We developed a call trace decoder for Geth
September 10, 2019
Complete with a bonus output formatter and demonstration app!
Development on Ethereum is hard. Frustrating. The arsenal currently available to developers is still rudimentary, and while we are grateful for every tool at our disposal, the environments required for the exploration and development of more mature technologies are still a long way off.
The thing is, up until now we have been spoiled for choice, with multiple IDEs and smart debuggers which have allowed us to create exciting apps with ease. With Solidity? Not so much. We sort of have to develop our own.
This is compounded by the fact that the Ethereum ecosystem is harsher than most. Contracts have to be deployed on the public net in order to be properly tested; execution happens asynchronously, with an unspecified delay; and it is totally non-interactive — all of our output comes down to a function reply or encoded transactions logs. This means that transactions can only be debugged after the fact, and that, as you might imagine, is not always useful.
If (and when) a transaction reverts, we are often greeted by cryptic messages like, “Error: Transaction has been reverted by the EVM.” Unhelpful, especially when Geth ignores any revert messaging that you’ve programmed in.
All of this conspires to make it extremely difficult to understand exactly why a contract call failed. And when it comes to contracts that make several calls of their own, searching for an error quickly becomes an exercise in hair-pulling. So, at the risk of early onset baldness, we decided to do something about it.
Enter the geth-trace-decoder
To make debugging sessions a degree less painful, we’ve developed a decoder that can take the call trace of a transaction (whether it’s successful or a failure), and translate it into simple, meaningful language. The tool gives the user oversight of the call sequence before the transaction failed. Unfortunately, it cannot extract the exact error that caused the revert, but it will deliver all the information leading up to that point, including:
- contract called into and any further library calls (by name or address)
- method name
- decoded inputs and outputs
If you want to see our hard work in action, we’ve made the repo available here. The library also comes complete with an example formatter which you can use to output the results to console.
Here’s how to get it up and running:
From the root of the repository, run:
To run the demo
From publicDemo simply run:
This is the basic usage of the library. All you need to do is replace the parameters of the function calls.
You can find example applications in demo.js. These are very simple implementations to highlight the library’s different use cases — they are not production-ready and will require some handiwork on your end. They include:
- Decoding hard coded call traces
- Replacing addresses with friendly names
- Dealing with multiple contracts (ABIs)
- Handling custom solidity types
- Getting the call trace from Rinkeby via etherscan()
- Getting the call trace from the mainnet via etherscan()
- Getting the call trace directly from a Geth node. To run this function you need to replace <YOUR TRANSACTION HASH> with a recent transaction hash and update the RPC IP address used to connect to your node if required.
And there you have it! A better way to debug Geth.
Share the love
We created this Geth trace decoder as a big ‘thank you’ to all of the people who have been working so hard to make Ethereum what it is today. A special mention has to go to ConsenSys for their “abi-decoder” tool and the inspiration it gave us. We hope that this tool will boost the productivity of developers working in the ecosystem, and ultimately make it an easier environment to develop in.
Please feel free to produce other formatters more suitable to your needs, and let us know if you find our work useful, if you know how it could be improved and how you’d like to see it evolve in the future.