Tornado的现金池,以DAI池子为例,每个Coin为100DAI。
目前有三个Coin:C1, C2, C3。
C1,C2,C3 在池子里,即300DAI,另外还有2个nullifier在合约里存储。
nullifier是为了防止双花的数据结构,存储的是花出去的note对应的nullifier。
C1,C2,C3 被保存在一个Merkle树中,这些Coin对外是公开的。
H1, H2是哈希函数。
接下来是deposit过程,比如Alice转100DAI到Tornado合约中,她需要提供:
- C4 = H1(k, r) k 和 r 是随机选取的随机数
- MerkleProof(4) 为C4生成一个默克尔树证明
智能合约验证MerkleProof(4) 是否合法,并用C4更新合约的merkle树,同时更新state。
Alice会保存(k,r) 作为note,一个note对应一个Coin,这里的note就是Tornado生成的txt文件。
这里,外部观察者可以对应到C4和Alice地址的关系。
Bob手中有:
- note = (k’, r’)
- nf = H2(k’)
Bob需要证明:
- 该note对应默克尔树中的一个Coin,而且其对应的nullifier为 nf
Bob构建证明Π
- 公开信息:x = (root, nf, A)
- root 是默克尔树树根
- nf 是其提供的nf值,nf = H2(k’)
- A 是提现地址
- 私有witness = (k’, r’, C3, MerkleProof(3))
电路 Circuit(x,w)=0,需要满足:
- MerkleProof(C3)是正确的,也就是
C3确实在合约中保存的默克尔树中
- C3 = H1(k’, r’),C3确实为note的哈希
- nf = H2(k’),nf是k’的哈希
注意,这里A没有在电路中,但是也包含在公开陈述中,是为了防止被矿工修改为其他值。
提现过程:
- Bob提供nf,proof,Anf,proof,A
- 合约检查ProofProof是否和(root, nf, A)匹配
- nf是否不在合约的nullifiers中(防止该note双花)
隐私性分析:
- nfnf和证明Π 没有泄露提现过程中是哪个Coin被花出去
- 并且Coin3不会被双花,因为nf = H2(k’) 现在被登记在了nullifiers中
提现的时候,gas fee谁来支付?——答案是relayer来支付。
为了防止用户提现的时候,将提现地址和支付fee的地址关联起来,这时候需要一个relayer代替用户和合约进行交互,并且在提现金额中把对应的fee进行扣除返回给用户。
三、总结用户存入资金的时候,只需要提供把note的哈希和插入Merkle树的相关Proof提供给合约。这时候,Coin和该用户是关联起来的。
用户提现的时候,只需要提供note对应的Merkle证明,证明该note对应的Coin存在于Merkle树中。
在合约的角度上,合约不知道究竟是哪个Coin被花费了,也不知道花费这个Coin的用户究竟是哪一个存币的用户,也就是说无法知道支取和存入的关系。
外部看来,只能知道合约默克尔树中保存Coin的人是谁,无法知道这个Coin是否被花费,更不知道支取和存入的关系了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)