Skip to content

如何调试合约


UTXO_Compiler 内置了一个交互式命令行调试器,在本地 BVM 模拟器上单步执行编译后的字节码。你可以设置断点、查看栈状态、跟踪函数调用,也可以加载真实交易数据来模拟链上环境。


启动调试器

bash
# 基本启动
./utxo_compiler my_contract.ct --debug

# 合约用到了子作用域副栈操作(--asa 模式)
./utxo_compiler my_contract.ct --debug --asa

启动调试器后先要选择语言:

bash
选择 CLI 语言 / Select CLI language [zh/en] (默认 default: zh):

选择调试目标

如果合约有多个公有函数,调试器会提示选择:

=====================================
可调试的函数列表:
=====================================
[1] getCountFromPreTX (public, 1 个参数)
[2] verifyCurrentTX (public, 1 个参数)

请选择要调试的函数 (输入编号 1-2, 或直接回车跳过): _
  • 输入编号,只调试该函数
  • 直接回车,依次对所有公有函数输入参数并调试

导入的库函数不会作为独立调试目标列出;只有选中的公有函数调用它们时,它们才会执行。

接着输入函数参数:

=====================================
调试函数: getCountFromPreTX (public)
需要为以下参数提供初始值:
=====================================

参数 1/1: pretx (结构体: PreTX, 17 个字段)

参数输入格式

类型输入方式
整数42-100x1a(十六进制整数)
hex 字节0x1234abcd
字符串"hello"(用引号包围)
默认值直接回车使用类型默认值

命令参考

选择待调试函数和输入参数后出现 REPL 提示符:

=====================================
已将 17 个参数压入主栈
=====================================
=====================================
  UTXO_Compiler Debugger v1.0
=====================================
加载: my_contract.ct
输入 'help' 查看可用命令。

(apc-debug) _

输入 help 查看所有可用命令。

执行控制

命令简写说明
runr开始执行(或从当前状态继续执行)
continuec从断点或暂停处继续
steps单步进入(遇到函数调用时进入)
nextn单步跳过(不进入函数调用,将整个调用当作一步)
finishf跳出当前函数,执行到调用方的下一行
reset将 VM 完全重置到进入 REPL 时的初始状态
pause暂停正在运行的执行

断点管理

命令简写说明
break <行号>b <N>在指定源码行设置断点
break <函数名>b <name>在函数入口设置断点
delete <断点ID>d <ID>删除指定断点
disable <断点ID>禁用断点(不触发,但保留)
enable <断点ID>重新启用断点
info breakpointsinfo bp列出所有断点及其状态

状态查看

命令简写说明
list [行号]l显示源代码,默认以当前执行行为中心
stack显示主栈和副栈的当前内容
backtracebt显示函数调用栈
bytecode [N]bc [N]显示当前执行位置附近的字节码,N 为上下文行数

交易数据

命令说明
settxfile <路径>从 JSON 文件加载交易数据(用于 BVM.* 字段的模拟)
showtx显示当前已加载的交易数据

其他

命令说明
help / h显示命令帮助
quit / q / exit退出调试器
clear清屏

生成调试信息(不启动调试器)

如果只需要生成调试信息文件用于其他工具,使用 -d 标志:

bash
./utxo_compiler my_contract.ct -d

调试信息包含合约行号到字节码偏移的映射,以及函数符号表,供其他工具分析。


初级开发者易踩坑

  • 忘记先选择函数或输入参数:进入 REPL 前的参数输入会决定初始栈内容,栈不对时后面单步也会误导你。
  • run 当成自动重置:重新执行前建议先用 reset,避免从旧的 PC 或旧栈状态继续跑。
  • 没有加载交易上下文:合约读取 BVM.outputsHashBVM.unlockingInput 时,本地调试需要用 settxfile 提供模拟数据。
  • 只看最终结果,不看失败位置:调试拒绝路径时,失败位置比“是否跑完”更重要。

快速回顾

  • --debug 会先编译合约,再进入交互式调试器。
  • step 进入函数,next 跳过函数调用,continue 从断点继续。
  • stack 用来确认主栈和副栈是否符合预期。
  • 交易相关合约需要用 settxfile 加载模拟交易数据。
  • 只生成调试信息时,用 -d,不需要进入交互式调试器。

下一步


🇬🇧 English version