
龙卷风币(Tornado Cash)之所以能打破存款地址和提款地址之间的链上关联,关键在于它巧妙地结合了两种密码学工具:Merkle Tree 和 zk-SNARKs。
简单来说,Merkle Tree 负责高效地”记录”所有存款,而 zk-SNARKs 则让提款者能”证明”自己存过款,同时又不透露是哪一笔。理解它们如何协同工作,是理解龙卷风币(Tornado Cash)隐私模型的核心。
Tornado官网将为你深入解析这两大核心技术的协同原理。
1. Merkle Tree:存款的”指纹账本”
当用户存款时,会生成一个由两个31字节随机数——nullifier(注销码)和 secret(密钥)——组成的票据(Note)。这个票据是用户未来提款的唯一凭证。
为了防止票据直接暴露在链上,系统会通过 Pedersen 哈希 将其处理成一个独一无二的字符串,称为 “承诺”(Commitment)。承诺就像是这笔存款的”数字指纹”,会被作为叶子节点插入到一棵 MiMC Merkle Tree 中。
技术细节:
- Pedersen 哈希:一种在椭圆曲线上进行的高效哈希算法,非常适合在零知识证明中使用。
- MiMC 哈希:一种专门设计用于零知识证明的哈希函数,在合约中用于计算 Merkle Tree 的非叶子节点。
这个 Merkle Tree 的根(Merkle Root)就像是整个存款集合的”指纹”。任何一笔存款的变动(即一个叶子节点的改变),都会导致根的值发生彻底变化。因此,这个 Merkle Root 就成了一个不可篡改的、紧凑的存款账本摘要,其高度为20,可容纳超过一百万个存款记录。
想了解更多关于龙卷风币(Tornado Cash)的隐私保护流程,可以阅读我们的文章:龙卷风币隐私保护流程全图解。
2. zk-SNARKs:提款时的”无声证明”
当用户想要提款时,不需要出示存款时的”承诺”。相反,用户需要在本地生成一个 zk-SNARK 证明。这个证明实现了三个关键目标:
- 证明存款存在:证明用户拥有一个有效的”承诺”,且这个承诺是当前 Merkle Tree 中的一员。这通过提供从该叶子节点到树根的 Merkle 路径(一系列姐妹节点的哈希值)来实现。
- 保护隐私:证明过程不会透露这个”承诺”具体是哪个叶子节点,从而隐藏了存款的时间、金额等关键信息。
- 防止重复提款:证明中会包含一个 “注销码”(nullifier),用于标记该笔存款已被提取,有效防止双花攻击。

想深入了解龙卷风币(Tornado Cash)的 zk-SNARK 技术原理,可以阅读我们的文章:龙卷风币技术原理:零知识证明如何实现链上匿名。
3. 协同工作流程
- 存款:用户存入资金,系统生成秘密票据(
nullifier+secret),通过 Pedersen 哈希 创建”承诺”,将其作为新叶子插入 MiMC Merkle Tree,并更新 Merkle Root。 - 提款准备:用户在本地,基于其票据、对应的 Merkle 路径和当前的 Merkle Root,生成一个 zk-SNARK 证明。证明中包含了
nullifier的哈希值,用于防重放。 - 验证:龙卷风币(Tornado Cash)的智能合约在链上验证这个 zk-SNARK 证明,同时确认该笔存款的
nullifier尚未被使用过。 - 放款:验证通过后,合约记录该
nullifier,并将资金发送到用户指定的提款地址。
通过这种方式,Merkle Tree 提供了一个不可篡改且高效的数据结构来管理所有存款,而 zk-SNARKs 则提供了强大的隐私保护层,让用户可以”证明拥有”而不”暴露拥有什么”。两者结合,正是龙卷风币(Tornado Cash)实现去中心化隐私交易的密码学基石。
想了解龙卷风币(Tornado Cash)的技术架构全貌,可以阅读我们的文章:Tornado Cash 技术架构全解。
💡 常见疑问解答
Merkle Tree在Tornado Cash中起什么作用?
Merkle Tree负责高效记录所有存款,每个存款的承诺作为叶子节点插入树中。Merkle Root是整个存款集合的指纹,高度为20可容纳超过一百万笔存款记录。
zk-SNARKs在提款时实现哪些验证目标?
zk-SNARKs证明实现三个目标:证明用户拥有有效承诺且存在于Merkle Tree中(通过Merkle路径)、不透露具体是哪个叶子节点保护隐私、通过nullifier防止重复提款。
Tornado Cash使用了哪些哈希函数?
Tornado Cash使用Pedersen哈希(在椭圆曲线Baby Jubjub上进行的高效哈希,适合零知识证明)和MiMC哈希(专门用于零知识证明,在合约中计算Merkle Tree的非叶子节点)。
