This article applies to:
- Ethereum
- Polygon
- BNB Smart Chain
- Avalanche
- Fantom
Introduction
A transaction execution on an EVM-compatible protocol that involves a contract account can be complex as it allows to call other contracts.
What you normally get on transaction execution is if the transaction succeeded or failed.
To get all of the transaction details, you need to replay the transaction in the Ethereum Virtual Machine and collect the execution data during the process. This is called transaction tracing.
Requirements
Chainstack uses Geth as an EVM client and the full nodes are initially fast-synced.
To do transaction tracing on Chainstack, you must deploy a dedicated archive node or an elastic Ethereum archive node with the debug and trace APIs enabled. See Join a public network.
How-to
Basics
To trace a transaction on a Geth archive node, you must use the debug_traceTransaction method.
You can run the tracing directly in the Geth console attached to your archive node or as a JSON-RPC request outside of the node.
Geth console
debug.traceTransaction("TRANSACTION_HASH")
where
- TRANSACTION_HASH — the hash of the transaction your are tracing.
JSON-RPC
curl -H "Content-Type: application/json" -d '{"id": 1, "method": "debug_traceTransaction", "params": ["TRANSACTION_HASH"]}' HTTPS_ENDPOINT
- TRANSACTION_HASH — the hash of the transaction your are tracing.
- USERNAME — your node access username.
- PASSWORD — your node access password.
- HTTPS_ENDPOINT — your node HTTPS endpoint.
Running debug_traceTransaction will produce structured logs with the following fields:
- depth — execution depth
- gas — remaining gas
- gasCost — opcode cost
- memory (optional) — execution memory
- op — opcode name
- pc — program counter
- stack (optional) — execution stack
- storage (optional) — contract storage
Filtering
Out of the box, you can filter out memory, stack, and storage from the data collection.
debug.traceTransaction("TRANSACTION_HASH", {disableMemory: true, disableStack: true, disableStorage: true})
Pre-created JavaScript-based tracers
You can use the pre-created custom JavaScript-based tracers in Geth.
4byteTracer
Searches for 4byte-identifiers and collects them for post-processing. The tracer also collects the methods identifiers along with the size of the supplied data, so a reversed signature can be matched against the size of the data.
debug.traceTransaction("TRANSACTION_HASH", {tracer: "4byteTracer"})
bigramTracer
Extracts bigram opcodes.
debug.traceTransaction("TRANSACTION_HASH", {tracer: "bigramTracer"})
callTracer
Extracts all internal calls made by the transaction.
debug.traceTransaction("TRANSACTION_HASH", {tracer: "callTracer"})
evmdisTracer
Returns sufficient information from a trace to perform evmdis-style disassembly.
debug.traceTransaction("TRANSACTION_HASH", {tracer: "evmdisTracer"})
opcountTracer
Returns the number of instructions executed by the Ethereum Virtual Machine before the transaction terminated.
debug.traceTransaction("TRANSACTION_HASH", {tracer: "opcountTracer"})
prestateTracer
Returns sufficient information to create a local execution of the transaction from a custom assembled genesis block.
debug.traceTransaction("TRANSACTION_HASH", {tracer: "prestateTracer"})
trigramTracer
Extracts trigram opcodes.
debug.traceTransaction("TRANSACTION_HASH", {tracer: "trigramTracer"})
unigramTracer
Extracts unigram opcodes.
debug.traceTransaction("TRANSACTION_HASH", {tracer: "unigramTracer"})
Custom JavaScript-based tracing
You can also create your own JavaScript expressions to do custom tracing.
Comments
0 comments
Article is closed for comments.