OBOL 项目分享活动开启!调研 Obol (OBOL) 项目,在Gate.io动态发布您的看法观点,瓜分 $100 OBOL!
💰️ 选取10名优质发帖用户,每人轻松赢取 $10 OBOL 奖励!
项目简介:
Obol 致力于分布式、去中心化和民主化未来的数字基础设施——从以太坊开始,并扩展到整个 Web3 平台。作为 Layer 1 区块链和去中心化基础设施网络的基础,Obol Collective 拥有全球最大的去中心化运营商生态系统。目前,全球超过 800 个去中心化运营商运行 Obol 分布式验证器 (DV),保障主网超过 10 亿的资产安全,Obol 正在赋能下一代去中心化系统。
参与方式:
1.调研$OBOL项目,发表你对项目的见解。具体可包含但不限于:
🔹 Obol 是什么?
🔹 Obol 去中心化验证器有何优点?
🔹 $OBOL 代币经济模型如何运作?
2.带上$OBOL现货交易链接:https://www.gate.io/trade/OBOL_USDT
3.推广$OBOL Launchpool 质押挖矿活动,分享OBOL Launchpool 参与步骤及质押福利,质押$GT、$BTC、$OBOL 免费瓜分2,250,000 $OBOL空投奖励,年华收益率高达168%:https://www.gate.io/launchpool/OBOL?pid=291
详解 Tornado Cash V2 设计原理
> 开发者 ameen.eth 将「Proof-of-Innocence」概念和 Tornado Cash 结合,提供另一个「隐私不等同于犯罪」的方向。
撰文:林玮宸 Albert Lin
前言
TornadoCash 是加密货币世界中著名的匿名交易服务。TornadoCash 利用 ZKP(Zero-Knowledge Proof)技术来隐藏资金来源。美国政府主张这样的机制助长了非法金流活动,最终在 2022 年 8 月被美国财政部制裁而被迫下架。隐私保护和洗钱活动在很多情况下似乎总是紧密相连。在追求隐私的同时,不法分子往往利用这些隐私特性进行非法资金清洗。是否能找到一种方法,既能让人们拥有隐私,又能有效遏制洗钱活动? TornadoCash 早期开发者 ameen.eth 的 Privacy-Pools 或许给出了一个方向。(关于下架的部分只有前端网站和 GitHub Repository 受到影响,合约部份因在区块链上则不受影响。最后在电子前哨基金会的争取之下 GitHub 有恢复 Repository,详情可以参考这)
简介 TornadoCash 原理
在介绍 Privacy-Pools 之前,需要先理解 TornadoCash 相关的设计原理。详细介绍可以参考我之前的文章「Breaking Down TornadoCash: A Beginner’s Guide to Explaining its Functionality to Friends」。这边简单複习一下 TornadoCash 的设计原理。
TornadoCash 使用收据( commitment)来控制访问权限。收据是由 secret(秘密值)和 nullifier (注销码)一起 Hash 产生,每个收据只能提款一次。使用 Merkle Tree (杂凑树)记录存款信息,将收据作为 leaf 节点并计算出 Merkle Root (杂凑树根)。使用者只需提供 leaf 到 root 中间经过的数据,即可证明该数据是否 Merkle Tree 的 leaves 之一,也间接证明之前有存款资金到 TornadoCash。使用 Zero-Knowledge Proof 来隐藏存款来源,另外使用 nullifier 防止 Double Withdrawal 攻击。
TornadoCash 的收据有两个含义
「Proof-of-Innocence」
根据 TornadoCash 设计的原理,只能知道领款的资金一定是来自之前的某笔存款的资金,但却不知道是来自哪一笔存款。这是不法份子使用 TornadoCash 进行不法的洗钱活动的主要目的,也是美国政府为什麽要监管 TornadoCash 原因。若我们可以提出另外的 Proof(ZKP),来证明领款时的资金不是来自拒绝清单的存款,是否就能证明这笔领款并非来自于不法份子,这就是「Proof-of-Innocence」(「无罪证明」)核心概念。
「Proof-of-Innocence」概念可以分成两个方向
这两种做法都是可以证明领款资金都不是来自于拒绝清单裡的存款。下图的做法是採用拒绝清单的方式,证明领款的资金并非来自于拒绝清单的存款(红色)。
Privacy-Pools 设计原理
Privacy-Pools 在 TornadoCash 基础上多加上了「Proof-of-Innocence」的概念。Privacy-Pools 领款收据除了 TorandoCash 收据原本代表的意义之外,还有第三个意思:「证明领款的资金来自于允许清单中的存款」。
Privacy-Pools 收据代表意义:
这边我们使用 Allow Merkle Tree 来解释 Privacy-Pools 是如何把「Proof-of-Innocence」运用在这个系统中(Allow Merkle Tree 是运用允许清单的概念)。首先 Allow Merkle Tree 有几个特点
Allow Merkle Tree leaf 资料可以分成下面二类:
下图可以看到 index 0 和 1 的位置在 Deposit Merkle Tree 皆为 legal funds,对应的 Allow Merkle Tree leaf 位置也是 allowed。
假设今天有一名不法份子想要进行洗钱活动,他把攻击后所得不法资金存进 Privacy-Pools ,存款位置是 Deposit Merkle Tree index:2 的位置。我们知道那是不法的资金,所以在对应的 Allow Merkle Tree index:2 位置我们更新为 blocked。
允许清单领款情形
假设今天有一名在美国政府允许清单存款的用户想要提领资金,需要提供「有存款在 Dposit Merkle Tree 中的证明」之外,还需要提供「在美国允许清单的 是 Allowed 的证明」。对应美国允许清单的证明包含了 Allow Merkle Root (由用户自行提供,在程式码中为 subetRoot)和中途会经过的 node 值。Privacy-Pools 在验证 ZKP 阶段时,会以 leaf 值为 allowed (实际程式码中是 keccak256(allowed))和给定中途会经过的 node 值去建构出 Merkle Root。验证此 Merkle Root 与用户提供的 Allow Merkle Root 是否相同。若相同代表验证通过,表示该领款的资金是来存在于美国政府允许清单中的存款。
拒绝清单领款情形
今天有一名不在美国政府允许清单存款的用户想要提领资金 ,而对应的存款的位置在美国政府允许清单中被标记成 blocked。这样会导致用户无法使用美国政府允许清单的 Allow Merkle Root 去领出资金,因为产生不出对应的证明而导致验证失败(因为 Privacy-Pools 使用 leaf 是值 allowed 去做计算,而美国政府允许清单将该位置标记成 blocked,导致计算不出相同的 Merkle Root )。
这样的设计被迫这名用户需要提供其他的 Allow Merkle Root 才能提领资金(其他的 Allow Merkle Tree 需将该存款位置标记成 allowed,才能计算出相同的 Allow Merkle Root 来通过验证)。这个其他的 Allow Merkle Tree 可能来自于其他政府或机构所维护,甚至是这名用户自行产生。今天美国政府就可以藉由提领时所用的 Allow Merkle Root, 来判断用户的资金是否符合美国政府的法律规范,藉此来达到追踪的目的。若用户是使用自己产生或不具公信力的的 Allow Merkle Tree ,基本上该笔领款资金极有可能来自有问题的存款(每个具公信力的第三方 Allow Merkle Tree 都将该存款位置标记成 blocked)。
常见的问题
Q: 如果 Allowroot 是由提领人提供,是不是可以假造一个假 Allow Merkle Root 来证明该 leaf 是允许清单中的存款,是不是代表还是可以把钱领走呢?
A: 答案是肯定的,确实是可以把钱领走。这一点作者有特别提出说,这样的机制并不是要禁止不法份子把钱领走,而是就算可以领走也会被知道说这笔资金是拒绝清单的资金。当提领人提供了一个没有说服力的 Allow Merkle Root,基本上可以视为他是从拒绝清单存款提领。笔者这边猜测允许这样做的原因是想要保持这个服务的去中心化性质。因为每个 Allow Merkle Tree 都需要有一定的权限管理去更新每个 leaf 的 status。 若强制指定某个 allow tree root 的话,代表有人有一定权限控制资金的提领,这一点并不符合去中心化的精神。
Q: 会是由谁来决定这笔交易是来自于拒绝清单资金呢?
A: 笔者看到的部分并没有特别提,理解是这部分应该由各监管单位自己去做。假设今天美国政府要查 Privacy-Pools 的髒钱,他可以透过去检查每笔的 Allow Merkle Root 来判断他是不是髒钱。至于怎样的 Allow Merkle Root 是允许,那就是各监管单位他们自己去判断。
Privacy-Pools 程式码
这裡附上主要的程式码和笔者自己的注解,希望可以帮助大家可以透过程式码理解主要逻辑。
// circuits/withdraw_from_subset.circom
template WithdrawFromSubset(levels, expectedValue) {
// public
signal input root;
signal input subsetRoot;
signal input nullifier;
signal input assetMetadata; // abi.encode(token, amount).snarkHash();
signal input withdrawMetadata; // abi.encode(recipient, refund, relayer, fee).snarkHash();
// private
signal input secret;
signal input path; // Indicate whether the data represents the left leaf or the right leaf.
signal input mainProof[levels]; // Construct the data required for deposit root.
signal input subsetProof[levels]; // Construct the data required for allow root.
// Calculate the nullifier and commitment.
component hasher = CommitmentNullifierHasher();
hasher.secret <== secret;
hasher.path <== path;
hasher.assetMetadata <== assetMetadata;
nullifier === hasher.nullifier;
// expectedValue: keccak256("allowed") % p
component doubleTree = DoubleMerkleProof(levels, expectedValue);
doubleTree.leaf <== hasher.commitment;
// Convert the path to bits to specify whether it is the left leaf or the right leaf.
// It can be observed that the deposit tree and allow tree share the same path.
doubleTree.path <== path;
for ( i = 0; i < levels; i++) {
doubleTree.mainProof[i] <== mainProof[i];
doubleTree.subsetProof[i] <== subsetProof[i];
}
root === doubleTree.root; // Verify the deposit root.
subsetRoot === doubleTree.subsetRoot; // Verify the allow root.
signal withdrawMetadataSquare;
withdrawMetadataSquare <== withdrawMetadata * withdrawMetadata;
}
TLDR
开发者 ameen.eth 将「Proof-of-Innocence」概念和 TornadoCash 结合,提供另一个「隐私不等同于犯罪」的方向。笔者觉得有趣的角度是利用另一个 ZKP 来证明另一件事实,有点像是 ZKP 的加法。这样的使用方式会比建构一个更大行更複杂的 ZKP 更来为简单,效率也更高。关于 Allow Merkle Tree 的选择,感觉之后会是由一个比较公正的单位来建构,这样对于其他人也有比较高的说服性。
最后感谢 Chih-Cheng Liang 以及 Ping Chen 帮忙 Review 文章和给出宝贵的意见!
> Reference:
> Stealth Address
> Tornado Cash實例解析
> ZKP 與智能合約的開發入門
> [ZKP 讀書會] TornadoCash
> Tornado Cash — How it Works | DeFi + Zero Knowledge Proof
> 深入理解 TornadoCash 技术细节
> 0xhhh Thread 介紹新功能和其原理
> demo video
> Vitalik’s 講如何改進 Tornadov2
> privacy pools v0tweet
> Introducing Proof of Innocence built on TornadoCash