name: compact-core:testing-debugging
description: 用于测试Compact合约、调试编译错误、理解诸如“潜在见证值泄露”或“电路约束失败”等错误信息、设置TypeScript测试框架,或为单元测试模拟见证函数。
测试与调试
测试Compact合约、调试常见错误以及理解编译器/运行时错误信息的重要指南。
常见错误速查
| 错误信息 |
可能原因 |
快速修复 |
潜在见证值泄露 |
见证值流向公共输出 |
添加 disclose() 或使用承诺 |
类型不匹配 |
操作中的类型不兼容 |
检查类型签名,使用 as 进行转换 |
无界循环 |
循环边界非编译时常量 |
使用字面量或 #N 参数作为边界 |
电路约束失败 |
运行时断言失败 |
检查断言条件和输入 |
证明生成失败 |
无效的见证值 |
验证见证函数返回有效数据 |
溢出 |
算术运算超出类型边界 |
使用更大的 Uint<N> 或检查边界 |
调试决策树
编译期间出错?
├── “潜在见证值泄露”
│ └── 参见:references/error-messages.md#disclosure-errors
├── “类型不匹配” 或 “无法转换”
│ └── 参见:references/error-messages.md#type-errors
├── “无界循环” 或 “边界必须为常量”
│ └── 参见:references/error-messages.md#loop-errors
└── 其他编译错误
└── 参见:references/error-messages.md
证明生成期间出错?
├── “断言失败” 或 “约束失败”
│ └── 检查断言条件和见证值
├── “证明生成失败”
│ └── 验证见证函数返回预期类型
└── “溢出” 或 “除零错误”
└── 检查算术边界
测试方法
单元测试电路
import { TestContext } from '@midnight-ntwrk/compact-testing';
describe('MyContract', () => {
let ctx: TestContext;
beforeEach(async () => {
ctx = await TestContext.create('my_contract.compact');
});
it('应处理有效输入', async () => {
const result = await ctx.call('process', [42n]);
expect(result.success).toBe(true);
});
});
见证模拟
const mockWitness = {
get_secret: () => BigInt('12345'),
get_balance: () => BigInt(1000)
};
const result = await ctx.call('transfer', [recipient], mockWitness);
状态验证
// 在电路执行后读取账本状态
const balance = await ctx.ledger.get('balances', userKey);
expect(balance).toBe(expectedBalance);
常见陷阱
| 陷阱 |
症状 |
解决方案 |
忘记 disclose() |
编译错误 |
添加显式披露 |
| 错误的ADT选择 |
证明效率低下 |
计数使用Counter,成员资格使用MerkleTree |
| 尝试无界循环 |
编译错误 |
使用有界的 for i in 0..N |
| Uint溢出 |
证明失败 |
使用更大的位宽或检查边界 |
| 除零错误 |
证明失败 |
除法前添加零检查 |
参考资料
示例