debug_traceTransaction
https://api.triport.io/v1/ethReplays a single already-mined transaction and returns its full EVM execution trace.
debug_traceTransaction re-executes a transaction that has already been included
in a block and records every step of its EVM execution. It is the canonical way
to understand why a transaction behaved the way it did — which opcodes ran,
how gas was consumed, what state was touched, where it reverted, and the revert
reason.
By default the method returns a struct (opcode) log: a step-by-step list of
every executed opcode with its program counter, gas, stack, memory, and storage
deltas. Because these logs can be very large for complex transactions, you will
usually pass a tracer in the options object instead — for example
callTracer to get a compact tree of internal calls, or prestateTracer to get
the accounts and storage the transaction read. See
Tracer options below.
This is a debug-namespace method available on the Pro tier and above. It
is rate limited per tier (5 RPS on Pro, 15 RPS on Business) with a short burst
allowance; there is no daily quota. Tracing is computationally heavy — keep the
opcode-level default reserved for the transactions you genuinely need to inspect,
and prefer a focused tracer where possible.
Parameters
Two positional parameters.
txHashstringrequired0x-prefixed 32-byte hash of the transaction to trace. The transaction must already be mined into a block.optionsobjectoptionalTracer optionsobjecttracerstringcallTracer (call tree), prestateTracer (touched accounts/storage), 4byteTracer (function-selector counts), or opcodeTracer. If omitted, the default opcode-level struct logger is used.tracerConfigobjectcallTracer, { "onlyTopCall": true } limits output to the top-level call (no internal calls); { "withLog": true } includes emitted logs.timeoutstring"10s"). Long traces that exceed this are aborted.disableStoragebooleandisableStackbooleanenableMemorybooleanenableReturnDatabooleanResponse
With tracer: "callTracer", the result is the transaction's call tree:
The default struct logger (no tracer) instead returns an object with
gas, failed, returnValue, and a structLogs array (one entry per opcode).
typestringCALL, STATICCALL, DELEGATECALL, CREATE, CREATE2, or SELFDESTRUCT.fromstringtostringvaluestring0x-prefixed hex wei transferred with the call.gasstring0x-prefixed hex gas supplied to the frame.gasUsedstring0x-prefixed hex gas actually consumed.inputstring0x-prefixed hex calldata.outputstring0x-prefixed hex return data.errorstringout of gas, execution reverted).revertReasonstringcallsarrayErrors
| Code | Meaning | When it happens |
|---|---|---|
-32002 | tier_insufficient | Your API key's tier is below Pro; this debug-namespace method is not enabled for it. The error.data carries current_tier, required_tier, and upgrade_url. |
-32003 | rate_limited | You exceeded your tier's request rate (5 RPS on Pro, 15 RPS on Business) including burst. Honor the Retry-After header / error.data.retry_after_sec and retry after a short back-off. |
See the shared error envelope reference for the full error object shape and handling guidance.
Examples
JavaScript (fetch)
const res = await fetch("https://api.triport.io/v1/eth", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.TRIPORT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "debug_traceTransaction",
params: [
"0x5b8d2a3c9f1e7b04c6f2a1d8e3047b9a6c1f0e2d4b8a7c5e9f3a1d2c4b6e8f0a",
{ tracer: "callTracer", tracerConfig: { withLog: true } },
],
}),
});
const { result } = await res.json();
console.log(result.type, result.gasUsed, result.calls?.length ?? 0);TypeScript SDK (@triport/sdk)
import { Triport } from "@triport/sdk";
const triport = new Triport({ apiKey: process.env.TRIPORT_API_KEY! });
const trace = await triport.eth.request("debug_traceTransaction", [
"0x5b8d2a3c9f1e7b04c6f2a1d8e3047b9a6c1f0e2d4b8a7c5e9f3a1d2c4b6e8f0a",
{ tracer: "callTracer", tracerConfig: { onlyTopCall: false } },
]);
console.log(trace.gasUsed);Python (triport-sdk)
import os
from triport import Triport
triport = Triport(api_key=os.environ["TRIPORT_API_KEY"])
trace = triport.eth.request(
"debug_traceTransaction",
[
"0x5b8d2a3c9f1e7b04c6f2a1d8e3047b9a6c1f0e2d4b8a7c5e9f3a1d2c4b6e8f0a",
{"tracer": "callTracer", "tracerConfig": {"withLog": True}},
],
)
print(trace["type"], trace["gasUsed"])Notes
- Pick the smallest tracer that answers your question.
callTraceris the right default for "what calls did this transaction make and where did it revert"; reach for the opcode-level struct logger only when you need step-by-step EVM detail, and usedisableStack/disableStorageto keep the payload manageable. - The transaction must already be mined. To trace a hypothetical call that
has not been sent, use
debug_traceCallinstead; to trace every transaction in a block, usedebug_traceBlockByNumberordebug_traceBlockByHash. callTracerresults are returned for the whole transaction as a single tree; settracerConfig.onlyTopCall: trueif you only need the outermost frame.- Raise
timeout(e.g."30s") for unusually deep or compute-heavy transactions whose default 5-second trace would otherwise be aborted.