Web3.py: Where can I find the transaction revert reason provided by contract?

Created on 13 Aug 2020  路  5Comments  路  Source: ethereum/web3.py

  • Version: 5.2.2
  • Python: 3.6
  • OS: osx
  • Geth: 1.9.15-stable-0f77f34b

What was wrong?

when send a transaction to blockchain but get fail status, how can I know the reason reported by the contract as printed in Remix?

eth.getTransaction("{txhash}") and eth.getTransactionReceipt("{txhash}") doesn't provide me sufficiency details.

Submit the transaction:

tx_hash =getattr(test_contract.functions, 'tokenSafeTransferFrom')(from_addr, to_addr, id, amount, description.encode('utf-8')).transact(transaction={'from': from_addr, 'gas': 10000000})

Get transaction hash:

detail = w3.eth.getTransaction(tx_hash)

AttributeDict({'blockHash': HexBytes('0xb1d67b375abf2f169e0608b6e0561b71845ab9a963fce29d0f601a5e7f1ce131'), 'blockNumber': 428874, 'from': '0x175EC34c2B545a4E2195bfBFE03A82B67e594390', 'gas': 10000000, 'gasPrice': 1000000000, 'hash': HexBytes('0x9ecc5e6d247156bba6eb15b3dfa9a1bd6a3d4027cf208d19d708763af3792507'), 'input': '0x5e9a5cb9000000000000000000000000175ec34c2b545a4e2195bfbfe03a82b67e594390000000000000000000000000f992d2cbadafc20a0f08c55ab288a80f8d134c170000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d526567756c617220776972656400000000000000000000000000000000000000', 'nonce': 251, 'to': '0xda075dE76D506D6Eff6275c471e1996024c35D9c', 'transactionIndex': 0, 'value': 0, 'v': 20034, 'r': HexBytes('0xc9288a8d306e97eaac5868d5a016698aa9def3a88e598832f9231b0c1bacc301'), 's': HexBytes('0x5816bdc5bf6f71c0ebef11b9e9752e9bd28ede7b6d25af463afd26954375423b')})

Get Receipt:

receipt = w3.eth.waitForTransactionReceipt(tx_hash, timeout=600)

AttributeDict({'blockHash': HexBytes('0xb1d67b375abf2f169e0608b6e0561b71845ab9a963fce29d0f601a5e7f1ce131'), 'blockNumber': 428874, 'contractAddress': None, 'cumulativeGasUsed': 46809, 'from': '0x175ec34c2b545a4e2195bfbfe03a82b67e594390', 'gasUsed': 46809, 'logs': [], 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'), 'status': 0, 'to': '0xda075de76d506d6eff6275c471e1996024c35d9c', 'transactionHash': HexBytes('0x9ecc5e6d247156bba6eb15b3dfa9a1bd6a3d4027cf208d19d708763af3792507'), 'transactionIndex': 0})

Remix log:

status | 0x0 Transaction mined but execution failed
-- | --
transaction hash | 0x08cec4c36e55ea6b1e1832f5d5cb61909ced8e716b980e3c9d4d130a110b8724
from | 0xe0030094b06ce55db30596d2252e465e0aff40ff
to | TokenTrekGen.tokenSafeTransferFrom(address,address,uint256,uint256,bytes) 0x16ac6ed9fe9e7d6231239a428bc05016632f185a
gas | 5000000 gas
transaction cost | 34445 gas
execution cost | 9141 gas
hash | 0x08cec4c36e55ea6b1e1832f5d5cb61909ced8e716b980e3c9d4d130a110b8724
input | 0x5e9...00000
decoded input | {   "address from": "0xE0030094b06CE55db30596d2252e465e0aFf40FF",   "address to": "0x2437a53B905CE5B49F28E793382e5d3045D23869",     "uint256 id": {         "_hex": "0x01"  },  "uint256 amount": {         "_hex": "0x50be4349"    },  "bytes data": "0x123456" }
decoded output | {}
logs | []
value | 0 wei

transact to TokenTrekGen.tokenSafeTransferFrom errored: VM error: revert.
revert  The transaction has been reverted to the initial state.
Reason provided by the contract: "ERC1155: insufficient balance for transfer".  Debug the transaction to get more information. 

According to remix source, remix get the error message by reading the reported string.

https://github.com/ethereum/remix/blob/master/remix-lib/src/execution/txExecution.js

Seems like geth doesn't report such error message defined in EIP758

https://github.com/ethereum/EIPs/blob/master/EIPS/eip-758.md

Not sure if this is related with geth or web3. Can someone guide please?

Most helpful comment

I found when send the gas estimate function and I can get contract exception. I will use this to get some failure message for the time been. Look forward to get revert message function enabled in the next release.

All 5 comments

Native support for revert messages is a work in progress, but will hopefully be ready in the next release. In progress here: https://github.com/ethereum/web3.py/pull/1585.

Tangentially, the Brownie framework has some support for revert message testing, if that's of interest.

I found when send the gas estimate function and I can get contract exception. I will use this to get some failure message for the time been. Look forward to get revert message function enabled in the next release.

Revert support was released in 5.13.0. Closing!

transact to ERC20.transfer errored: VM error: revert. revert The transaction has been reverted to the initial state. The reason provided by the contract: "Insufficient balance". Tried Debugging but nothing changed. Can you give some details about this?

@samdruster Revert is a solidity control structure that will validate certain things depending on how it's defined in the function in the contract. Based on your error, it looks like the transaction has been reverted because you didn't have enough funds. I can't really tell more than that from the info you provided. See the solidity docs here for details on revert and please open up a new issue with more details if you need more help.

Was this page helpful?
0 / 5 - 0 ratings