📢 Gate广场 #MBG任务挑战# 发帖赢大奖活动火热开启!
想要瓜分1,000枚MBG?现在就来参与,展示你的洞察与实操,成为MBG推广达人!
💰️ 本期将评选出20位优质发帖用户,每人可轻松获得50枚MBG!
如何参与:
1️⃣ 调研MBG项目
对MBG的基本面、社区治理、发展目标、代币经济模型等方面进行研究,分享你对项目的深度研究。
2️⃣ 参与并分享真实体验
参与MBG相关活动(包括CandyDrop、Launchpool或现货交易),并晒出你的参与截图、收益图或实用教程。可以是收益展示、简明易懂的新手攻略、小窍门,也可以是现货行情点位分析,内容详实优先。
3️⃣ 鼓励带新互动
如果你的帖子吸引到他人参与活动,或者有好友评论“已参与/已交易”,将大幅提升你的获奖概率!
MBG热门活动(帖文需附下列活动链接):
Gate第287期Launchpool:MBG — 质押ETH、MBG即可免费瓜分112,500 MBG,每小时领取奖励!参与攻略见公告:https://www.gate.com/announcements/article/46230
Gate CandyDrop第55期:CandyDrop x MBG — 通过首次交易、交易MBG、邀请好友注册交易即可分187,500 MBG!参与攻略见公告:https://www.gate.com/announcements
一站式社交恢复: zk-SNARKs如何实现钱包的交易逻辑与资产分离?
原文作者:@Toni Wahrstätter
发布日期:2023 年 9月 12日
翻译:DeBox研究院
前 言
Vitalik 建议使用 zk-SNARKs 将交易逻辑账户与持有资产的账户分开。这样可以改善隐私,用户体验和一键式社交恢复。以太坊研究员 Toni Wahrstätter 对此钱包原型进行详细解析,涵盖工作流和优势。
由于多种原因,管理多个帐户可能具有挑战性,包括社交恢复、隐私、L2 和整体用户体验问题。使用隐形地址会使事情变得更加复杂,因为每次交互都需要一个新帐户。Vitalik建议使用 zk-SNARKs 将交易逻辑账户与持有资产的账户分开。这可以改善隐私、用户体验和一键社交恢复。
简而言之,我们试图实现的目标是:
在不损害隐私的情况下一站式社交恢复。
一、传统的方法
一个简单但会损害隐私的实现如下所示:
缺点是,这将逻辑账户和资产持有账户公开联系起来,从而损害了隐私。
二、使用ZK-SNARK
通过使用 zk-SNARK,用户可以证明他们有权支出,而无需透露逻辑持有账户和资产持有账户之间的联系。
工作流程如下所示:
1.1. Merkle 树基本上包含按日期或名称排序的每个现有合约的 slot0 和 slot1 值。
1.2. 每个用户都可以根据最近的状态在本地构建 Merkle 树。
用户构造一个 zk 证明,证明知道逻辑持有帐户中的秘密。稍后再详细证明。
用户将 zk-proof 发送到资产持有账户。
资产持有账户验证证明,确认以下内容:
4.1用户知道逻辑在哪里。
4.2 用户知道一个秘密值,该秘密值在散列后映射到存储在逻辑持有账户中的值。
4.3用户可以重建在规范链中维护的帐户状态默克尔树根(例如预编译)
4.4使用正确的随机数(用于切换逻辑持有账户中的密钥)。
本质上,用户可以说:“我拥有逻辑持有帐户的可证明的权限来执行此操作,并且我知道该逻辑帐户的位置。”
优点
此外,通过在逻辑和资产持有合约之间添加另一个(聚合器)合约,可以在一次交易中提供不同资产持有账户的多个证明,从而几乎可以像 UTXO 一样对待账户。聚合器将能够获取多个 zk 证明并将其转发到各自的资产持有账户进行验证。当然,这样的聚合器可以在各个资产持有账户之间创建链接——包括隐私。
技术细节
zk-SNARK 设置包括私有元素:
1、逻辑持有账户
逻辑持有账户的原型可能如下所示:
pragma solidity >=0.7.0 <0.9.0;
contract LogicHoldingAccount is Ownable { uint256 public slot0 = 0x1234; // hashed secret uint256 public nonce = 0; // keep track of key changes address public owner;
function updateOwner(uint256 newValue) public onlyOwner { nonce += 1; slot0 = newValue;
该合约跟踪所有者当前的支出逻辑 (slot0) 并允许通过该updateOwner函数进行更新。
2、账户持有账户
pragma solidity >=0.7.0 <0.9.0;
contract AssetHoldingAccount { uint256 public logicHoldingAccountHash = 1234...;
// Scalar field size, Base field size, Verification Key data, etc. // ...
function verifyProof( uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[2] calldata _pubSignals) public view returns (bool val) { // Snarkjs assembly code for proof verification... // ... }
// _pubSignals[0] - the root of the contract-slot0||nonce Merkle tree // _pubSignals[1] - the hased logic-holder address function ute( address payable to, uint256 amount, uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[2] calldata _pubSignals) public { contractRootPrecompile.getRoot(block.number) uint256 specifiedLogicHolder = _pubSignals[1]; require(specifiedLogicHolder == logicHoldingAccountHash, "Not allowed");
bool validProof = verifyProof(_pA, _pB, _pC, _pubSignals) == true; if (validProof) { (bool success,) = to.call{value:amount}(""); require(success); } }
receive() external payable {
资产持有账户存储ETH等资产,并允许用户提交提款证明。通过验证是否specifiedLogicHolder匹配logicHoldingAccountHash,所有者可以确保资产持有合约仅接受来自授权逻辑持有合约的证明,而不是任何任意合约。
在构造证明时作为私人信号提供的秘密确保只有包含支出逻辑的帐户的所有者才能从资产持有帐户访问资金。
3、电路
以下电路是使用circom开发的,完整的代码可以在这里找到。
pragma circom 2.0.2;
include "./modules/merkleTree.circom";include "./modules/commitmentHasher.circom";
template Main(levels) { signal input root; signal input logicHoldingAddressHash; signal input logicHoldingAddress; signal input secret; signal input nonce; signal input pathElements[levels]; signal input pathIndices[levels]; component secretHasher = SecretHasher(); secretHasher.secret <== secret; component hasher = CommitmentHasher(); hasher.logicHoldingAddress <== logicHoldingAddress; hasher.secret <== secretHasher.hashedSecret; hasher.nonce <== nonce; hasher.logicHoldingAddressHash === logicHoldingAddressHash; component tree = MerkleTreeChecker(levels); tree.leaf <== hasher.commitment; tree.root <== root; for ( i = 0; i < levels; i++) { tree.pathElements[i] <== pathElements[i]; tree.pathIndices[i] <== pathIndices[i];
component main {public [root,logicHoldingAddressHash]} = Main(N);
该电路共有 7 个信号,其中 2 个是公开的,即 Merkle 树根和逻辑持有账户的哈希地址(在编码到资产持有合约之前必须进行哈希处理,以防止观察者对账户进行聚类)基于相同的逻辑持有者帐户)。
结论
在用户必须管理多个帐户的世界中,对一站式社交恢复功能的需求变得越来越重要。Zk-SNARK 可用于实现逻辑/资产分离的钱包,使用户能够使用账户 A 的“逻辑”从账户 B 进行支出,而无需在两者之间创建链接。作为第一步,SNARK 证明可以用于风险低于资产支出的行动。例如,一个好的起点可能是允许用户发起“提款请求”。如果逻辑持有合约的所有者没有提出异议,用户可以在一段时间后最终确定该请求。
这样,逻辑持有合约的所有者仍然可以进行干预,尽管是以破坏隐私的方式,以防出现意外情况。