Skip to main content

Quick Start

Ethereum Virtual Machine transaction tracing tool

Dependencies

  • Python 3.10 or newer. CI tests Python 3.10–3.14.

Installation

via pip

You can install the latest release via pip:

pip install evm-trace

From source

To install the current development version from source:

git clone https://github.com/ApeWorX/evm-trace.git
cd evm-trace
python -m pip install .

See CONTRIBUTING.md for development setup with uv.

Quick Usage

Geth Style Traces

If you are using a node that supports the debug_traceTransaction RPC, you can use web3.py to get trace frames:

from web3 import HTTPProvider, Web3
from evm_trace import TraceFrame

web3 = Web3(HTTPProvider("https://path.to.my.node"))
txn_hash = "0x..."
struct_logs = web3.manager.request_blocking("debug_traceTransaction", [txn_hash]).structLogs
for item in struct_logs:
    frame = TraceFrame.model_validate(item)

If you want to get the call-tree node, you can do:

from evm_trace import CallType, get_calltree_from_geth_trace

root_node_kwargs = {
    "gas_cost": 10000000,
    "gas_limit": 10000000000,
    "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "calldata": "0x00",
    "value": 1000,
    "call_type": CallType.CALL,
}

# Where `trace` is a `TraceFrame` (see example above)
calltree = get_calltree_from_geth_trace(trace, **root_node_kwargs)

Parity Style Traces

If you are using a node that supports the trace_transaction RPC, you can use web3.py to get trace objects:

from evm_trace import CallType, ParityTraceList

raw_trace_list = web3.manager.request_blocking("trace_transaction", [txn_hash])
trace_list = ParityTraceList.model_validate(raw_trace_list)

And to make call-tree nodes, you can do:

from evm_trace import get_calltree_from_parity_trace

tree = get_calltree_from_parity_trace(trace_list)

Compressed VM Traces

Some clients support trace_replayTransaction with ["vmTrace"]. This is an opcode trace containing stack and memory deltas, distinct from the Parity call tree above:

from evm_trace.vmtrace import from_rpc_response, to_trace_frames

# response_bytes is the complete JSON-RPC response, encoded as bytes.
vm_trace = from_rpc_response(response_bytes)
for frame in to_trace_frames(vm_trace, address=transaction_to):
    print(frame.pc, frame.op, frame.stack)

op and idx are optional client extensions. The converter can recover opcode names from code and pc, reconstruct Cancun stack effects and memory expansion, and replay DUP, SWAP, and MCOPY directly. Memory snapshots are taken before the current instruction expands or writes memory, matching modern Geth struct logs. This changes the older converter's expansion timing.

Recovered opcode names use Geth spelling (KECCAK256 for 0x20, DIFFICULTY for 0x44). The trace does not identify the fork, so 0x44 cannot distinguish pre-Merge difficulty from post-Merge randomness. Explicit names supplied by the client are preserved.

frame.address identifies the execution context: DELEGATECALL and CALLCODE retain their caller's context, while successful CREATE operations use the returned address. Failed creation addresses are unavailable. copy_memory=False yields a mutable memoryview; consume it immediately.

These synthetic frames do not expose gas/refund/error fields, and storage contains only the storage deltas reported so far in that call. They are not a complete Geth TraceFrame substitute. Client output can also be incomplete; see the upstream Reth fixes. Missing bytecode (when opcode names are absent) and missing CALL/CREATE result pushes raise evm_trace.vmtrace.IncompleteTraceError, a ValueError subclass. Other missing or incorrect client data may still produce incorrect frames.

For call-tree reconstruction, struct logs need memory enabled to recover calldata, initcode, events, and return values. If a call has no opcode frames (for example a precompile), enable return-data capture as well; without it the full returned bytes cannot be recovered from the truncated output-memory copy. LOG0 events have no topics and their selector is None.

Events and call order

Struct-log call trees include LOG0–LOG4 events. For callTracer, request {"tracer": "callTracer", "tracerConfig": {"withLog": true}} to include logs; get_calltree_from_geth_call_trace imports them into each node's events list. The emitting event.address is retained when the client supplies it, including logs emitted through DELEGATECALL.

event.position is the number of child calls preceding that event in its parent. The text renderer uses it to interleave events and calls in execution order, while events and calls remain separate lists. Older traces without positions use None and retain the previous events-first display order. If callers filter out child calls, they should update event positions; positions beyond the remaining calls render at the end.

Struct logs include attempted emissions even when execution later reverts. A client's callTracer may discard reverted logs, so event lists across these formats are not necessarily equivalent for failed calls.

Gas Reports

If you are using a node that supports creating traces, you can get a gas report.

from evm_trace.gas import get_gas_report

# see examples above for creating a calltree
calltree = get_calltree_from_geth_trace(trace, **root_node_kwargs)

gas_report = get_gas_report(calltree)

For a more custom report, use the merge_reports method to combine a list of reports into a single report. Pass two or more Dict[Any, Dict[Any, List[int]]] to combine reports where List[int] is the gas used.

Customize the values of Any accordingly:

  1. The first Any represents the bytes from the address.
  2. The second Any represents the method selector.

For example, you may replace addresses with token names or selector bytes with signature call strings.

Import the method like so:

from evm_trace.gas import merge_reports

Development

This project is in development and should be considered a beta. Things might not be in their final state and breaking changes may occur. Comments, questions, criticisms and pull requests are welcomed.

License

This project is licensed under the Apache 2.0.

Metadata

Release files for evm-trace 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for evm-trace 0.3.0
File Size Uploaded
evm_trace-0.3.0.tar.gz 939.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for evm-trace 0.3.0
File Interpreter ABI Platform
evm_trace-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 963.8 kB

Release files / evm_trace-0.3.0.tar.gz

Download URL evm_trace-0.3.0.tar.gz
Size 939.8 kB
Tags Source
SHA-256 checksum
How to use checksums
7984a635e86e5681e8913d04161476b2336f886ad65496c456014f63228dc820
BLAKE2b-256 checksum
How to use checksums
638fc14b66e1499b82c5462dd5d855db946691ddb512f260df6835be66a14fb6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Release files / evm_trace-0.3.0-py3-none-any.whl

Download URL evm_trace-0.3.0-py3-none-any.whl
Size 24.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
539e0c5a0a534c244d541b998b6c0da86ea7b54cc153a9f8bcae5baf34bbb078
BLAKE2b-256 checksum
How to use checksums
36f21a2eb1e9184353d9a7e324f0c497f9e803d41ca906bf69d95775083fb7b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page