美文网首页
Tornado.Cash 匿名协议及挖矿

Tornado.Cash 匿名协议及挖矿

作者: 雪落无留痕 | 来源:发表于2023-06-25 16:12 被阅读0次

    Tornado.Cash是以太坊上完全去中心化的匿名交易协议,基于zk-SNARK实现,可以切断交易中发送者和接收者的关联,目前支持代币有:ETH, DAI, cDAI(Compound Dai),USDC,USDT,WBTC。

    Tornado.Cash支持采用 relayer 进行取款,将资金发送到新生成的地址上。

    Tornado.Cash于2019年在以太坊上线,2021年6月,在 BSC 和 Polygon上部署, 分别支持BNB 和 Matic 代币的匿名化。

    Tornado.Cash支持一些代币进行匿名挖矿,可以获取TORN治理代币。

    匿名交易原理

    Tornado.Cash支持deposit 和 withdraw 两种操作, deposit 将用户将资金存入资金池中,经过混币后,再通过withdraw将资金取到一个新的地址中。因此越多人参与,匿名效果越好。

    存款

    用户要往合约存款,需要生成两个248bits的随机数k,r,k为nullifier,r为随机数,这两个数就是凭证。 计算

    commitment = H1(k||r), H1是PedersenHash
    

    commitment是触发TC合约存款函数deposit的唯一参数。

    deposit函数主要完成以下工作

    • 检查commitment是否已存在(合约要求commitment不能重复)
    • 将commitment插入到merkle树中
    • 将commitment标记为已存在(mapping(bytes32 => bool) public commitments)
    • 如果是针对ERC20的代币,则执行转账,将用户账户的token转到合约账户里。如果是ETH,则不用执行显示转账,在触发合约deposit函数时必须附带指定金额的ETH.

    合约deposit执行成功后会emit

    event Deposit(bytes32 indexed commitment, uint32 leafIndex, uint256 timestamp);
    

    用户可以确定自己的commitment处于叶子节点的位置。

    提款

    用户要想提款,必须向合约提供proof,证明用户知道某个commitment对应的隐私信息(k,r),同时不能让别人知道(k,r)的任何信息,确保别人不知道花费的是哪个commitment.

    具体步骤:

    1. 用户选择一个收款地址A和fee,fee是根据具体的中继者的收费标准确定。

    2. 用户选择一个Root,构造证明commitment存在的Merkle path。在合约里,存储里最近100个历史Root,而非所以的历史Root。

    3. 计算nullifier(即k)的hash, h=H1(k).

    4. 计算零知识证明的proof,具体算法用的是Groth16。约束条件为:

      1. h = H1(k)
      2. commitment = H1(k||r)
      3. commitment的Merkle证明

      公开输入:Root, h,

      隐私输入:k, r, l(commitment在叶子节点的位置), path

    5. 触发合约withdraw函数

      withdraw(bytes calldata _proof, bytes32 _root, bytes32 _nullifierHash, address payable _recipient, address payable _relayer, uint256 _fee, uint256 _refund)

    withdraw函数完成以下过程:

    1. 检查_nullifierHash是否被花掉
    2. 检查_root是否是历史root
    3. 验证_proof
    4. _nullifierHash标记为已花掉
    5. 处理转账:分别转给收款人和中继者(若有)。
    6. refund:这个字段是针对ERC20 token设置的,用户可以用自己的token跟中继者兑换一些ETH,可以用来支付以后的交易gas费用。

    Setup

    1. TC合约部署时绑定验证proof的合约,存/提款金额,Merkle树高度(20),特权账户(operator).
      等trusted setup完成之后,特权账户更新proof的验证密钥VK,然后将特权账户地址更新为0,之后便没有任何人可以更改VK,保证合约的安全性。
    2. 针对ERC20 token,部署合约时还要绑定对应的ERC20合约。

    凭证示例:

    tornado-eth-1-5-0xc594a62c82e8772b1731601a90d30f0d5b705fdcdd3147b46c3a1dbe546f58173f2a8ad7b19dce041e46a4626a48ff555b00eaa33ea47a5f6bf812d7c2c1

    在deposit时,需要更新20层的Merkle树, 需要消耗较多的gas; withdraw 生成证明的过程相对复杂,但消耗的gas较少。

    匿名挖矿

    匿名挖矿主要激励用户将资金在资金池存留更长时间,增加匿名池资金, 以提升交易匿名性。激励从2020.12开始, 到2021.12月截止。

    支持匿名挖矿的代币有:ETH, WBTC, DAI, cDAI. 资金存款每过一个块会获取固定AP(Anonymity Points) 奖励,AP 可以兑换 TORN代币,汇率是浮动的。

    (1) 首先用户发起deposit操作

       此时需要构建deposit Mekle 树,叶子节点为hash( address(torando) || commitment || blockNumber):       
    
     bytes32 leafHash = keccak256(abi.encode(deposit.instance, deposit.hash, deposit.block));
    
       但是更新Merkle树需要消耗大量的gas费用,因此合约首先记录deposit 的 LeafHash, 更新操作由第(3)步完成。  
    
       (2)   等过段时间后,用户发起withdraw 操作.
    
        此时需要构建 withdraw Merkle 树, 叶子节点为: hash(address(tornado) || nullifierHash || blockNumber)      
    
     bytes32 leafHash = keccak256(abi.encode(withdrawal.instance, withdrawal.hash, withdrawal.block));
    
        同上,更新Merkle 树由第(3) 步完成,合约记录withdraw 的 LeafHash. 
    

    (3) 需要有人调用 updateRoots, 更新deposit Merkle树和 withdraw Merkle 树,需要消耗大量的gas.

    (4) 用户需要利用凭证根据deposit和withdraw时间差获取奖励AP,为了不泄露凭证的信息,需要生成零知识证明,主要包括reward 和withdraw两种操作。

    \- reward: 主要为了领取奖励AP:rate * (withdrawalBlock - depositBlock) , 奖励AP以commint 的形式存在于合约Account Merkle树中。 
    
        此时需要利用deposit和withdraw 树 生成的零知识证明 构建Accout Merkle 树,叶子点节为: hash( amount || secret || nullifier )
    
        此时可以用匿名挖矿密钥加密 Accout 信息, 在链上存储。 加密密钥又由以太坊密钥加密存储在链上,即使丢失也可以恢复。
    
        为了避免用户重复领取奖励,需要生成:rewardNullifer = noteNullifier
    
        对于累加的奖励,需要生成:accountNullifier.   
    
    \- withdraw: 可以取出部分或全部AP,将其转化为TORN代币。
    
        需要根据Account Merkle树生成零知识证明。        
    
        为了避免用户重复withdraw, 需要生成 accountNullifer: 
    
    用户将AP兑换成TORN代币,采用AMM流动模型,TORN代币线性增加流动池中,AP换成TORN代币的公式为:
    

    BalanceAfter = BalanceBefore * e^(-rewardAmount/poolWeight)
    tokens = BalanceBefore - BalanceAfter

    链上备份

    先前用户需要本地备份凭证,并不方便。目前添加可以在链上存储加密凭证的功能。用户需要设置凭证账户(Note Account), 在deposit时,可以选择利用公钥加密凭证保存链上,可以用对应的私钥解密。

    去中心化的Relayer

    任何人可以申请成为Realyer, 帮助用户触发withdraw操作,赚取手续费用。采用零知识证明,保证Relayer 无法对withdraw 接收者,手续费,relayer 进行更改。

    来源证明

    通过提供凭证,可以重新链接发送者和接收者地址,证明资金来源。

    合约部署

    (1) tornado-core

    合约代码:https://github.com/tornadocash/tornado-core.git

    部署步骤:

    1. 部署Verifier.sol

      运行:npm run build:circuit 生成 Verifier.sol 合约;

      运行:./solc --bin --abi --optimize Verifier.sol 编译合约;

      在wallet-cli 利用 deploycontract 部署Verifier.sol 合约

      Verifier.sol 合约地址:

      https://nile.tronscan.org/#/contract/TYfR63UZJy9XqPwUhZKewnnwgPHEZeX5Wp

    2. 运行: node compileHasher.js 生成 Hasher的abi 和 字节码;

      在wallet-cli利用deploycontract 部署 Hasher 合约。

      Hasher 合约地址:https://nile.tronscan.org/#/contract/TZ7GYKy3BwU4fBrK3KQKoXKa8XXHtwMCoi/code

    3. 编译ETHTornado 合约:./solc --bin --abi --optimize --libraries Hasher:0xFDD12CCE9EF36ABC2C4BD1500FE3322FBECCF3D1 ETHTornado.sol

      在wallet-cli 利用 deploycontract 部署ETHTornado合约。

      合约地址为:https://nile.tronscan.org/#/contract/TXb7LSgx3BbwqVSzMr9FhMuA3GvgGi1ACA

    4. 合约调用:https://nile.tronscan.org/#/transaction/f6cbccf0552ba3a6dce8c0a8f3dc343d74fe67714ac078bfb0484d1ee3e930a2

    参考

    https://tornado.cash/

    https://docs.tornado.cash/

    https://github.com/tornadocash

    https://torn.community/t/anonymity-mining-spreadsheet/720

    https://github.com/tornadocash/relayer

    https://torn.community/t/anonymity-mining-technical-overview/15

    https://github.com/tornadocash/tornado-root-updater

    https://tornado-cash.medium.com/tornado-cash-governance-proposal-a55c5c7d0703#2084

    https://github.com/tornadocash/tornado-relayer

    https://tornado.cash/Tornado.cash_whitepaper_v1.4.pdf

    相关文章

      网友评论

          本文标题:Tornado.Cash 匿名协议及挖矿

          本文链接:https://www.haomeiwen.com/subject/amwiydtx.html