This answer explains well how to measure the gas used in a block of code.
I had actually been using this method before I found that answer:
pragma solidity 0.4.26;
import './IERC20Token.sol';
contract Tester {
uint256 public gasUsed;
function transfer(IERC20Token _token, address _to, uint256 _value) public {
uint256 bgn = gasleft();
require(_token.transfer(_to, _value));
uint256 end = gasleft();
gasUsed = bgn - end;
}
}
Then, simply from a Truffle 4.1.16 test:
const token = await ERC20Token.new('name', 'symbol', 18, SUPPLY);
const tester = await Tester.new();
await token.transfer(tester.address, AMOUNT);
await tester.transfer(token.address, accounts[0], AMOUNT);
const gasUsed = await tester.gasUsed();
console.log(gasUsed.toFixed());
However, it seems that it doesn't take into account gas-refund for changing storage variables from nonzero to zero.
Reading a little bit about this refund, I believe that it is sent back to the sender (msg.sender
) or even all the way back to the original sender (tx.origin
).
So I'm looking for a more accurate method.
I don't mind if the solution involves the off-chain, for example (using web3.js):
const balanceBefore = await web3.eth.getBalance(myAccount);
const response = await myContract.methods.myFunc().send({from: myAccount, gasPrice: myGasPrice});
const balanceAfter = await web3.eth.getBalance(myAccount);
const gasUsed = response.receipt.gasUsed;
// now do something with balanceBefore, balanceAfter, myGasPrice and gasUsed
But the result should reflect only the gas-cost of the actual block of code in the contract.
For example, it should avoid taking the cost of the transaction itself into account.
Does anybody have a leading clue on this?
Thank you!