1

We are currently testing functions on Ropsten test network and have an issue regarding the gas usage. Our functions sometimes use 12 gas more and we can not fathom why that would be the case. To test this we defined a function

    function refund (bytes32 sessionId) public {
            require (false);
            ...
}

It fails after the first line and reverts the transaction. We called it 30 times with different byte32 values approx. every 3min. Here are two transactions to this function with different gas usage:

  1. https://ropsten.etherscan.io/tx/0xa48c4f09da3a8d57fc4061ecad27a3097c225ad3e524e81948e6d38461e41b1f

  2. https://ropsten.etherscan.io/tx/0x3126bdcdb6c5fd569a85a9c95928b1fd8c856ded7047670064f0d4e965199fe8

The only difference there seems to be the nonce(duh), the block index position and a different 32 bytes long input (that is not used). Is there some calculation for the used gas that we are missing?

EDIT:

Tested with an even simpler contract on goerli.

pragma solidity ^0.5;

contract FairDataExchange {
    function refund(bytes32 t) public{
    }
}

Issue is the same here. Without parameter t this issue does not seem to come up (n=45).

Transactions on goerli:

1. https://goerli.etherscan.io/tx/0xd48b8ad613145af060489082507253786e6211fd34dfbe641c10f5e03b82f3d8

2. https://goerli.etherscan.io/tx/0x434a546e43f2e2bfc5bf509f67fd8543506e9223b0d52fa41213063ca90595b7

  • 1
    "Our functions sometimes use 12 gas more and we can not fathom why" - gas consumption of a function is not necessarily the same every time the function is called. In fact, it typically changes from one call to another, depending on the current state of the blockchain. For example, a simple function which does x++ will cost a lot more the first time it is called (changing x from zero to non-zero), than every other time it is called (changing x from non-zero to non-zero). Show what your function does, and we'll be able to point it out more accurately. – goodvibration Oct 17 at 10:27
  • I can see that the input in both the cases is different. It could be a different path taken in the contract code execution. (if loop skipped etc..) – Sanjay S B Oct 17 at 10:27
  • It's exactly the same path: The execution stops in the first line, since require(false) always fails. But that doesn't explain the difference in some executions. – Matthias Lohr Oct 17 at 11:16
  • The only differences I see is in the input data (should not matter since the length is the same and it's ignored until require is reached) and the position of the transaction in the block. Does this position have an influence on the gast costs? – Matthias Lohr Oct 17 at 11:19
  • Well, the value of the nonce is definitely one thing that affects the state of the blockchain every time the function is called (because the nonce is incremented by 1 every time the transaction is executed). So perhaps this state-change ultimately impacts the gas-cost. – goodvibration Oct 17 at 11:30
1

The difference is in the input. You pay a fee for every byte in the input data. Zero bytes are cheaper.

First tx has a zero byte

d1cde79209c0d871e6bb93c58344007991a382ee75fc0e4b016486be3c195595

Second doesn't

d494db4db43f7d40fc919665c4935441e05a2fac218738a2e1e217afaaaeb1e7

From Yellow paper Appendix G "Fee Schedule"

  • Gtxdatazero, 4, Paid for every zero byte of data or code for a transaction.
  • Gtxdatanonzero, 16, Paid for every non-zero byte of data or code for a transaction.

Note: Ropsten has activated Istanbul, it uses the new cost defined in EIP 2028. Goerli and mainnet still use the previous costs 4/68.

  • I just tested this. Thank you! – J4D0 Oct 17 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.