name: compact-core:privacy-disclosure description: 当遇到“潜在见证值泄露”编译器错误、实现承诺-揭示模式、处理 persistentCommit/transientCommit 与 persistentHash/transientHash、或设计具有适当见证保护的隐私保护电路时使用。
隐私与披露
关于 Midnight 隐私模型的重要指导:何时需要披露、承诺模式以及见证保护。
披露规则
见证值未经显式 disclose() 包装,不得流向公共输出。
编译器会追踪代码中所有源自见证的值。如果一个值触及以下任何“披露触发器”,你必须用 disclose() 包装它:
| 触发器 | 为何需要披露 |
|---|---|
| 账本存储 | 链上数据是公开的 |
| 电路返回值 | 返回值会传递给 TypeScript |
| 外部合约 | 数据会离开你的合约边界 |
| 比较操作 | 比较操作可能泄露信息 |
快速决策树
该值是否源自见证?
├── 否 → 无需披露
└── 是 → 它是否流向:
├── 账本写入 → 需要 disclose()
├── 电路返回值 → 需要 disclose()
├── 比较操作 (==, <, >) → 需要 disclose()
└── 承诺 (transientCommit/persistentCommit) → 安全,无需披露
安全与不安全操作
| 操作 | 安全? | 原因 |
|---|---|---|
persistentCommit(x) |
✅ 安全 | 使用随机数隐藏值 |
transientCommit(x) |
✅ 安全 | 使用随机数隐藏值 |
persistentHash(x) |
❌ 不安全 | 无随机数,可能被暴力破解 |
transientHash(x) |
❌ 不安全 | 无随机数,可能被暴力破解 |
常见模式
承诺-揭示模式
witness get_secret(): Field;
// 阶段 1:承诺
export circuit commit(): Bytes<32> {
const secret = get_secret();
return persistentCommit(secret); // 安全:承诺隐藏了秘密
}
// 阶段 2:揭示 (需要披露)
export circuit reveal(): Field {
const secret = get_secret();
return disclose(secret); // 显式:用户知道这会揭示秘密
}
作废符模式
witness get_secret(): Field;
export circuit spend(commitment: Bytes<32>): Bytes<32> {
const secret = get_secret();
// 验证对秘密的知识
assert persistentCommit(secret) == commitment, "无效承诺";
// 生成作废符 (每个秘密唯一,不泄露信息)
const nullifier = persistentHash("nullifier", secret);
return nullifier;
}