TL;DR — We’ve built a solution to extract commented console.sol logs from on-chain
transactions, allowing better logging.
Coming from Web2, one of the most invaluable capabilities of a developer is logging.
Although might be heavy on CPU and disk usage, partially activating it for a limited
period of time allows the developer to gain deep insights about how his code operates
and provides the best infrastructure for finding bugs.
All you had to do was defining log lines in your code, set the respective level per log
line and set the minimum log level before execution. As any Web2 developer knows,
informative log and error lines are crucial for debugging.
Moving forward to Web3 we were looking for similar functionality. At SphereX we’re
developing highly complexed smart contracts. Debugging & logging capabilities are
crucial. We tried to understand what were the options currently available:
Frustrated with the options in front of us, we asked ourselves what can we do to
gain insights into the inner execution of the transaction — log lines in “production”?
So, with all the options in mind, it made sense to start off with console.sol . We
asked ourselves, what to we need to do to make it “production”-friendly, in the
We first wanted to have a sense of how widely used console.sol is:
In addition, the amount of console.sol we’ve seen in the verified section on Etherscan,
though not deployed, was huge. It is probably the most common debugging library
in use today.
Of course, it is bad practice to include console logs in deployed contracts, so another
common practice we witnessed was commenting out those lines before deployment:
So as PoC we decided to go with this approach. Leverage the practice of commenting
out console.log lines as way of easily integrating debug logs into deployed contracts.
To start working on utilizing this approach for debug logs, we decided to use foundry
as our dev library. Although we have mixed feelings regarding rust, we feel like
foundry is currently the most feature complete library for our needs. Moreover, is
has the fastest integrated EVM which will help us during the simulation process
explained later. Some bug fixes had to be integrated into foundry for it to work
though  .
Given a deployed contract with commented out console.log lines, there are several
steps needed in order to extract the relevant log lines:
Step 1 is pretty straight forward, it is already well implemented inside foundry.
For step 2 (again, this is a PoC) we’ve used a simple regex replacement:
(\n[ \t]*)//([ \t]*console.log) Will be replaced with $1$2 which will effectively remove
the // sign. This is obviously not a bulletproof method, but it’s good for now.
For step 3 foundry does all the heavy lifting. It stores the fetched sources in a
project-like object that can easily be altered and compiled.
Step 4 is the tricky one. Since we are simulating a mined transaction, we need to
reconstruct the exact state the blockchain was at right before the transaction
started executing. This generally means forking to tx.block-1 and replaying all
block transactions before the current ones. This can sum up to hundreds of
eth_getCode and eth_getStorageAt calls which will prevent the simulation from
finishing in a timely fashion.
Instead, we went with a different approach. There’s a lesser known usage for
debug_traceTransaction involving getting the entire state a transaction requires
to run — prestateTracer . This type of tracer will produce all the code, balances,
nonce and storage slots a certain transaction requires to execute properly, all in
one single RPC call. This approach reduces the simulation time dramatically.
Another aspect is the gas limits set in the original transaction. Since we’re altering
the code, the gas consumption of the simulated transaction will probably increase.
It makes sense to increase the limits before actually simulating the transaction.
And the end result — for transaction 0xa41a5e85874c305b2cdc1c0f529d2025ae41b5ed865452999ace0c385cc9fc4e
using the contract 0x60FB45483d9E48dFC602f49E094024F8DA292416:
Some Caveats using this tool
Ariel has over 12 years of software development and cybersecurity research experience. Before joining SphereX, Ariel was the co-founder and CEO of Realmode Labs, a boutique cybersecurity research firm.