作者:@Toni Wahrstätter 翻译:DeBox研究院
前 言
Vitalik 建议运用 zk-SNARKs 将买卖逻辑账户与持有财物的账户分隔。这样能够改进隐私,用户体会和一键式交际康复。以太坊研究员 Toni Wahrstätter 对此钱包原型进行具体解析,包括作业流和优势。
因为多种原因,管理多个帐户或许具有挑战性,包括交际康复、隐私、L2 和全体用户体会问题。运用隐形地址会使事情变得更加复杂,因为每次交互都需要一个新帐户。Vitalik建议运用 zk-SNARKs 将买卖逻辑账户与持有财物的账户分隔。这能够改进隐私、用户体会和一键交际康复。
简而言之,咱们试图完成的方针是:
在不危害隐私的状况下一站式交际康复。
一、传统的办法
一个简单但会危害隐私的完成如下所示:
-
用户向财物持有账户供给签名和一些意图/指令。
-
财物持有账户将签名转发给逻辑持有账户。
-
逻辑持有账户从签名中导出公钥,并将其与它存储的公钥进行比较。
-
假如验证经过,逻辑账户将告诉财物持有账户继续操作。
-
财物持有账户执行用户的指令。
缺陷是,这将逻辑账户和财物持有账户揭露联络起来,然后危害了隐私。
二、运用ZK-SNARK
经过运用 zk-SNARK,用户能够证明他们有权开销,而无需透露逻辑持有账户和财物持有账户之间的联络。
作业流程如下所示:
1. 用户在本地构建一棵 Merkle 树并辨认包括其合约的叶子。
1.1. Merkle 树基本上包括按日期或称号排序的每个现有合约的 slot0 和 slot1 值。
1.2. 每个用户都能够依据最近的状况在本地构建 Merkle 树。
2. 用户结构一个 zk 证明,证明知道逻辑持有帐户中的隐秘。稍后再具体证明。
3. 用户将 zk-proof 发送到财物持有账户。
4. 财物持有账户验证证明,确认以下内容:
4.1用户知道逻辑在哪里。
4.2 用户知道一个隐秘值,该隐秘值在散列后映射到存储在逻辑持有账户中的值。
4.3用户能够重建在标准链中保护的帐户状况默克尔树根(例如预编译)
4.4运用正确的随机数(用于切换逻辑持有账户中的密钥)。
本质上,用户能够说:“我具有逻辑持有帐户的可证明的权限来执行此操作,而且我知道该逻辑帐户的方位。”
优点
-
用户体会:一个私钥或一个多重签名设置能够操控多个帐户,即使它们位于不同的 L2 上。
-
康复:经过一次合同更新能够更轻松地康复帐户。
-
隐私:各个帐户之间没有公共链接。
-
兼容性:这有助于遍及帐户笼统(AA)钱包和其他功能。
此外,经过在逻辑和财物持有合约之间添加另一个(聚合器)合约,能够在一次买卖中供给不同财物持有账户的多个证明,然后简直能够像 UTXO 一样对待账户。聚合器将能够获取多个 zk 证明并将其转发到各自的财物持有账户进行验证。当然,这样的聚合器能够在各个财物持有账户之间创立链接——包括隐私。
技术细节
zk-SNARK 设置包括私有元素:
-
用于验证的密钥。
-
逻辑持有账户地址为财物持有账户所指向的地址。
-
Merkle 分支来辨认特定的状况值。
-
答应密钥轮换同时使旧密钥无效的随机数。明文逻辑持有合约地址和隐秘等私有元素不揭露,而是用于私下链接逻辑持有账户和财物持有账户。经过生成整个状况的证明,不需要中心机构来构建默克尔树来提交证明。
1、逻辑持有账户
逻辑持有账户的原型或许如下所示:
pragma solidity >=0.7.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:最初保存哈希值的公共变量。只要所有者知道哈希的原像。
-
nonce:盯梢所有者信息更新次数的计数器。这保证旧密钥变得无效。
-
updateOwner(uint256 newValue):更新值并增加随机数的函数。
该合约盯梢所有者当前的开销逻辑 (slot0) 并答应经过该updateOwner函数进行更新。
2、账户持有账户
pragma solidity >=0.7.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 execute( 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
component main {public [root,logicHoldingAddressHash]} = Main(N);
该电路共有 7 个信号,其间 2 个是揭露的,即 Merkle 树根和逻辑持有账户的哈希地址(在编码到财物持有合约之前必须进行哈希处理,以防止观察者对账户进行聚类)根据相同的逻辑持有者帐户)。
定论
在用户必须管理多个帐户的世界中,对一站式交际康复功能的需求变得越来越重要。Zk-SNARK 可用于完成逻辑/财物分离的钱包,运用户能够运用账户 A 的“逻辑”从账户 B 进行开销,而无需在两者之间创立链接。作为第一步,SNARK 证明能够用于危险低于财物开销的举动。例如,一个好的起点或许是答应用户建议“提款恳求”。假如逻辑持有合约的所有者没有提出异议,用户能够在一段时间后最终确认该恳求。
这样,逻辑持有合约的所有者仍然能够进行干涉,虽然是以损坏隐私的方式,以防出现意外状况。
此时快讯
【Floki多签钱包向Binance存入158亿FLOKI,价值26.14万美元】金色财经报道,据The Data Nerd监测,51分钟前,Floki多签钱包通过钱包0xbd7以0.0000165美元的价格向Binance存入158亿FLOKI(26.14万美元)。此外,这个Binance存款钱包收到的代币主要来自DWF Labs。