Simulation and traces
Find out what a transaction will do before it does it — including a sequence of them.
One call
The Simulator page runs a call and shows the call tree, gas and a decoded revert reason, without committing anything. It can pretend about state — a balance, a storage slot, code that was never deployed — for that run only. Over RPC it is debug_traceCall:
[{ "from": "0x…", "to": "0x…", "data": "0x…" }, "latest", {
"tracer": "structLogger",
"tracerConfig": { "opcodes": "relevant", "limit": 2000 },
"stateOverrides": { "0xYou": { "balance": "0x56BC75E2D63100000" } }
}]Opcode steps are opt-in, because one swap is tens of thousands of them. opcodes picks a set — relevant, storage, calls, logs, memory — before the limit applies.
A sequence: forkstate_simulateBundle
Several transactions, in order, each on top of what the one before it did — and none of it kept. An approve and a swap simulated separately answer a different question; as a bundle they answer the real one.
[{
"transactions": [
{ "from": "0xYou", "to": "0xToken", "data": "0x095ea7b3…" },
{ "from": "0xYou", "to": "0xRouter", "data": "0x38ed1739…" }
],
"overrides": { "0xToken": { "stateDiff": { "0x…": "0x…" } } },
"trace": true,
"diff": true
}]- A transaction that reverts is rolled back on its own; the rest still run, so you hear about all of them.
- Each result has status, gas, return value, decoded revert reason, logs, and — if asked — the call tree and storage changes.
- Up to 64 transactions per bundle. The Simulator page has a Bundle tab for the same thing.
Traces of real transactions
debug_traceTransaction returns the call tree and state diff recorded when a transaction ran on the testnet. The console's transaction page shows the same, and its debugger steps through the opcodes.
block.timestamp and block.number the real one will see.