15

If a contract call predictably requires 41043 of gas to be processed as estimated by estimateGas, how come I need to specify gasLimit of ~70000 to be processed?

3 Answers 3

8

I believe in some cases cumulativeGasUsed is not accurate due to spending gas / refunding gas. If at any point the contract gets above the gasLimit, it will fail with an Out of Gas exception. If a refund is issued later in the contract, it will bring the cumulative gas down even though it rises above what you think is the "gas limit" during the execution of the contract.

Let's look at Etherdice as an example.

  • Contract had data in storage

  • Each time a user sent a transaction to the contract, the contract would clear the oldest item in storage out

  • However, since the contract only refunds at the end of the transaction, all funds were stuck in the contract due to being out of gas.

So before a user sends a transaction, let's say the gas is 100,000. After the user sends the transaction, the gas is 100,000. During the contract, at a certain point, it "needs" 200,000. And the second it hits that limit, it's out of gas and done.

In etherdice's case, it was actually worse because he was hitting the global limit of 3141592 that was around prior to homestead.

2
  • thanks for your answer. This makes a lot of sense, but I believe I'm not doing any op with negative gas price - one external call and a few storage writes (where value is overwritten).
    – Ales
    Commented Apr 15, 2016 at 0:20
  • You should not consider the cumulativeGasUsed, it is the cumulative amount of Gas Used within the current block. Look at various tx in various block, this value will 'randomly' go up or down so you cannot use that to set your gas limit (unless there was only your tx in the block).
    – Chevdor
    Commented Nov 8, 2016 at 12:04
7

You don't.

You can specify the gas exactly and it should go through just fine. The only gotcha is that if the contract state changes that you're executing against, and it would require more gas than provided by even a single unit, you'll lose all the provided gas and the transaction will be rolled back.

7
  • Contract logic shouldn't be a problem (gas usage is constant), meaning cumulativeGasUsed is stable. Thats why i'm wondering, if is specify 70k gasLimit everything is ok (but only 40k is used), and if I specify 50k all gas is spent and tx is not processed.
    – Ales
    Commented Apr 14, 2016 at 14:30
  • @Ales It does look like you're running out of gas, so you may need to debug with the EVM or simpler is to check a blockchain explorer that simulates the EVM: ethereum.stackexchange.com/q/1179/42
    – eth
    Commented Apr 14, 2016 at 15:43
  • @eth yes thats seem most likely since gasLimit==cumulativeGasUsed for these txs. But I would like to understand the reason for this
    – Ales
    Commented Apr 14, 2016 at 16:02
  • One possible explanation: as miner execute operations for contract they sometimes (eg. for external calls) estimate how much gas the operation would be needed (and maybe add some safety margin), check if there is enough gas, and only then proceed with said operation if enough gas is available. If this is true, then gasLimit must always be larger than amount of gas that is actually required and will be used in the end.
    – Ales
    Commented Apr 14, 2016 at 16:07
  • Ah, this is a very good point. I think estimateGas didn't take into account refunds (i.e. you free up some storage space), which could cause it to underestimate the actual requirement. See github.com/ethereum/go-ethereum/issues/2395 Commented Apr 15, 2016 at 11:24
5

Here are general tips, followed by a synthesis of the other answers and comments to explain this particular situation.

General tips

Specific question

Conclusion appears to be:

  • OP was performing a few storage writes (where value is overwritten)
  • The few storage writes actually lead to a gas refund
  • OP was using a stable branch of Geth
  • Stable branch of Geth has a bug that underestimated the gas since Geth normalized it to include gas refunds, instead of reporting the maximum gas consumed during the transaction
  • Thus the transaction was running Out of Gas and needed a higher gas limit to be processed

Geth v1.4 or the develop branch has the fix for estimateGas. Note, althoughestimateGas is practical to use, it will still not be correct for all possible scenarios.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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