I have a deployed smart contract and attempt to write codes to call it through web3.py. I'm getting the following error when I call estimateGas().

ValueError: {'code': -32000, 'message': 'gas required exceeds allowance or always failing transaction'}

Due to I'm just estimating gas, I guess it should be impossible to have not enough gas. So the error should be caused by always failing transaction.

The contract function indeed has some require parts that verify something before executing the logics, like the following:

   "Failed to call function due to replay attack."

However, I cannot ensure which part causes the error. Is there any chance that I can get the error message, such as the above message Failed to call function due to replay attack., in web3.py, so I can at least know the reason of failure?

  • In some clients like ganache estimateGas execute the transaction so the maximum gas available is the block gas limit, if you need more you have to explicitely set it. – Ismael Oct 31 '18 at 2:12
  • In my case I connect to Ethereum through infura API. Does infura API have this kind of characteristic? – user1802604 Oct 31 '18 at 3:13
  • There's an unaswered question about estimateGas from web3.py using infura ethereum.stackexchange.com/questions/48494/…, and a closed github issue github.com/ethereum/web3.py/issues/845. It appears to be an infura limitation, estimateGas fails for complex transactions. – Ismael Oct 31 '18 at 5:23

You could use Brownie, which displays the specific error message when a transaction (or gas estimate) fails:

>>> contract.myFunction()
  File "<console>", line 1, in <module>
  File "eth_brownie-1.0.0-py3.6.egg/brownie/network/contract.py", line 455, in __call__
    return self.call(*args)
  File "eth_brownie-1.0.0-py3.6.egg/brownie/network/contract.py", line 359, in call
    raise VirtualMachineError(e) from None
VirtualMachineError: VM Exception while processing transaction: revert Failed to call function due to replay attack.

The specific error string is available as VirtualMachineError.revert_msg:

>>> try:
...     t.myFunction()
... except Exception as exc:
...     print(exc.revert_msg)
Failed to call function due to replay attack.

See the Brownie documentation on debugging contracts for more info.

Disclosure: I am the lead developer of Brownie.

  • Thanks, helpful feature that Brownie provides – alper Nov 11 '19 at 8:53

It's most probably because you don't have booleans in traderNonces[msg.sender][_nonce].

In the docs, it's stated that:

Note that there is no type conversion from non-boolean to boolean types as there is in C and JavaScript, so if (1) { ... } is not valid Solidity.

Assuming _nonces should be positive integers, you can change your require to:

   !(traderNonces[msg.sender][_nonce] > 0),
   "Failed to call function due to replay attack."
  • Thank you for your reply. In my smart contract, the value is defined as boolean. So changing the condition will make the compile fail. – user1802604 Oct 30 '18 at 14:13

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.