Debugging is a crucial step in any phase of the development process, from creating your business logic and writing algorithms to code testing. For Ethereum developers, debugging is also one of the most time-consuming tasks.
Debugging a blockchain transaction is different from debugging a traditional application built using a programming language such as JavaScript. With Web3 applications, you’re not running code in real-time. Instead, blockchain outlines a historical transaction execution mapped with associate code, so engineers need a comprehensive insight into such data to debug a transaction.
Additionally, debugging a Smart Contract requires analyzing a transaction step by step. Developers need to examine the logic of a Smart Contract’s internal functions, determine where and why a transaction failed, and then proceed with debugging the issue. When done manually, this takes a lot of time.
This is why we’re introducing a new functionality to the already well-known Tenderly Debugger feature – Evaluate Expression.
What is Evaluate Expression?
Evaluate Expression is a straightforward feature that allows you to efficiently evaluate transaction expressions during a debugging session. You can easily analyze human-readable code, gather information on a contract state, and test various custom scenarios at runtime. It also allows you to inspect global and local variables, functions, conditions, and other important transaction parameters.
This time-saving functionality combines multiple Tenderly features, including Run Simulation
and Edit Contract Source.
Basically, think of Evaluate Expression as console.log
injected into your contract source code at the exact tracepoint.
Additionally, Evaluate Expression can be particularly useful in war room scenarios since it allows you to speed up the debugging process significantly. After filtering external calls in the transaction trace, you can inspect suspicious parts of code using this feature. In these situations, acting quickly is essential for mitigating damage and saving funds. Evaluate Expression makes this possible.
How Evaluate Expression came to be
We started noticing how annoying it is to always console.log
to read a state of your contract. To add console.log
to Tenderly, you need to click the Re-Simulate button —> click Edit Contract Source —> add console.log
—> click Apply Changes, and click the Simulate Transaction button.
You can console.log
only primitive types, which also involves a fair number of clicks. So, we came up with a time-saving idea that allows you to easily examine any value in the transaction trace by clicking a single button in Tenderly Debugger – Evaluate.
Before & after Evaluate Expression
Before: To examine the variable value of a contract that’s in production, you need to collect data manually. Once you gather all the information, you need to complete multiple calculations. Since this involves a number of steps and an even greater number of clicks, many developers give up halfway through the process due to time constraints.
After: To examine a transaction error and debug an issue, you just need to go to Evaluate Expression in Tenderly Debugger. After that, type in an expression and click Evaluate to get the needed information in a human-readable format. And that’s it!
How to Evaluate
You can look at Evaluate Expression as a hardhat console.log
but you can console.log
anything, including methods, structs, enums, functions, complex expressions, and state variables. You don’t need to write code or deploy a new version of a contract. Instead, just click Evaluate and read the expression result. After that, you can run Tenderly Simulation to test your custom scenario or check if you’ve resolved an issue successfully.
4 Common Evaluate Expression use cases
Evaluate Expression enables you to inspect different expressions and test out numerous custom scenarios. Here are a few common examples to get you started:
1. Evaluating complex expressions
For example, let's say you want to check if your code went into an if block
. You can do this by evaluating a whole statement while going through a trace call.
Here’s an example transaction:
Here, you can check if your code went into an if block
. To see the result of an if statement, click Evaluate —> type the step.tickNext < TickMath.MIN_TICK
expression, and click enter. In this example, the result is false
, which means that you didn’t get into the if block
logic.
Another possible use case scenario is to use Evaluate Expression for calculations. For instance, let’s examine the following transaction step to calculate the next feeGrowthGlobalX128
:
2. Evaluating dynamic arrays, mappings, and other state variables
The Evaluate Expression feature also allows you to examine the contents of a whole struct. For example, you can evaluate state
:
3. Evaluating functions
Using Evaluate Expression, you can also inspect a whole function. Let’s examine the _blockTimestamp
function:
4. Evaluating global and local variables
This user-friendly feature enables you to evaluate global and local variables, including enums and struts. In the following example, you can see how Evaluate Expression can help you identify a contract caller:
Use Evaluate Expression and speed up your debugging
The standard debugging process involves many complex and time-consuming steps that can often get you off track and slow you down when speed matters the most. Evaluate Expression gets you to your destination more quickly, giving you an even deeper insight into transactions and relevant expressions.
This feature will help you make the most of Tenderly Debugger and handle various scenarios, from debugging transaction errors and potentially reducing Smart Contract gas fees to reacting quickly in time-sensitive war room situations. When done with Evaluate Expression, debugging turns from a time-consuming endeavor to a simple task. Ready to try it out?