ApeWorX / ApeWorX/web3.py

Parse encoded revert reasons from ABI (ContractCustomError)

Open
#3,523 1 comment 0 reactions 0 assignees View on GitHub
priority: p2 normal
Dominant language
Python
Stars
5.5k
Forks
1.7k
Avg merge
3d 10h
Merged PRs (30d)
2

Description

### What feature should we add?

🌟 Hello everyone! 🌟

It would be easier to debug and understand what happened if contracts automatically parsed reverts into a human-readable format.

Current contract reverts exceptions example:
`ContractCustomError('0xcd0883ea', '0xcd0883ea')`

Parsed reverts with feature:
```
abi = '[{"inputs":[],"name":"InitialEpochIsYetToArrive","type":"error"}]'

contract = Contract(abi=abi, parse_reverts=True)

try:
contract.functions.someMethod()
except ContractCustomError as error:
print(error)
# output: ContractCustomError('0xcd0883ea', 'InitialEpochIsYetToArrive()')
```

Also, parsing inputs could be implemented.
```
abi = '[{"inputs":[{"internalType":"uint256","name":"secondsPerSlot","type":"uint256"}],"name":"InitialEpochIsYetToArrive","type":"error"}]'

ContractCustomError('0xcd0883ea', 'InitialEpochIsYetToArrive(secondsPerSlot=12)')
# or
ContractCustomError('0xcd0883ea', 'InitialEpochIsYetToArrive', kwargs={'secondsPerSlot': 12})
```

Some python pseudocode how to parse exceptions could be implemented
```
# Parse encoded revert data by matching the error signature

error_signature = revert_reason.data

for item in abi:
if item.get("type") == "error" and w3.keccak(text=item["name"])[:4].hex() == error_signature:
error_name = item["name"]
error_inputs = item["inputs"]
decoded_data = contract.decode_function_input("0x" + revert_reason_data)

print(f"Error Name: {error_name}")
print("Decoded Data:", decoded_data)
break
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.