Tornado.Cash 匿名协议及挖矿

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容