
在Tornado官网关于龙卷风币(Tornado Cash)的技术讨论中,最常被提及的两个概念是”承诺”(Commitment)和”注销码”(Nullifier)。这两个密码学原语构成了协议的核心逻辑,是理解其如何保障隐私与安全的关键。
1. 存款:承诺的诞生
当用户向龙卷风币(Tornado Cash)存款时,钱包会生成两个31字节的随机数——nullifier(注销码)和 secret(秘密值)。这两个随机数共同构成用户的票据(Note),是未来提款的唯一凭证。
为了防止票据直接暴露在链上,系统会通过 Pedersen 哈希将nullifier和secret压缩成一个独一无二的字符串,称为“承诺”(Commitment)。这个承诺就像是这笔存款的”数字指纹”,会被作为叶子节点插入到 Merkle Tree 中。
关于Merkle Tree在龙卷风币(Tornado Cash)中的技术细节,可以阅读我们的文章:Merkle Tree 与 zk-SNARKs 协同工作。

2. 提款:注销码的验证
当用户提款时,需要在本地生成一个 zk-SNARK 证明。这个证明的核心任务之一,是证明用户拥有一个有效的票据,且该票据尚未被使用过。
这里的关键是nullifier。提款时,用户会披露nullifier的哈希值(而不是nullifier本身),智能合约会检查这个哈希值是否已经被记录过。如果已经被记录,则说明该票据已被提走,交易将被拒绝;如果未被记录,则合约会记录这个nullifier哈希值,并将资金发送到用户指定的提款地址。
这个过程实现了两个关键目标:
- 防止双花攻击:通过记录已使用的
nullifier,确保每个票据只能被提款一次。 - 保护隐私:整个证明过程不会透露任何关于存款的具体信息,外部观察者只能看到一个成功的提款事件。
想了解更多关于龙卷风币(Tornado Cash)的zk-SNARK技术原理,可以阅读:Tornado Cash 与 zk-SNARK。
3. 为什么需要两个随机数?
nullifier和secret各司其职:
nullifier用于防重放(防止双花)。secret用于隐私保护(防止存款被关联)。
nullifier需要被披露(通过哈希值)才能防止双花,但secret必须始终保密,否则任何人都可以窃取资金。这种分工使协议既安全又私密。
4. 对用户的意义
这对密码学原语的设计决定了龙卷风币(Tornado Cash)的核心安全模型:
- 票据(
nullifier+secret)是唯一的取款凭证:任何人只要拥有它,不仅可以取走资金,还能知道这笔存款的来源地址。 - 承诺公开、票据保密:链上只记录承诺,票据由用户离线保存,这就是隐私的来源。
- 注销码公开但不泄露隐私:
nullifier的哈希值被记录在链上用于防双花,但无法被反向推导出原始票据。
这也意味着用户需要谨慎保管票据:一旦丢失,资金将永久锁定,无法恢复。
查看龙卷风币(Tornado Cash)的最新链上数据和生态指标,可以访问我们的数据看板。
💡 常见疑问解答
Tornado Cash中的承诺(Commitment)是如何生成的?
用户存款时钱包生成两个31字节的随机数nullifier和secret,通过Pedersen哈希压缩成一个独一无二的字符串(承诺),该承诺作为叶子节点插入Merkle Tree,链上只记录承诺而非票据本身。
注销码(Nullifier)在提款时起什么作用?
提款时用户披露nullifier的哈希值,智能合约检查该哈希是否已被记录。如已被记录则拒绝交易,否则记录该哈希并放款。nullifier用于防止双花攻击,secret用于保护隐私。
为什么需要nullifier和secret两个随机数?
nullifier用于防重放(防止双花),需要被披露(通过哈希值);secret用于隐私保护(防止存款被关联),必须始终保密。这种分工使协议既安全又私密。
票据丢失了还能找回资金吗?
不能。票据(nullifier+secret)是唯一的取款凭证,一旦丢失资金将永久锁定无法恢复。承诺公开但票据由用户离线保存,这就是隐私的来源。
