Solidity

如何在 Truffle 單元測試中獲取交易成本?

  • December 23, 2018

如何獲得sendTransaction松露測試內部消耗的實際氣體?

在以下測試中,向合約buyer發送amount50 ETH:

const EmptyContract = artifacts.require("EmptyContract");
const BigNumber = web3.BigNumber;

contract('Test', function(accounts) {   
   it("should work", async () => {
       let contract = await EmptyContract.new({ from: accounts[1] });
       let amount = web3.toWei(50, 'ether');
       let buyer = accounts[2];

       // BALANCE BEFORE TX
       let balanceBefore = web3.eth.getBalance(buyer);

       // SEND TX
       let hash = await contract.buy.sendTransaction({from: buyer, value: amount});

       // BALANCE AFTER TX
       const balanceAfter = web3.eth.getBalance(buyer);

       let tx = await web3.eth.getTransaction(hash);
       const gasUsed = tx.gas;
       const gasCost = tx.gasPrice.mul(gasUsed);
       console.log("BEFORE", balanceBefore.toNumber());
       console.log("amount sent", amount);
       console.log("gas price", tx.gasPrice.toNumber());
       console.log("gas used", gasUsed);
       console.log("gas cost", gasCost.toNumber());
       console.log("AFTER", balanceAfter.toNumber());
       console.log("CHECKSUM", balanceAfter.add(gasCost).add(amount).toNumber());

       assert.equal(balanceBefore.toNumber(), balanceAfter.add(gasCost).add(amount).toNumber());
   });
});

然後buyer檢查 的餘額。它應該是

$$ balance before tx $$=$$ balance after tx $$+$$ amount sent $$+$$ gas cost $$

但它失敗了,列印:

BEFORE 100000000000000000000
amount sent 50000000000000000000
gas price 100000000000
gas used 6721975
gas cost 672197500000000000
AFTER 49997862200000000000
CHECKSUM 100670059700000000000       
  :    
AssertionError: expected 100000000000000000000 to equal 100670059700000000000

契約很基礎:

pragma solidity ^0.4.18;

contract EmptyContract {
   function buy() public payable  { }
}

似乎交易成本比返回的值少 0.6700597 ETH tx

在 truffle 測試案例中遵循了 Transaction gas cost ,但它沒有幫助。

任何的想法?

你必須乘以gasUsedgasPrice包含在gasUsed交易收據中。雖然gasPrice是進入交易本身。實際上,在您的情況下,您正在嘗試將 乘以gasPricegas這是發件人提供的(可能高於gasUsed)。參考:getTransactiongetTransactionReceipt

所以,這就是你的程式碼應該看起來正確的樣子

const hash = await contract.buy.sendTransaction({from: Buyer, value: amount});

// 發送後的餘額
const balanceAfter = web3.eth.getBalance(buyer);
const tx = 等待 web3.eth.getTransaction(hash);
常量收據 = 等待 web3.eth.getTransactionReceipt(hash);
const gasCost = tx.gasPrice.mul(receipt.gasUsed);

或者如果您直接呼叫您的方法,您也可以實際保存getTransactionReceipt呼叫(在這種情況下,應該給您一個包含交易收據ref的結果)

const txInfo = await contract.buy({from: Buyer, value: amount});

// 發送後的餘額
const balanceAfter = web3.eth.getBalance(buyer);
常量 tx = 等待 web3.eth.getTransaction(txInfo.tx);
常量 gasCost = tx.gasPrice.mul(txInfo.receipt.gasUsed);

引用自:https://ethereum.stackexchange.com/questions/42950