https://github.com/paradigmxyz/ultimate_evm_tracing_reference
a collection of EVM tracing information for easy reference
https://github.com/paradigmxyz/ultimate_evm_tracing_reference
besu erigon evm geth nethermind parity reth tracing
Last synced: 8 months ago
JSON representation
a collection of EVM tracing information for easy reference
- Host: GitHub
- URL: https://github.com/paradigmxyz/ultimate_evm_tracing_reference
- Owner: paradigmxyz
- License: apache-2.0
- Created: 2023-11-09T22:21:35.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-11-21T03:23:57.000Z (almost 2 years ago)
- Last Synced: 2025-01-03T16:18:47.076Z (9 months ago)
- Topics: besu, erigon, evm, geth, nethermind, parity, reth, tracing
- Homepage:
- Size: 35.2 KB
- Stars: 162
- Watchers: 6
- Forks: 10
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# Ultimate EVM Tracing Reference
[](https://t.me/paradigm_data)
This repo is a collection of trace-related information for easy reference.
A best effort is made to provide accurate information. Please submit corrections to the issue tracker.
## Contents
1. [Tracers](#tracers)
2. [Trace Methods](#trace-methods)
3. [Node Client Support](#node-client-support)
4. [RPC Provider Support](#rpc-provider-support)
5. [Ecosystem Tooling Support](#ecosystem-tooling-support)
6. [Hosted Data Platform Support](#hosted-data-platform-support)
7. [Example Tracer Data](#example-tracer-data)## Tracers
A tracer gives a detailed view into what happened during a block or transaction.
Each tracer type provides a different set of information. There are two main categories of tracers, parity and geth. Each node client supports these tracer types to varying degrees.
**To see the specific information returned by each tracer, see the schemas and data samples in the [Example Tracer Data](#example-tracer-data) below.**
| tracer | description | parameters |
| --: | --- | --- |
| [`parity calls`1](https://openethereum.github.io/JSONRPC-trace-module) | calls in a flat list structure | `[ "trace" ]` |
| [`parity stateDiffs`2](https://openethereum.github.io/JSONRPC-trace-module) | all state changes for each tx | `[ "stateDiff" ]` |
| [`parity vmTraces`](https://openethereum.github.io/JSONRPC-trace-module) | opcode-level trace | `[ "vmTrace" ]` |
| [`geth opcodes`](https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers#struct-opcode-logger) | opcode-level trace | `{ }` |
| [`geth calls`1](https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers#call-tracer) | calls in a nested structure | `{ "tracer": "callTracer" }` |
| [`geth preState`2](https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers#prestate-tracer) | data that was read before each tx | `{ "tracer": "prestateTracer" }` |
| [`geth stateDiffs`2](https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers#prestate-tracer) | all state changes for each tx | `{ "tracer": "prestateTracer", "diffMode": true }` |
| [`geth 4byte`](https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers#4byte-tracer) | 4byte prefixes of function calls | `{ "tracer": "4byteTracer" }` |
| [`geth javascript`3](https://geth.ethereum.org/docs/developers/evm-tracing/custom-tracer#custom-javascript-tracing) | custom javascript tracer functions | `{ "tracer": "{ fault: ..., result: ... }" }` |*1: Geth call traces contain nearly identical information to Parity call traces. There are differences such as 1) they include precompile calls, 2) they used a nested schema instead of a list, 3) they do not include block rewards. See [here](https://github.com/blockchain-etl/ethereum-etl/blob/develop/docs/schema.md#differences-between-geth-and-parity-tracescsv) for additional differences.*
*2: There are four types of state changes: balances, codes, nonces, and storage. State-related traces include information about all four.*
*3: "tracer is interpreted as a JavaScript expression that is expected to evaluate to an object which must expose the result and fault methods. There exist 4 additional methods, namely: setup, step, enter, and exit. enter and exit must be present or omitted together."*
## Trace Methods
RPC methods are used to obtain trace data from RPC endpoints.
Each method applies one or more tracers to a particular scope of data, such as a block, transaction, or call data.
| rpc method | description | tracers |
| --: | --- | --- |
| `trace_block` | basic block trace | parity calls
| `trace_transaction` | basic transaction trace | parity calls
| `trace_replayBlockTransactions` | advanced block trace | all parity tracers
| `trace_replayTransaction` | advanced transaction trace | all parity tracers
| `trace_filter` | query a subset of traces | all parity tracers
| `trace_call` | trace custom call_data | all parity tracers
| `trace_callMany` | trace sequence of call_data | all parity tracers
| `trace_rawTransaction` | parity call_data trace | all parity tracers
| `trace_get` | parity indexed trace | parity calls
| `debug_traceBlock` | advanced block trace | all geth tracers
| `debug_traceTransaction` | basic transaction trace | all geth tracers
| `debug_traceCall` | trace custom call_data | all geth tracers
| `debug_traceBlockByNumber` | advanced block trace | all geth tracers
| `debug_traceBlockByHash` | advanced block trace | all geth tracers## Node Client Support
Node clients track the state of the chain and can perform tracing on the chain's history.
Each node client supports a different set of tracers and trace methods.
| rpc method | [geth](https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers) | [reth](https://paradigmxyz.github.io/reth/jsonrpc/intro.html) | [erigon](https://github.com/ledgerwatch/erigon/blob/devel/cmd/rpcdaemon/README.md) | [besu](https://besu.hyperledger.org/public-networks/reference/api) | [nethermind](https://docs.nethermind.io/interacting/json-rpc-ns/trace) |
| --: | :-: | :-: | :-: | :-: | :-: |
| `trace_block` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `trace_transaction` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `trace_replayBlockTransactions` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `trace_replayTransaction` | ❌ | ✅ | ✅ | ❌ | ✅ |
| `trace_filter` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `trace_call` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `trace_callMany` | ❌ | ✅ | ✅ | ✅ | ❌ |
| `trace_rawTransaction` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `trace_get` | ❌ | ✅ | ✅ | ✅ | ❌ |
| `debug_traceBlock` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `debug_traceTransaction` | ✅ | ✅ | ✅ | ❌ | ✅ |
| `debug_traceCall` | ✅ | ✅ | ✅ | ❌ | ✅ |
| `debug_traceBlockByNumber` | ✅ | ✅ | ✅ | ❌ | ✅ |
| `debug_traceBlockByHash` | ✅ | ✅ | ✅ | ✅ | ✅ |The set of traces that can be obtained for a chain is determined by the clients that support that chain:
| rpc method | geth | reth | [erigon](https://github.com/ledgerwatch/erigon#system-requirements) | [besu](https://besu.hyperledger.org/public-networks/get-started/connect/mainnet) | [nethermind](https://www.quicknode.com/guides/infrastructure/node-setup/how-to-run-nethermind-node) | geth fork |
| --: | :-: | :-: | :-: | :-: | :-: | :-: |
| ethereum | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| goerli | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| [arbitrum](https://docs.arbitrum.io/node-running/how-tos/running-a-full-node) | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
| [optimism](https://community.optimism.io/docs/developers/bedrock/node-operator-guide/) | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ |
| zora | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ |
| [base](https://docs.base.org/guides/run-a-base-node/) | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ |
| [polygon](https://wiki.polygon.technology/docs/category/operate-a-node/) | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ |
| [gnosis](https://docs.gnosischain.com/node/manual/execution) | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ |
| [bnb](https://github.com/bnb-chain/bsc) | ❌ | ❌ | ✅[*](https://github.com/node-real/bsc-erigon) | ❌ | ❌ | ✅ |## RPC Provider Support
RPC providers create endpoints where customers can access RPC data without having to run their own nodes.
Every node provider supports different tracers and trace methods.
| rpc method | [infura](https://docs.infura.io/networks/ethereum/json-rpc-methods/trace-methods) | [alchemy](https://docs.alchemy.com/reference/trace-api)
([pricing](https://docs.alchemy.com/reference/compute-unit-costs#debug-api)) | [quicknode](https://www.quicknode.com/docs/ethereum)
([pricing](https://www.quicknode.com/api-credits)) | [llamanodes](https://llamanodes.notion.site/Ethereum-Request-Method-Pricing-288b72d56067497c88deddef36dbb19e)
([pricing](https://llamanodes.notion.site/Ethereum-Request-Method-Pricing-288b72d56067497c88deddef36dbb19e)) | [chainstack](https://docs.chainstack.com/docs/debug-and-trace-apis)
([pricing](https://chainstack.com/pricing/)) |
| --: | :-: | :-: | :-: | :-: | :-: |
| `trace_block` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `trace_transaction` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `trace_replayBlockTransactions` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `trace_replayTransaction` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `trace_filter` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `trace_call` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `trace_callMany` | ✅ | ❌ | ✅ | ✅ | ✅ |
| `trace_rawTransaction` | ❌ | ✅ | ✅ | ❌ | ✅ |
| `trace_get` | ❌ | ✅ | ❌ | ✅ | ✅ |
| `debug_traceBlock` | ❌ | ❌ | ✅ | ❌ | ✅ |
| `debug_traceTransaction` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `debug_traceCall` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `debug_traceBlockByNumber` | ❌ | ✅ | ✅ | ✅ | ✅ |
| `debug_traceBlockByHash` | ❌ | ✅ | ✅ | ✅ | ✅ |## Ecosystem Tooling Support
Many different tools exist for obtaining and analyzing traces.
Each tool supports a different set of tracers and trace methods. The libraries in the javascript ecosystem generally do not support tracing.
📟 = can use from command line
🐍 = can use as a python library
🦀 = can use as a rust library| tracer | [cryo](https://github.com/paradigmxyz/cryo)
📟🐍🦀 | [ethereum
etl](https://github.com/blockchain-etl/ethereum-etl) 📟 | [ethers.rs](https://github.com/gakonst/ethers-rs)
🦀 | [ctc](https://github.com/checkthechain/checkthechain)
🐍 | [ape](https://github.com/apeworx/evm-trace)
🐍 | [web3py](https://github.com/ethereum/web3.py)
🐍 |
| --: | :-: | :-: | :-: | :-: | :-: | :-: |
| `parity calls` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `parity stateDiffs` | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `parity vmTraces` | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
| `geth opcodes` | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
| `geth calls` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| `geth preState` | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ |
| `geth stateDiffs` | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ |
| `geth 4byte counts` | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| `geth javascript` | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |## Hosted Data Platform Support
Hosted data platforms allow customers to interact with trace data directly without running their own infrastructure.
Most platforms only support call traces.
| tracer | [Dune](https://dune.com/docs/data-tables/raw/evm/traces/) | [Flipside](https://flipsidecrypto.xyz/) | [Bigquery](https://cloud.google.com/blog/products/data-analytics/ethereum-bigquery-public-dataset-smart-contract-analytics) | [Allium](https://docs.allium.so/data-tables/ethereum/decoded/decoded-traces) |
| --: | :-: | :-: | :-: | :-: |
| `parity calls` | ✅ | ✅ | ✅ | ✅ |
| `parity stateDiffs` | ❌ | ❌ | ❌ | ❌ |
| `parity vmTraces` | ❌ | ❌ | ❌ | ❌ |
| `geth opcodes` | ❌ | ❌ | ❌ | ❌ |
| `geth calls` | ✅ | ✅ | ✅ | ✅ |
| `geth preState` | ❌ | ❌ | ❌ | ❌ |
| `geth state diffs` | ❌ | ❌ | ❌ | ❌ |
| `geth 4byte counts` | ❌ | ❌ | ❌ | ❌ |
| `geth javascript` | ❌ | ❌ | ❌ | ❌ |## Example Tracer Data
A 100 block sample of data is provided for each tracer (block range 10,000,000 through 10,000,099)
tracer
schema
data
collection command
parity calls
schema- action_from: binary
- action_to: binary
- action_value: string
- action_gas: uint32
- action_input: binary
- action_call_type: string
- action_init: binary
- action_reward_type: string
- action_type: string
- result_gas_used: uint32
- result_output: binary
- result_code: binary
- result_address: binary
- trace_address: string
- subtraces: uint32
- transaction_index: uint32
- transaction_hash: binary
- block_number: uint32
- block_hash: binary
- error: string
- chain_id: uint64
parquet
cryo traces -b 10M:+100
parity stateDiffs balances
schema- transaction_hash: binary
- block_number: uint32
- address: binary
- from_value_string: string
- from_value_binary: binary
- from_value_f64: float64
- to_value_string: string
- to_value_binary: binary
- to_value_f64: float64
- chain_id: uint64
- transaction_index: uint32
parquet
cryo balance_diffs -b 10M:+100
parity stateDiffs codes
schema- block_number: uint32
- transaction_index: uint32
- transaction_hash: binary
- address: binary
- from_value: binary
- to_value: binary
- chain_id: uint64
parquet
cryo code_diffs -b 10M:+100
parity stateDiffs nonces
schema- block_number: uint32
- transaction_index: uint32
- transaction_hash: binary
- address: binary
- from_value: uint64
- to_value: uint64
- chain_id: uint64
parquet
cryo nonce_diffs -b 10M:+100
parity stateDiffs storage
schema- block_number: uint32
- transaction_index: uint32
- transaction_hash: binary
- address: binary
- slot: binary
- from_value: binary
- to_value: binary
- chain_id: uint64
parquet
cryo storage_diffs -b 10M:+100
parity vmTraces
schema- block_number: uint32
- transaction_index: uint32
- pc: uint64
- cost: uint64
- used: uint64
- op: string
- chain_id: uint64
parquet
cryo vm_traces -b 10M:+100
geth opcodes
schema- block_number: uint32
- transaction_hash: binary
- transaction_index: uint32
- trace_address: string
- depth: uint64
- error: string
- gas: uint64
- gas_cost: uint64
- op: string
- pc: uint64
- refund_counter: uint64
- return_data: binary
- chain_id: uint64
parquet
cryo geth_opcodes -b 10M:+100 \
--include-columns stack storage
geth calls
schema- typ: string
- from_address: binary
- to_address: binary
- value_string: string
- value_binary: binary
- value_f64: float64
- gas_string: string
- gas_binary: binary
- gas_f64: float64
- gas_used_string: string
- gas_used_binary: binary
- gas_used_f64: float64
- input: binary
- output: binary
- error: string
- block_number: uint32
- transaction_hash: binary
- transaction_index: uint32
- trace_address: string
- chain_id: uint64
parquet
cryo geth_calls -b 10M:+100
geth prestate balances
schema- block_number: uint32
- transaction_index: uint32
- transaction_hash: binary
- address: binary
- balance_binary: binary
- balance_string: string
- balance_f64: float64
- chain_id: uint64
parquet
cryo balance_reads -b 10M:+100
geth prestate codes
schema- block_number: uint32
- transaction_index: uint32
- transaction_hash: binary
- contract_address: binary
- code: binary
- chain_id: uint64
parquet
cryo code_reads -b 10M:+100
geth prestate nonces
schema- block_number: uint32
- transaction_index: uint32
- transaction_hash: binary
- address: binary
- nonce: uint64
- chain_id: uint64
parquet
cryo nonce_reads -b 10M:+100
geth prestate storages
schema- block_number: uint32
- transaction_index: uint32
- transaction_hash: binary
- contract_address: binary
- slot: binary
- value: binary
- chain_id: uint64
parquet
cryo storage_reads -b 10M:+100
geth stateDiffs balances
schema- block_number: uint32
- transaction_index: uint64
- transaction_hash: binary
- address: binary
- from_value_f64: float64
- from_value_binary: binary
- from_value_string: string
- to_value_f64: float64
- to_value_binary: binary
- to_value_string: string
- chain_id: uint64
parquet
cryo geth_balance_diffs -b 10M:+100
geth stateDiffs codes
schema- block_number: uint32
- transaction_index: uint64
- transaction_hash: binary
- address: binary
- from_value: binary
- to_value: binary
- chain_id: uint64
parquet
cryo geth_code_diffs -b 10M:+100
geth stateDiffs nonces
schema- block_number: uint32
- transaction_index: uint64
- transaction_hash: binary
- address: binary
- from_value_f64: float64
- from_value_binary: binary
- from_value_string: string
- to_value_f64: float64
- to_value_binary: binary
- to_value_string: string
- chain_id: uint64
parquet
cryo geth_nonce_diffs -b 10M:+100
geth stateDiffs storages
schema- block_number: uint32
- transaction_index: uint64
- transaction_hash: binary
- address: binary
- slot: binary
- from_value: binary
- to_value: binary
- chain_id: uint64
parquet
cryo geth_storage_diffs -b 10M:+100
geth 4byte counts
schema- block_number: uint32
- transaction_index: uint32
- transaction_hash: binary
- signature: binary
- size: uint64
- count: uint64
- chain_id: uint64
parquet
cryo 4byte_counts -b 10M:+100