交易 trace:debug_traceTransaction 与 Data API 的 trace 接口
为交易重建执行调用树:JSON-RPC 的 debug_traceTransaction 方法及其允许的 tracer 与各项守卫,以及 Data API 的 getTransactionTrace 与 getBlockTraces 接口及其最终性限制。
重建调用树的两种方式
交易 trace 是一次执行重建出来的调用树:调用了哪个合约、传入什么参数、消耗多少 gas、又发起了哪些子调用。BlockVectra 通过两个入口提供:
- JSON-RPC
debug_trace*—— 通过 JSON-RPC 端点在这条链的节点上执行,因此可以追踪节点仍保留的最新状态。 - Data API trace 接口 ——
GET /{chain}/transactions/{hash}/trace与GET /{chain}/blocks/{number}/traces通过 REST 返回已存储、已索引的调用树。
两者使用同一个 API key,并按方法权重以 CU 计量(见下方权重表)。选哪一种,取决于要查单笔交易还是整个区块、目标有多新,以及是否要一次取回整个区块。
debug_trace* 受到的限制
debug_trace* 请求需要该链的方法策略允许对应方法,且 tracer 取值在允许范围内:
- 允许的 tracer:
tracer参数仅允许内置原生 tracer ——callTracer、flatCallTracer、prestateTracer、4byteTracer、noopTracer,或缺省使用默认 struct logger。其余取值返回 JSON-RPC 错误-32602 tracer not allowed,不转发、不计费。 - trace 超时:
timeout参数需为合法 duration 且不超过 30s,否则返回-32602 trace timeout not allowed,不转发、不计费。 - 节点同步门:当某条链的节点未同步时,除
eth_chainId外的所有方法(包括debug_trace*与按哈希/高度的历史查询)一律返回-32010;该调用不转发、不计费。 - 状态窗口:
debug_traceCall、debug_traceBlockByNumber、debug_traceTransaction、debug_traceBlockByHash的目标区块必须在链的状态窗口内;早于窗口,或使用safe、finalized、earliest标签,返回-32011。节点自身对窗口外状态返回的错误不计费。区块、收据等非状态数据不受状态窗口限制,但受节点保留历史限制。 - 哈希预解析:
debug_traceTransaction与debug_traceBlockByHash会先把哈希解析为区块高度,再套用状态窗口。不是0x+ 64 位十六进制的哈希返回-32000 transaction not found/block not found,且不会查询节点;格式正确但节点查不到的哈希同样返回-32000;解析查询失败返回-32603 upstream unavailable(可重试)。以上都不转发、不计费。 - 逐链方法策略:某条链允许哪些
debug_trace*方法,由公开的GET /v1/chains响应公布。请在运行时读取,不要写死方法列表;链列表见支持的链,方法参考见 JSON-RPC 方法页面。
请求 debug_traceTransaction 并使用 callTracer
规格中的示例请求只带交易哈希。下面的调用在此基础上增加 tracer 参数以请求调用树;取值来自上面的 tracer 白名单,因此这里不编造任何响应体。
export BLOCKVECTRA_API_KEY=rgw_your_api_key
# 规格示例(reqTraceTx)只传交易哈希:
# {"jsonrpc":"2.0","id":1,"method":"debug_traceTransaction",
# "params":["0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"]}
# 增加 "tracer",用允许的内置原生 tracer 请求调用树。
curl -s "https://dev-api.blockvectra.network/v1/robinhood_mainnet" \
-H 'Content-Type: application/json' \
-H "x-api-key: $BLOCKVECTRA_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "debug_traceTransaction",
"params": [
"0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
{ "tracer": "callTracer" }
]
}'Data API trace 接口提供什么
Data API 为两种范围返回已存储的调用树。两者都不分页:绝不会有 next_cursor。
GET /{chain}/transactions/{hash}/trace—— 按交易哈希查询单笔交易的调用帧。GET /{chain}/blocks/{number}/traces—— 区块内每笔交易一棵调用树,按tx_index顺序排列。一个真实已终局且没有任何交易的区块返回data: []。
响应信封为:
TxTraceEnvelope:data直接是一个CallFrame,另有meta。BlockTracesEnvelope:data是BlockTraceItem数组,每项含txHash与result(一个CallFrame),另有meta。
两个 trace 接口都返回标准的以太坊 callTracer 格式。这是 Data API「金额安全」编码的一处例外:其他接口会把可能超过 2^53 的数值序列化为十进制字符串;这两个接口的 value、gas、gasUsed 是 0x 前缀的十六进制数量,而不是十进制字符串。每个 CallFrame 都带 type、from、gas、gasUsed、input;type 为 CALL、DELEGATECALL、STATICCALL、CREATE、CREATE2、SELFDESTRUCT 之一。CREATE/CREATE2 帧的目标地址没有 to,STATICCALL 帧没有 value。可选成员有 output(调用没有返回数据时缺失)、error(成功时缺失)、revertReason(仅在以 Error(string) 回滚时出现)、calls(按调用顺序排列的嵌套子调用)。调用帧里的其他成员会原样保留。
为便于理解结构,下面给出 CallFrame 的字段骨架——只是带注释的结构说明,不是实测响应。规格没有为这两个 trace 接口提供响应示例,因此这里不给出任何具体数值:
{
"type": "CALL | DELEGATECALL | STATICCALL | CREATE | CREATE2 | SELFDESTRUCT",
"from": "0x…", // 20 字节地址
"to": "0x…", // CREATE/CREATE2 的目标地址缺失
"value": "0x…", // 0x 前缀十六进制数量;STATICCALL 帧缺失
"gas": "0x…", // 0x 前缀十六进制数量
"gasUsed": "0x…", // 0x 前缀十六进制数量
"input": "0x…",
"output": "0x…", // 调用没有返回数据时缺失
"error": "…", // 成功时缺失
"revertReason": "…", // 仅当以 Error(string) 回滚时出现
"calls": [] // 按调用顺序排列的嵌套子调用;叶子帧缺失
}参数
{chain}(路径参数,必填):链标识,即GET /chains中某项的chain值。精确匹配且区分大小写;别名与数字 chain ID 均不接受。{hash}(路径参数,交易 trace 必填):32 字节交易哈希,0x前缀可选,大小写不限。{number}(路径参数,区块 traces 必填):非负区块高度。
覆盖范围与最终性
- 两个接口都属于
traces能力。未提供该能力的链返回422 no_coverage。提供该数据集的链以支持的链页面为准。 - trace 数据可能晚于该链其余已索引历史开始。早于该链首个已追踪区块的请求、落在已记录缺口内的请求,或交易已被索引但从未被追踪且已落后索引链头太远的请求,均返回
422 no_coverage;GET /chains以coverage.traces_from_block公布这一边界,早于它的 trace 请求(或落在无法追踪的区间内)返回422 no_coverage。 - 交易 trace 先把哈希解析为区块,再用
finalized_block检查:解析出的区块高于它时返回409 finality_exceeded。哈希查询没有可用于判断「尚未索引」的水位线,因此刚提交、索引尚未追上的交易同样返回404 not_found;请稍后重试,再当作永久不存在处理。 - 区块 traces 接口接收区块高度。
{number}高于as_of_block时返回409 not_indexed_yet,并带indexed_through;不高于as_of_block但高于finalized_block时返回409 finality_exceeded。 - 有交易但尚无 trace 数据的新近区块返回
503 unavailable,并带Retry-After头。等它落后索引链头超过该链的 trace 窗口后,就改为422 no_coverage。
用 Data API 请求 trace
export BLOCKVECTRA_API_KEY=rgw_your_api_key
# 单笔交易的调用帧。
curl -s "https://dev-api.blockvectra.network/v1/data/robinhood_mainnet/transactions/0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd/trace" \
-H "x-api-key: $BLOCKVECTRA_API_KEY"
# 某个已终局区块内,每笔交易一棵调用树。
curl -s "https://dev-api.blockvectra.network/v1/data/robinhood_mainnet/blocks/1/traces" \
-H "x-api-key: $BLOCKVECTRA_API_KEY"该选哪一个
| 典型任务 | 更适合 | 理由 |
|---|---|---|
| 交易刚落链就需要重建它 | debug_traceTransaction | 它针对节点当前状态执行,因此不限于 finalized_block 及以下的区块;可用性取决于该链的方法策略。 |
| 读取单笔交易已存储的调用树 | GET /{chain}/transactions/{hash}/trace | 通过 REST 直接返回该交易的 CallFrame;解析出的区块须不高于 finalized_block。 |
| 一次请求取回整个区块的全部调用树 | GET /{chain}/blocks/{number}/traces | 不分页返回整个区块,按 tx_index 顺序排列;区块须不高于 finalized_block。 |
| 追踪节点仍有、但数据集尚未存储的状态 | debug_trace* | Data API 只提供截止 finalized_block 的已存储数据;节点可以为更新的区块作答。 |
单次调用的 CU
每个方法都按其 CU 权重计费。下方权重在构建时从平台计划接口读取:
单次调用的 CU 权重
| 方法 | 单次调用 CU |
|---|---|
debug_trace* | 100 |
data.transaction_trace | 200 |
data.block_traces | 200 |
以上权重在构建时从平台计划接口读取。
被拒绝的请求不计费。完整计费规则见哪些请求不计费:错误码与计费规则。