使用松露计算以太坊合约中的交易费用

时间:2017-12-19 23:25:01

标签: ethereum truffle

我正在为以太坊使用松露测试框架(v4.0.1)。我无法弄清楚为什么以下简单合同的交易费用不等于gasPrice*gasUsed

contract MinTest {
    function run() public returns(bool) {
        return true;
    }
}

我正在使用的摩卡测试是:

contract('Minimum Test', function (accounts) {

  it("min test", function () {
    var initial = web3.eth.getBalance(accounts[1]);
    var final;

    return MinTest.deployed().then(function(instance) {
        return instance.run({from: accounts[1]});
    }).then(function(result) {
        final =  web3.eth.getBalance(accounts[1]);

        var gasPrice = new BigNumber(web3.eth.gasPrice);
        var gasUsed = new BigNumber(result.receipt.gasUsed);
        var gasCost = gasPrice.times(gasUsed);

        console.log("gasPrice       : " + gasPrice);
        console.log("gasUsed        : " + gasUsed);
        console.log("gasCost        : " + gasCost);
        console.log("initial        : " + initial);
        console.log("initial-gasCost: " + initial.minus(gasCost));
        console.log("final          : " + final);
        console.log("unaccounted    : " + initial.minus(gasCost).minus(final));
    });
  });

});

上述测试产生以下输出:

gasPrice       :            20000000000
gasUsed        :                  21478
gasCost        :        429560000000000
initial        :  100000000000000000000
initial-gasCost:   99999570440000000000
final          :   99997852200000000000
unaccounted    :       1718240000000000

我期望调用合同的MinTest.run函数导致accounts[1]被扣除的金额完全等于gasPrice*gasUsed,但在本例中并非如此。还有一笔额外的1718240000000000 wei借记我无法解释。为什么额外的1718240000000000 wei会在这里扣除?

1 个答案:

答案 0 :(得分:2)

{ path: '/beats', components: { navbar: Navbar, default: { template: `<router-view/>` } }, children: [{ name: 'BeatsCatalog', path: 'catalog/:page', components: { default: () => import('@/views/BeatsCatalog') }, props: { default: true } }, { path: 'upload', name: 'BeatsUpload', components: { default: () => import('@/views/BeatsUpload') } }, ], meta: { requiresAuth: true } } 不是您的交易调用中指定的价格。来自文档:

  

此属性为只读并返回当前的汽油价格。气体   价格由x最新区块中位数天然气价格确定。

它用于告诉您其他人正在支付的费用,因此您可以动态确定&#34;正在进行的费率&#34;。如果您想要随时间更改交易的天然气价格,您可以使用此方法。我猜web3.eth.gasPrice只是设置为20000000000。

另一方面,如果您未在事务调用中指定testrpc,则默认为10000000000.以下是传入gasPrice的更新测试用例和输出(我用了15 Gwei进行测试)。

gasPrice
contract('Minimum Test', function (accounts) {

  it("min test", function () {
    var initial = web3.eth.getBalance(accounts[1]);
    var final;
    var gasPrice = new BigNumber(15000000000);

    return MinTest.deployed().then(function(instance) {
      return instance.run({from: accounts[1], gasPrice: gasPrice});
    }).then(function(result) {
      final =  web3.eth.getBalance(accounts[1]);

      var gasUsed = new BigNumber(result.receipt.gasUsed);
      var gasCost = gasPrice.times(gasUsed);

      console.log("gasPrice       : " + gasPrice);
      console.log("gasUsed        : " + gasUsed);
      console.log("gasCost        : " + gasCost);
      console.log("initial        : " + initial);
      console.log("initial-gasCost: " + initial.minus(gasCost));
      console.log("final          : " + final);
      console.log("unaccounted    : " + initial.minus(gasCost).minus(final));
    });
  });

});

编辑 - web3js文档确实说 Contract: Minimum Test gasPrice : 15000000000 gasUsed : 21431 gasCost : 321465000000000 initial : 100000000000000000000 initial-gasCost: 99999678535000000000 final : 99999678535000000000 unaccounted : 0 √ min test (773ms) 1 passing (922ms) 的默认值应该是相同的:

  

gasPrice:Number | String | BigNumber - (可选,默认值:   待定)这笔交易的天然气价格在wei,   默认为平均网络燃气价格。

这可能是松露的一个错误。在任何情况下,如果你传递自己的汽油价格,数字就可以了。