http://www.7klian.com

一种以太坊 Layer-2 的通用桥

这个要领很是有效,合约的作者也不再需要耗费大量的 eth 来预加载所有余额,一个默克尔根就足够了,并且挪用者想申领余额的时候,可以本身付出证明 token 所有权的开销。
const balance = balances[args.addr];
· 客户端不需要为它们大概与之交互的每一个系统提供显式支持。
const proof = merkleTree.getProof(addr, balance);
      return;
· 第三方必需可以或许为 L2 平台开拓接口,无需平台维护者的支持和参加。
假设客户端信任了原始合约 —— 我们的意思是,期望该合约会以特定的方法运行,而这可以通过查抄它宣布的源代码来验证 —— 那么这个系统就不会引入任何新的信任假设。固然网关的响应是一个外部流程,但其不良行为的范畴仅限于拒绝处事。
2. 向该网关发送一个 HTTP POST 请求,请求与第一步中沟通的数据。网关返回一个不透明值(opaque value),resolver(理会器) calldata。验证该 理会器 calldata 的起始位就是第一步中获得的 calldata 前缀。
在 10 月 27 号最新的一次事情集会会议上,我演示了这个想法的一个劈头实现。本文中我会具体讲授这种办理方案。
    }
      _mint(addr, preload[addr]);
  mapping(address=>bool) claimed;
这里的网关处事只需要为客户端所发送的 claim 挪用解码函数挪用数据,组装一个证明 —— 可能,在一个实际的 L2 方案中,参考 L2 来组装出一个证明 —— 然后将功效编码放在对 claimWithProof 的挪用中,返回给客户端。
    if(preload[addr] > 0) {
这个简朴的办理方案有一个显而易见的问题:陈设者必需在陈设时将所有余额填充到 preload 映射中,这是一种很是昂贵的操纵。他们会更愿意把数据存储在链下,然后让可以或许证明本身拥有余额的用户来提取本身的数额。用默克尔树很容易就能实现这一点:
实用的要领必需满意下列条件:
· 今朝,客户端无法别离出一个返回无效 calldata(譬喻提供一个无效的证明)的网关和一个无论如何城市回滚的挪用。需要作出一些划定来区分这两种环境 —— 举个例子,假如证明数据的验证不通过的话,要求合约利用一个特定的回滚来由。
  }
ENS 应用
ENS 利用这套系统也会相对直接一些。理会器可以实现本文所述的协议,用于理会任何的数据字段,然后每一个但愿支持 ENS 数据的存储和检索的 L2 都可以陈设新的理会器实现和相应的网关。但愿利用 L2 的用户只需存储本身的记录到符合的 L2 中,并在以太坊上发送一笔一次性的生意业务来指定相关的理会器地点,来利用本身的域名。

在该模子下,得到数据的进程分三步:

    return preload[addr];
  function claimWithProof(address addr, uint balance, bytes proof) external {
contract PreloadedToken is ERC20 {
    }
  function claimableBalance(address addr) external view returns(uint) {
首先,假如我们信任合约,我们同样也会信任它来拟定一个网关 URL 往返应我们的查询请求。其次,我们也可以信任它来实现充实的验证、担保网关的响应是精确的,既可以通过在第一步中指定 calldata 前缀、也可以通过在最后一步中验证网关的响应来担保。
}

1. 向合约发出查询数据的请求。合约并不直接返回所需的功效,而是返回两个值:一个 网关 URL,以及一个 calldata 前缀。
方针
  bytes32 merkleRoot;
    require(verifyProof(keccak256(addr, balance), proof));
对付 ENS 和其它应用来说,要害问题在于,在一个存在很多互不兼容的 Layer-2 方案的世界里,如何能以信任最小化的方法 —— 也就是不引入任何新的信任假设 —— 从某个系统中检索数据,且不需要酿成所有 Layer-2 方案的客户端、本身来存储大概有用的数据 。
· 固然某些应用(好比 ENS )可以从合约指定网关 URL 所缔造的特别间接层中获益,另一些应用,好比上文所示的 token 合约,最好把这些编码为该合约 ABI 的一部门来,使得用户更容易 fork。一个终极的办理方案最好能支持两种选择,且不会强加不须要的承担。
(为了简化,我们省略掉了 verifyProof (验证证明成果)的实现)
  }
我们可以用一个预加载了一组余额的 ERC20 token 合约,以及一个自己是简朴静态默克尔树的 “Layer-2” 来演示这条系统在实践中是如何运作的:
      preload[addr] = 0;
不外,此刻挪用者必需领略生成证明的详细流程,而且知道要到哪儿去获取余额清单来生本钱身账户的证明。假如我们可以把第一个方案的接口(利便),与第二个方案的效率团结起来,那就完美了。这就是我们的方案。
我们提议的方案的焦点是一种尺度化的东西,让客户端可以或许从一个外部系统 —— 一个网关处事 —— 处检索数据;以及一种尺度化的要领,来验证返回的数据是正确的。
    return 0;
· 客户端必需可以或许验证返回的数据是有效的,最好无需引入除相关 L2 方案自带假设以外的信任模子。
return merkleInterface.encodeFunctionData(“claimWithProof”, [args.addr, balance, proof]);
· 它需要一个比 “以太坊 L2 通用桥” 更吸引人的名字。
    _mint(addr, balance);
  }
· 办理方案不会要求接入的 L2 平台发生布局性的改观。
    if(!claimed[addr]) {
    require(verifyProof(keccak256(addr, balance), proof);
重要的是,这三个步调的流程在挪用者处可以完全抽象掉;一个领略这个协议的库就可以让整个流程看起来跟一个通例的 web3 合约挪用一般无二,也就是说,不只应用不需要知道本身在跟哪个 L2 交互,它们甚至完全不知道本身是在跟 L2 交互!
为了让这个方案更通用,ENS 也应该改造,以支持某种形式的通配符理会(wildcard resolution),使得搜索域名失败时会向理会器咨询该域名的父域名 —— 假如 “foo.example.eth” 不存在,那客户端就会在理会器内搜索 “example.eth”。这一成果使得其它系统可以存储 ENS 的整个子树,而不只仅是单个域名的记录。
网关可以完全拒绝响应,也就是拒绝处事,并且这种环境确实大概因为网关恶意可能妨碍而产生。因为这一点,我们提议,任意最终类型,都应该让用户易于 fork 处事,并提供本身的网关;就像此刻用户可以或许 fork dApp 的前端一样。
  }

跟着走向成熟的 Layer-2 办理方案多了起来,ENS 也要能为整个生态系统提供处事,同时让 ENS 用户可以或许得到 Layer-2 办理方案给他们带来的效率晋升。自 Vitalik 的一篇帖子提出了一种大概的要领之后,ENS 团队和宽大的 ENS 和 L2 社区也一直在开拓一种通用的 “Layer-2 桥”,让包罗 ENS 在内的应用,可以或许以免信任的方法在多个链下信源处检索数据,进而使跨平台的互操纵性成为大概。
相应地,这里有两个主要的构成部门:第一个,是一个放在以太坊 Layer-1 上的智能合约,向客户端提供一个发明网关并验证网关响应正确性的东西;第二个,是一个网关处事,领略如何与给定的 L2 系统交互、以及如作甚合约的用途而名目化数据。

3. 查询合约,可能与之互动,提供第二步中获得的 理会器 calldata ,合约验证该数据的有效性,假如有效的话,返回 功效 可能执行生意业务。
安详思量和信任模子
  mapping(address=>uint) preload;
    return (abi.encodeWithSelector(claimableBalanceWithProof.selector, addr), gateway);
    claimed[addr] = true;
    if(claimed[addr]) {
    return (abi.encodeWithSelector(claimWithProof.selector, addr), gateway);
(再一次,为了简捷,我们假设已经有了包罗 getProof 函数在内的符合实现)
  string gateway;
因为认真领略如何与 L2 交互的是网关处事,所以这样一种简朴的协议就可以让客户端从链下得到数据,而且不需要让客户端领略任何与 L2 相关的对象。为了利用这套系统,每一个应用都需要为本身意向交互的 L2 实现并陈设一个网关处事和一个验证合约。在大部门利用,这些网关可以长短常通用的,低落了在差异应用间反复劳动的承担。
  function claim(address addr) external view returns(bytes prefix, string url) {
网关返回错误可能误导性功效的本领受到协议自己的限制。合约所实现的验证逻辑担保了任何无效的功效城市在第三步被发明,同时,合约在第一步中返回的前缀,在第二步中获得验证;这些都安排了网关用对某一次查询有效的谜底往返应另一次查询。
      return balance;
因此,一个实验用不正确的值来响应的网关 —— 无论是提交了不正确的数据,照旧不正确的证明 —— 城市被执行验证步调的合约发明。一个实验正确响应、但利用非用户所发出请求的对应功效来响应的网关,会在用户的 calldata 前缀查抄中发明。客户端可以通过查抄合约的行为来担保这些 —— 可能依赖于某些人对合约的查抄 —— 都可以在开始交互前实现。
claimableBalance 的实现也差不多,只是客户端利用 calldata 来挪用合约,将返回值作为挪用的最终功效。
办理方案概览
未办理的问题
这个界说比大大都人所认为的 “Layer-2” 要越发遍及 —— 它还包罗了其它一些淘汰链上数据存储的东西,好比利用账户余额默克尔树的空投(airdrop),以及会触发事件但并不在链上存储余额的代币。
  }
一个幼稚的要领是,要求所有的系统都利用同样的 witness 数据名目。但这一点是不行能的,,两个原因:第一,witness 数据的名目和范例都高度依赖于相干系统的实现细节,ZK Rollup 和 Optimistic Rollup 利用的元件肯定差异;第二,客户端仍然无法实际得到数据。
我文章所有 demo 的源代码都可以在这里找到。

首先,我们插手了匹配初始 claim 的签名和 claimbleBalance 的要领:
  function claimableBalanceWithProof(address addr, uint balance, bytes proof) external view returns(uint) {
接下来,我们需要实现一个网关处事来,可以满意客户端的查询请求。以 claim1 为例,很直接就能实现:
  function claimableBalance(address addr) external view returns(bytes prefix, string url) {
  function claim(address addr) external {
contract PreloadedToken is ERC20 {
    }
本身试试

const args = tokenInterface.decodeFunctionData(“claim”, data);
事情案例
提要来说,Layer-2 和其它相干系统的事情道理都是淘汰与以太坊交互的需要,它们将原本需要在链上生存和会见的 状态 移到了此外处所,同时,担保在以太坊上有足够多的信息能验证数据的正确性。举个例子,在 Rollup 这种常见的方案中,(Rollup 的)状态会存储在别的一个系统中,只有 witness 数据譬喻默克尔根会存储在以太坊区块链上(译者注:作者此处的举例不足完整,witness 还包罗用户生意业务的原始数据)。有了这些 witness 数据和 Layer-2 办理方案的会见权,一个参加者就可以构建出对任意掩护在 Layer-2 系统中的数据的有效性证明,而且可以由以太坊来验证。
}
这些函数的挪用者可以获得两个值:第一个值是一个后续 callback 的前缀;第二个值是一个网关处事的 URL。该前缀担保了两件事:callback 会用相关的 proof 函数来响应,而且其第一个参数会是所提供的地点。这防备了网关用给另一个地点的数据来响应请求。
最后,客户端验证返回的 calldata 是否以合约所断言的前缀开始,假如是,则利用生意业务发送 calldata 给合约。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

相关文章阅读