Tenderly怎么调试交易?重放、状态与核验

 / 
2

Tenderly 调试交易的核心路径有两条,用途不同:Debugger 用于逐行剖析一笔已经上链的交易,Simulator 用于在不动真实资产的前提下预演一笔还没发的交易。如果你面对的是"这笔交易为什么失败了",从 Debugger 进入;如果你想知道"这笔交易发出去会怎样",从 Simulator 进入。重放不是目的,通过重放看清状态变化和回滚点才是。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

Debugger:从失败交易进入,定位回滚点

Debugger 的入口在交易详情页右上角。打开一笔具体交易后,点击 Debugger 按钮,你会看到四个区域:左上执行跟踪(Execution Trace)、右上合约源码、左下堆栈跟踪、右下调用信息。

执行跟踪显示交易生命周期中的每一次调用。如果交易失败了,跟踪里会标出回滚发生的精确位置。点击那个位置,右侧的合约源码会跳到对应的代码行。这是 Debugger 最直接的用途:把"交易失败"这个笼统的结果,定位到某一行 Solidity 代码或某一个 EVM 操作码上。

导航按钮的含义需要分清:Next/Previous 在调用跟踪中逐条移动,Step Up 和 Step Over 用于在堆栈层级之间跳转。Step Over 会跳过当前函数的内部调用,Step Up 回到上一层。如果你只想看合约之间的调用关系而不想陷入每个内部函数的细节,用执行跟踪区域顶部的过滤器,切换到只显示 CALL 和 DELEGATECALL。

右下角的调用信息以 JSON 格式显示当前调用的解码细节,包括函数名、操作码、调用者地址、解码后的输入输出、以及 gas 使用统计。如果你需要检查某个变量在执行到某一步时的值,用 Evaluate 功能输入表达式。它支持数组和结构体,但不支持元组。

Simulator:预演交易,状态覆盖是关键

Simulator 的入口在 Simulator 页面,或者从任何交易详情页点击 Re-Simulate 把现有交易参数载入构建器。单次模拟就是一个一步的 bundle,你可以指定 From 地址、目标合约、函数和参数,然后运行。

一个 Simulator 特有的能力是 cheatcodes,它们在这一步执行之前立即生效。常用的包括:

  • Fund address:给任意地址充值代币余额,让你在没有真实持仓的情况下测试转账

  • State overrides:覆盖合约存储槽、余额或字节码

  • Increase block / Override timestamp:调整区块上下文

  • Override gas & value:设置自定义 gas 限制和 ETH 值

如果你在测试一个需要先 approve 再 transferFrom 的流程,单次模拟不够用。用 Simulation bundle,最多五步共享状态,第一步 approve,第二步 transferFrom,每一步都能看到前一步造成的状态变更。

运行后,右侧面板会填充结果:解码输出、已使用的 gas、事件、状态变更、资金流向和 Gas Profiler。核验这笔模拟是否"成功"的标准不是看它有没有弹窗,而是看状态变更是否符合预期。State Changes 标签页会列出所有被修改的存储变量和余额,包括旧值和新值。如果你只看了"模拟成功"的提示就发真实交易,可能会漏掉某些合约状态被意外修改的情况。

重放与状态核验:两个容易混淆的概念

"重放"在 Tenderly 里至少有两种含义。Debugger 的重放是对一笔已上链交易的执行过程做逐行回溯,它不改变任何状态,只是让你看清历史发生了什么。Simulator 的重放(Re-Simulate)是把一笔交易的参数载入构建器,在最新网络状态或指定区块上重新执行,结果可能和原始交易不同,因为状态已经变了。

核验状态时,注意 Debugger 和 Simulator 展示的是不同层面的信息。Debugger 的 State Changes 显示的是这笔交易执行过程中的存储变化。Simulator 的 State Changes 显示的是模拟执行之后的状态,如果你用了 cheatcodes(比如 Fund address),模拟结果会包含这些人为注入的状态,不能直接当作真实链上结果。

一个实用的核验顺序:先用 Simulator 预演,看 State Changes 和 Fund Flow 是否符合你的意图;确认后发真实交易;拿到 txHash 后再用 Debugger 检查实际执行路径是否和模拟一致。不一致的地方,就是你需要排查的差异。

如果 Simulator 结果和预期不符

先检查 cheatcodes 是否干扰了结果。如果你用了 Fund address 给某个地址充值,模拟中该地址的余额是人为设置的,和真实链上状态不同。如果你用了 State overrides 修改了存储槽,后续所有依赖该存储的调用都会基于被修改的值执行。这些在 State Changes 里能看到,但容易被忽略。

另一个常见问题是 block 和 transaction_index 的选择。Simulator 默认在 Pending 区块的最新状态上执行。如果你想复现某个特定历史时刻的条件,需要指定 block_number。transaction_index 控制的是"在区块的第几笔交易之后执行",0 表示区块开始前,count 表示区块结束后。选错这两个参数,模拟结果可能和你试图复现的场景对不上。

你该从哪里开始

如果你手头有一笔失败的交易,先复制 txHash,在 Tenderly Explorer 中打开,点 Debugger,看执行跟踪里红色的回滚点。那是你排查的起点。

如果你还没有发交易,想验证一个合约调用是否可行,去 Simulator 页面,选网络和合约,填参数,运行。如果涉及授权或余额不足,用 cheatcodes 注入状态再试。模拟通过后,再发真实交易。

无论走哪条路径,核验的完成标准都是你看到了具体的状态变更和调用路径,而不是一个"成功"的徽章。Tenderly 的价值在于让你在发交易之前或失败之后看清细节,这个细节需要你自己去 State Changes 和 Execution Trace 里确认。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

参考资料

  1. Tenderly Documentation·How to Use Tenderly Debugger,页面发布或更新日期:2026-10-14;核查日期:2026-10-19。
  2. Tenderly Documentation·如何使用 Tenderly Debugger,页面发布或更新日期:2026-08-24;核查日期:2026-10-19。
  3. Tenderly Documentation·使用高级 Debugger 评估表达式,页面发布或更新日期:2026-08-24;核查日期:2026-10-19。
  4. Tenderly Documentation·Simulator UI,页面发布或更新日期:2026-08-27;核查日期:2026-10-19。
  5. Tenderly Documentation·单笔模拟,页面发布或更新日期:2026-07-07;核查日期:2026-10-19。