Skip to content

Latest commit

 

History

History
66 lines (34 loc) · 2.03 KB

TornadoCash.md

File metadata and controls

66 lines (34 loc) · 2.03 KB

Tornado Cash

Tornado Cash 本质上是一个基于零知识证明的资金混合池,核心思路可以用一句话概括:

把很多人的钱放进同一个"固定面额"的池子里搅混,取款时只需证明"我确实存过钱",而不用暴露"我存的是哪一笔"。

工作原理

存款

  1. 本地生成一个随机秘密 secret 与 nullifier,算出它的哈希 commitment,这有哈希会公开上链

    commitment = Hash(nullifier, secret)

  2. 同时算出 nullifierHash 留着取款的时候用,要公开的值(唯一目的是防双花,合约会检查它有没有被用过)

    nullifierHash = Hash(nullifier),

  3. 调用合约 Deposit 存入固定金额(比如 1 ETH),把 commitment 记录到链上的 Merkle 树里

    rootnew​ = H(…H(H(leafi​,siblingi​),⋅)…)

  4. 此时链上记录

    {存款地址addr​, commitment, v=1ETH, 时间戳}

取款

  1. 重新构建 Commintment 和 NullifierHash

  2. 确定 Commitment 是在 Merkle 树的第几个叶子节点

  3. 确定 Recepient (以及可选的 relayer、fee)

  4. 构造 ZK Proof

    π = Prove( 私密输入: nullifier, secret, path_i​​​ ; 公开输入: root, nullifierHash, recipient, relayer, fee​​ )

  5. 提交取款

    withdraw(π, root, nullifierHash, recipient, relayer, fee)

  6. 合约验证逻辑

    a. 验证 root 是历史上出现过的合法根

    b. 验证 nullifierHash 没有被用过(防双花核心)

    c. 验证 zk-proof 合法性

思考

  1. 为什么是固定额度?如果转账不同的额度怎么处理?

    保护金额的匿名性(避免通过金额把存款和取款关联起来)

    如果想转不同的额度,只能选择最接近的固定面额,多次使用不同池子(0.1 / 1 / 10 / 100 ETH)

  2. 匿名集的大小影响到实际隐私度

    如果在某个时间段内,只有一笔存款,关联性极大,任然可能被追踪。

  3. 前端被篡改风险

    如果前端被插入恶意代码,可能把用户的 deposit note 发给攻击者