๐ Trace Execution: Step-by-Step Analysis
Master transaction tracing with Tenderly and Etherscan
Debug failed transactions and trace execution
Your Progress
0 / 5 completed๐ฌ Transaction Execution Trace
Traces reveal the complete execution path. A single transaction can trigger dozens of internal callsโcontract A calls contract B, which calls C, which emits events and updates state. When debugging, you need to see this entire call tree: which contracts were invoked, in what order, with what parameters, and where it failed. Etherscan shows internal transactions, but only high-level. Tenderly provides interactive traces with step-by-step debugger, state diffs, and gas profiling. Hardhat console.log lets you inject debug output into local traces. This section teaches you to read traces, identify the failing call in a chain, and understand cross-contract interactions.
๐ฎ Interactive: Execution Trace Walkthrough
Step through a Uniswap swap transaction. See each internal call, gas usage, parameters, and state changes.
External Call
User calls swap function on Uniswap Router
swap(tokenIn, tokenOut, amountIn)UniswapRouter (0x7a25...)Router receives 1000 DAI, prepares to swap for USDC via liquidity pool
๐ ๏ธ Tracing Tools
Etherscan Internal Txs
Free, public, shows all contract calls in tree view
- โข View call hierarchy
- โข See value transfers
- โข Identify failing contract
- โข Limited detail (no opcodes)
Tenderly Debugger
Visual debugger with step-through, state diffs, gas profiling
- โข Step through opcodes
- โข See state changes
- โข Gas breakdown per line
- โข Requires account (free tier)
Hardhat console.log
Local debugging with Solidity console output
- โข Add console.log() in contracts
- โข Run tests locally
- โข See custom debug output
- โข Requires local setup
debug_traceTransaction
RPC method for full opcode-level trace
- โข Complete EVM trace
- โข Requires archive node
- โข Large data output
- โข For advanced debugging
๐ Reading a Trace
1. Start at External Call
User calls contract A. This is the entry point. Check function signature, parameters, msg.sender.
2. Follow Internal Calls
Contract A calls B, B calls C. Each call has depth (indent level). Failed call shows red marker + revert reason.
3. Check State Changes
Look for storage writes, balance updates, event emissions. These show what changed before failure.
4. Identify Failure Point
Find deepest call that failed. Read revert reason. Trace back to understand why inputs were invalid.
๐ก Common Trace Patterns
- โขReentrancy: See same contract called multiple times in trace (A โ B โ A). Check for state updates between calls.
- โขOut of Gas in Deep Call: Early calls succeed, deep call fails OOG. Indicates insufficient gas limit for complex operation.
- โขFailed transferFrom: Router calls token.transferFrom() โ fails. Check allowance and balance before transferFrom.
- โขUniswap K Check: Swap calls pair.swap() โ K invariant check fails. Means insufficient liquidity or price manipulation.