首页>>资讯>>学院

前Arbitrum技术大使解读Arbitrum的组件结构

2024-01-09 10:48:36 184

本文是Arbitrum前技术大使 及 智能合约自动化审计公司Goplus Security前联合创始人罗奔奔 对Arbitrum One的技术解读。


Rollup排序器简述


Rollup扩容的原理可以概括为两点:


成本优化:将⼤部分运算与存储任务移交至L1链下也即L2上。L2大多是运⾏在单台服务器也即排序器(Sequencer/Operator)上的⼀条链。


排序器在观感上接近于一台中心化服务器,在“区块链不可能三⻆”中舍弃“去中心化”来换取TPS与成本上的优势。 ⽤户可以让L2来代替以太坊处理交易指令,成本比在以太坊上交易要低得多。

3-cn.png

安全保障:L2上的交易内容与交易后的状态,会同步⾄以太坊L1,通过合约来校验 状态转换的有效性。同时,以太坊上会保留L2的历史记录,排序器即便永久宕机,他⼈也可以通过以太坊上的记录,还原出整个L2的状态。


从根本上来说,Rollup的安全性是基于以太坊的。排序器如果不知道某个账户的私钥,就无法用该账户的名义发起交易,或者无法篡改该账户的资产余额(即便这么做了,也很快被识破)。


虽然排序器作为系统中枢带有中⼼化色彩,但在成熟度比较高的Rollup方案中,中心化排序器仅能实施交易审查等软性作恶⾏为,或者恶意宕机,但在理想状态的Rollup⽅案中,有相应的⼿段进⾏遏制(比如强制提款或排序证明等抗审查机制)。

1.jpg

(路印协议在L1上的合约源码中设置的,供用户调用的强制提款函数)


而防止Rollup排序器作恶的状态校验⽅式,分为欺诈证明(Fraud Proof)和有效性证明(Validity Proof)两类。使⽤欺诈证明的Rollup⽅案称为OP Rollup(Optimistic Rollup,OPR),⽽因为一些历史包袱,使⽤有效性证明的Rollup往往被称为ZK Rollup(Zero-knowledge Proof Rollup,ZKR),而不是Validity Rollup。


Arbitrum One是典型的OPR,它部署在L1上的合约,并不主动验证提交过来的数据,乐观地认为这些数据没有问题。如果提交的数据有错误,L2的验证者节点会主动发起挑战。


因此OPR也暗含一条信任假设:任意时刻⾄少有⼀个诚实的L2验证者节点。⽽ZKR的合约则通过密码学计算,主动但低成本地验证排序器提交的数据。 

3-cn.png

(乐观Rollup运转方式)

1.jpg

(ZK Rollup运转方式)


本文会深度介绍乐观式Rollup中的龙头项目——Arbitrum One,覆盖整个系统的方方面面,仔细阅读完后你将对Arbitrum和乐观式Rollup/OPR有深刻的理解。


Arbitrum的核心组件与工作流程


核心合约:


Arbitrum最重要的合约包括SequencerInbox, DelayedInbox, L1 Gateways, L2 Gateways, Outbox, RollupCore, Bridge等。后续将详细介绍。


排序器Sequencer:


接收用户交易并进行排序,计算交易结果,并迅速(通常<1s)返还给用户回执。用户往往在几秒内就能看到自己的交易在L2上链,体验就如同Web2平台。


同时,排序器还会在以太坊链下即时广播最新产生的L2 Block,任何一个Layer2节点都可以异步的接收。但此时,这些L2 Block不具备最终确定性,可以被排序器回滚掉。


每隔几分钟,排序器会将排序后的L2交易数据进行压缩,聚合成批次(Batch),提交至Layer1上的收件箱合约SequencerInbox,以保证数据可用性和Rollup协议的运转。一般而言,被提交至Layer1上的L2数据无法回滚,可以具备最终确定性。

3-cn.png

从以上流程中我们可以概括:Layer2有自己的节点网络,但这些节点数量稀少,且一般没有公链惯用的共识协议,所以安全性是很差的,必须要依附于以太坊来保证,数据发布的可靠性与状态转换的有效性。


Arbitrum Rollup协议:


定义Rollup链的区块 RBlock 的结构,链的延续方式,RBlock的发布,以及挑战模式流程等⼀系列的合约。注意,这⾥说的Rollup链并不是大家理解的Layer2账本,而是Arbitrum One为了施展欺诈证明机制,而独立设置的一条抽象出来的“链状数据结构”。


⼀个RBlock可以包含多个L2区块的结果,⽽且数据也迥异,它的数据实体 RBlock 存储在RollupCore的⼀系列合约中。如果⼀个 RBlock 存在问题,Validator将⾯向该RBlock的提交者对其进⾏挑战。


验证者Validator:


Arbitrum的验证者节点其实是Layer2全节点的特殊子集,目前有白名单准入。

3-cn.png

Validator根据排序器提交至SequencerInbox合约的交易批次batch,来创建新的RBlock(Rollup区块,也叫断⾔assertion),并监控当前Rollup链的状态,对排序器提交的错误数据进⾏挑战。


主动型的Validator需要事先在ETH链上质押资产,有时我们也称其为Staker。不进⾏质押的Layer2节点虽然也可以监控Rollup的运⾏动态,向⽤户发送异常报警等,但⽆法在ETH链上直接对排序器提交的错误数据进行⼲预。

3-cn.png

挑战:


基础步骤可以概括为多轮互动式细分、单步证明。在细分环节,挑战双⽅先对有问题的交易数据进⾏多轮回合制细分,直⾄分解出有问题的那⼀步操作码指令,并进⾏验证。“多轮细分-单步证明” 这种范式,被Arbitrum开发者认为是欺诈证明中最节省gas的实现⽅式。所有环节都在合约控制之下,没有⼀⽅可以作弊。


挑战期:


由于OP Rollup的乐观optimistic本质,每个RBlock提交上链后,合约并不主动检查,预留给验证者一段时间窗⼝期去证伪。此时间窗⼝即为挑战期,在Arbitrum One主⽹上为1周。挑战期结束后,该RBlock才会被最终确认,块内对应的从L2传递到L1的消息(比如通过官方桥执行的提款操作)才能被放行。


ArbOS, Geth, WAVM:


Arbitrum采用的虚拟机名为AVM,包含Geth和ArbOS两部分。Geth是以太坊最常⽤的客户端软件,Arbitrum对其进⾏了轻量化的修改。ArbOS负责所有L2相关的特殊功能,如⽹络资源管理、⽣成L2区块、与EVM协同⼯作等。我们将两者的组合视为⼀个Native AVM,也就是Arbitrum采用的虚拟机。WAVM是把AVM的代码编译为Wasm后的结果。Arbitrum挑战流程中,最后的那个“单步证明”,验证的就是WAVM指令。


在此,我们可以将上述各个组件之间的关系和⼯作流⽤下图来表示:

3-cn.png

L2交易生命周期


一笔L2交易的处理流程如下:


1.用户向排序器发送交易指令。


2.排序器先对待处理交易进数字签名等数据的验证,剔除无效交易,并进行排序和运算。


3.排序器将交易回执发送给⽤户(通常都⾮常快),但这只是排序器在ETH链下进行的“预处理”,处于Soft Finality的状态,并不可靠。但对于信任排序器的⽤户(⼤部分⽤户),可以乐观的认为交易已经完成,不会被回滚。


4.排序器将预处理后的交易原始数据,⾼度压缩后封装为⼀个Batch(批次)。


5.每隔⼀段时间(受到数据量、ETH拥堵程度等因素影响),排序器会向L1上的 Sequencer Inbox 合约发布交易Batch。此时可认为,交易已拥有最终性Hard Finality。

3-cn.png

Sequencer Inbox合约


合约会接收排序器提交的交易batch,保证数据可⽤性。深⼊地看,SequencerInbox中的batch数据完整记录了Layer2的交易输入信息,即使排序器永久宕机,任何⼈都可以根据batch的记录还原Layer2的当前状态,接替故障/跑路的排序器。


⽤物理的⽅式理解,我们所看到的L2,只是 SequencerInbox 中batch的投影,光源则是STF。因为光源STF不会轻易变化,所以影⼦的形状只由充当物体的batch来决定。 


Sequencer Inbox合约⼜称为快箱,排序器专门向其提交已经被预处理的交易,且只有排序器可向其提交数据。对应快箱的是慢箱Delayer Inbox,其功能在后续流程中会有描述。


Validator会一直监听SequencerInbox合约,每当排序器向该合约发布Batch后,就会抛出一个链上事件,Validator监听到这个事件发生后,就会去下载batch数据,在本地执⾏后,向ETH链上的Rollup协议合约发布RBlock 。 

3-cn.png

Arbitrum的bridge合约内有个叫累加器accumulator的参数,会针对新提交的L2 batch,以及慢Inbox上新接收的交易数和信息,进行记录。

3-cn.png

(排序器向SequencerInbox不断提交batch)

3-cn.png

(Batch的具体信息,data字段对应着Batch数据,这部分数据尺寸很大,截图没显示完)


SequencerInbox合约有两个主要函数:


add Sequencer L2Batch From Origin(),排序器每次都会调用该函数向Sequencer Inox合约提交Batch数据。


force Inclusion(),该函数任何人都可以调用,用于实现抗审查交易。这个函数的生效方式,会在后面谈到Delayed Inbox合约时详细解释。


上述两个函数都会调用 bridge.enqueueSequencerMessage(),来更新bridge合约内的累加器参数accumulator。


Gas定价


显然,L2的交易不可能免费,因为这样会引来DoS攻击,另外则是排序器L2本身的运⾏成本,以及在L1上提交数据都会有开销。⽤户在Layer2网络内发起交易时,gas费的结构如下: 


占用Layer1资源产生的数据发布成本,主要来自于排序器提交的batch(每个batch有很多用户的交易),成本最终由交易发起者们均摊。数据发布产生的手续费定价算法是动态的,排序器会根据近期的盈亏状况、batch⼤⼩、当前以太坊gas价格进⾏定价。


用户因占用Layer2资源产生的成本,设定了⼀个可以保证系统稳定运⾏的,每秒处理的gas上限(⽬前Arbitrum One是700万)。L1和L2的gas指导价格均由ArbOS跟踪并调整,公式暂时不在此赘述。

3-cn.png

虽然具体的gas价格计算过程⽐较复杂,但⽤户无需感知到这些细节,可以明显感到 Rollup交易费⽤比ETH主网便宜的多。 


乐观式欺诈证明


回顾上文,L2实际上只是排序器在快箱中提交的交易输入batch的投影,也即:


Transaction Inputs -> STF -> State Outputs。输入已经确定,STF是不变的,则输出结果也是确定的,而欺诈证明和Arbitrum Rollup协议这套系统就是把输出的状态根,以RBlock (aka断言)的形式发布到L1上并对其进行乐观式证明的一套系统。


在L1上有排序器发布的输⼊数据,也有验证者发布的输出状态。我们再仔细考量⼀下,是否有必要向链上发布Layer2的状态呢?


因为输⼊已经完全决定了输出,而输入数据是公开可见的,再提交输出结果-状态似乎是多余的?但这种想法忽略了L1-L2两个系统之间实际上需要状态结算,也即L2向L1⽅向的提现⾏为,需要有对状态的证明。 


在搭建Rollup的时候,⼀条最核⼼的思想就是把⼤部分运算和存储放到L2上来规避L1⾼昂的费⽤,这也就意味着,L1并不知道L2的状态,它仅仅帮助L2排序器发布全体交易的输入数据,但并不负责计算出L2的状态。


⽽提现⾏为,本质上是依照L2给出的跨链消息,从L1的合约⾥解锁相应资⾦,划转到⽤户的L1账户中或完成其他事情。


此时Layer1的合约就会问:你在Layer2上的状态是怎样的,怎么证明你真的拥有这些声明要跨走的资产。这个时候用户要给出对应该的Merkle Proof等。

1.jpg

所以,如果我们构建⼀条没有提现功能的Rollup,理论上不向L1进⾏状态同步是可以的,也不需要欺诈证明等状态证明系统(虽然可能带来其他问题)。但在现实应⽤中,这显然是不可⾏的。 


所谓的乐观式证明中,合约不会去检查提交到L1的输出状态是否正确,乐观地认为一切都是准确无误的。乐观证明系统会假设,在任意时刻都有⾄少⼀名诚实的Validator,如果出现错误的状态,则通过欺诈证明进⾏挑战。


这么设计的好处是,不需要主动验证每⼀个发布到L1上的RBlock,避免浪费gas。实际上对于OPR⽽⾔,对每⼀个断⾔进⾏验证也是不现实的,因为每个 Rblock都包含着一或多个L2区块,要在L1上去对每笔交易重新执⾏⼀遍,与直接在L1上执行L2交易无异,这就失去了Layer2扩容的意义。


⽽ZKR不存在这个问题,因为ZK Proof有简洁性,只需要验证⼀个很⼩的Proof,不需要真地去执⾏该Proof背后所对应的许多条交易。所以ZKR并不是乐观式运⾏,每次发布状态都会有Verfier合约进⾏数学验证。


欺诈证明虽然不能像零知识证明那样具有⾼度的简洁性,但Arbitrum使⽤了⼀种“多轮分割-单步证明”的轮流式交互流程,最终需要证明的仅仅是单⼀的虚拟机操作码,成本相对较⼩。


Rollup协议


我们先来看一下,发起挑战和启动证明的入口,也即Rollup协议是如何工作的。


Rollup协议的核心合约是RollupProxy.sol,在保证数据结构一致的情况下,使用了一个罕见的双重代理结构,一个代理对应两个实现RollupUserLogic.sol和RollupAdminLogic.sol,在Scan等工具中目前还无法很好的解析。


另外还有ChallengeManager.sol合约负责管理挑战,OneStepProver系列合约来判定欺诈证明。

3-cn.png

(图源:L2BEAT官网)


在RollupProxy中,记录由不同Validator提交的一系列RBlock(aka断言),也即下图中的方块:绿色-已确认,蓝色-未确认,黄色-已证伪。

3-cn.png

RBlock中包含了自上一个RBlock以来,一个或多个L2区块执行后的最终状态。这些RBlock在形态上构成了一条形式上的Rollup Chain(注意L2账本本身相区别)。在乐观情况下,这条Rollup Chain应该是没有分叉的,因为有分叉意味着有Validator提交了彼此冲突的Rollup Block。


要提出或认同断言,需要验证者先为该断言质押一定数量的ETH,成为Staker。这样在发生挑战/欺诈证明时,输者的质押品将被罚没,这是保障验证者诚实行为的经济学基础。


图中右下角的111号蓝色块最终会被证伪,因为其父块104号区块是错误的(黄色)。


此外,验证者A提出了106号Rollup Block,而B不同意,对其进行挑战。

3-cn.png

在B发起挑战后,ChallengeManager合约负责验证对挑战步骤的细分过程:


1.细分是一个双方轮流互动的过程,一方对某个Rollup Block中包含的历史数据进行分段,另一方指出是哪部分数据片段有问题。类似于二分法(实际是N/K)不断渐进缩小范围的一个过程。


2.之后,可以继续定位至哪条交易及结果有问题,再进一步细分至该交易中有争议的某条机器指令。


3.ChallengeManager合约只检查对原始数据进行细分后,产生的『数据片段』是否有效。


4.当挑战者和被挑战者定位到了将被挑战的那条机器指令后,挑战者调用oneStepProveExecution(),发送单步欺诈证明,证明这条机器指令的执行结果有问题。

1.jpg

单步证明


单步证明是整个Arbitrum的欺诈证明的核心。我们看一下单步证明具体证明的是什么内容。


这需要先理解WAVM,Wasm Arbitrum Virtual Machine,它是一个由ArbOS模块和Geth(以太坊客户端)核心模块共同编译成的虚拟机。由于L2与L1有许多截然不同的地方,原始的Geth核心必须经过轻量修改,并且配合ArbOS一起工作。


所以,L2上的状态转换其实是ArbOS+Geth Core的共同手笔。

1.jpg

Arbitrum的节点客户端(排序器、验证者、全节点等),是将上述ArbOS+Geth Core处理的程序,编译为节点主机能直接处理的原生机器代码(for x86/ARM/PC/Mac/etc.)。


如果把编译后得到的目标语言更改为Wasm,就得到了验证者生成欺诈证明时使用的WAVM,而验证单步证明的合约上,模拟的也是WAVM虚拟机的功能。


那为什么在生成欺诈证明时,要编译为Wasm字节码?主要还是因为,验证单步欺诈证明的合约,要用以太坊智能合约模拟出 能处理某套指令集的虚拟机VM,而WASM易于在合约上实现模拟。

3-cn.png

但WASM相比于Native机器代码,运行速度略慢,所以只有在欺诈证明生成及验证的时候,Arbitrum的节点/合约才会用到WAVM。


在之前的多轮互动细分后,单步证明最终证明的是WAVM指令集中的单步指令。


下面的代码中可以看到,OneStepProofEntry首先要判定,待证明指令的操作码属于哪个类别,再调用相应的prover如Mem,Math等,将单步指令传入该prover合约。

3-cn.png

最终结果afterHash会回到ChallengeManager,如果该哈希与Rollup Block上记录的,指令运算后的哈希不一致,则挑战成功。如果一致,则说明Rollup Block上记录的这个指令运行结果没问题,挑战失败。

3-cn.png

跨链与桥接的原理


跨链交易可分为L1到L2(充值)与L2到L1(提现)。注意这⾥所说的充值和提现未必与资产跨链相关,可以是不直接附带资产的消息传递。所以这两个词仅仅表示跨链相关行为的两个⽅向。


跨链交易与纯L2交易相⽐,跨链交易在L1和L2这两个不同的系统中进⾏了信息互换,因此过程更复杂。


另外,通常我们说的跨链⾏为,是在两个毫不相关的⽹络上,⽤⻅证⼈模式的跨链桥进⾏的跨链,这种跨链的安全性取决于跨链桥的运营者,历史上基于见证人模式的跨链桥被盗事件频繁发生。


⽽在Rollup与ETH主⽹之间的跨链⾏为,与上述跨链有本质不同,因为Layer2的状态是由记录在Layer1上的数据决定的,只要你使⽤的是Rollup官⽅的跨链桥,其在运作结构上是绝对安全的。


这也凸显出Rollup的本质,它只是在⽤户角度看,像⼀条独立的链,但实际上所谓的“Layer2”只是Rollup对⽤户敞开的快速展示窗⼝,它的真实链式结构还是刻录在Layer1上。所以,我们可以认为L2算半条链,或者说是“在Layer1上创造出的一条链”。


可重试票据 Retryables


需要注意,跨链都是异步和非原子性的,它不可能像在一条链上一样做完一笔交易确认后就知道结果,也不能保证另一侧一定会在某个时间点发生某些事。因此跨链有可能因为一些软性问题而失败,但只要使用正确的手段,诸如可重试票据(Retryable Ticket),就不会发生资金卡住等硬性问题。


可重试票据是通过Arbitrum官方桥充值时,用到的基本工具,ETH和ERC20的充值都会使⽤到。其⽣命周期分为三步: 


1. 在L1上提交票据。在Delayed Inbox合约中使用createRetryableTicket()方法创建充值票据,并提交。


2. L2上自动兑付。大部分情况下,排序器可以自动帮用户兑付票据,无需后续的手动操作。


3. L2上手动兑付。部分边缘情况,如L2上gas价格突然激增,票据上预付的gas不够,则无法自动兑付。此时需要用户手动操作。


注意,如果自动兑付失败,需要在7日内手动兑付票据,否则要么票据将会被删除(资金会永久损失),要么需要为票据的保存支付一定费用来续租。


另外,对于Arbitrum官方桥的提现流程,虽然和充值行为在流程上有一定对称相似性,但并没有Retryables这个概念,一方面可以从Rollup协议本身理解,另一方面我们可以从一些区别进行理解:


提现的过程中不存在自动兑付,因为EVM没有定时器或自动化,而L2上可以实现自动兑付,是排序器帮忙实现的,所以L1上用户要手动与Outbox合约交互,以Claim取回资产。


提现也不存在票据过期的问题,只要过了挑战期,可以在任意时间领取。


ERC-20资产跨链 Gateway


ERC-20资产的跨链是复杂的。我们可以思考几个问题:


一个在L1上部署的代币,它在L2上要如何部署?

它的L2对应合约需要预先手动部署,还是系统可以自动为跨过来的、但尚未部署合约的代币 自动部署资产合约?

L1上的ERC-20资产,在L2对应的合约地址是什么?是否该和L1一致?

在L2上原生发行的代币,如何跨链至L1?

拥有特殊功能的代币,如可调整数量的Rebase型代币,自增长生息代币,如何跨链?


我们不打算全部回答这些问题,因为展开太过复杂。这些问题仅是用来说明ERC20跨链的复杂性。

3-cn.png

目前非常多扩容方案使用的都是白名单+手动清单的方案,来规避各种复杂的问题和边界情况。


Arbitrum使用了Gateway系统,解决了大部分ERC20跨链的痛点,具有以下特性:


Gateway组件在L1和L2成对出现。


Gateway Router负责维护Token L1<->Token L2之间的地址映射,以及some token<->some gateway之间的映射。


Gateway本身可分为StandardERC20 gateway,Generic-custom gateway,Custom gateway等等,用以解决不同类型的和功能ERC20的桥接问题。


我们以比较简单的WETH跨链为例,来说明自定义gateway的必要性。


WETH是一种ETH的ERC20等价物。Ether作为主币,很多dApp中的复杂功能是无法实现的,因此需要一个ERC20的等价物。向WETH合约内转入一些ETH,它们会被锁在合约内,并生成出相同数量的WETH。


同理,也可以销毁WETH,取出ETH。显然,流通的WETH和锁仓的ETH数量永远是1:1的。

3-cn.png

如果现在把WETH直接跨链到L2上,我们会发现一些奇怪的问题:


无法在L2上把WETH进行Unwrap变成ETH,因为L2上并没有锁仓对应的ETH。


Wrap功能可以使用,但这些新生成的WETH如果跨回到L1,也无法在L1上解封装为ETH,因为L1和L2上的WETH合约不是“对称的”。


显然这违反了WETH的设计原理。那么WETH在跨链时,不论是充值还是提现,都需要先Unwrap成ETH后,再跨到对面,然后Wrap成WETH。这个也就是WETH Gateway的作用。


其他有更复杂逻辑的代币同理,需要更复杂和精心设计的Gateway才能正常在跨链环境下工作。Arbitrum的自定义Gateway继承了普通Gateway的跨链通信逻辑,并允许开发者自定义与代币逻辑相关的跨链行为,可满足大部分需求。


慢收件箱Delayed Inbox


与快箱也即 SequencerInbox相对应的是慢箱 Inbox (全称Delayed Inbox)。为什么要有快慢之分呢?因为快箱是专⻔接收排序器发布的L2交易Batch的,所有未经排序器在L2网络内预处理的交易,都不该出现在快箱合约中。


慢箱的第⼀点作⽤是,处理L1到L2的充值⾏为。⽤户通过慢箱进⾏充值,排序器监听到后再反映在L2上,最终这笔充值记录会被排序器包含进L2的交易序列中,并提交⾄快箱合约Sequencer Inbox。


在这个例⼦中,⽤户直接向快箱提交充值交易是不合适的,因为提交到快箱Sequencer Inbox中的交易,会干扰到Layer2正常的交易排序,然后会影响到排序器的工作。


慢箱的第⼆个作⽤,是抗审查。用户直接提交⾄慢箱合约中的交易,排序器⼀般会在10分钟内归集到快箱中。但如果排序器恶意忽略你的请求,慢箱还有⼀个强制归集force inclusion功能:


如果交易被提交至Delayed Inbox中,经过24小时,慢箱中的交易仍未被排序器包含至交易序列中,用户可以在Layer1上手动触发force inclusion函数,把被排序器忽略掉的交易请求,强制归集到快箱Sequencer Inbox中,之后就会被全体Arbitrum One节点监听到,会被强制包含进Layer2交易序列里。

图片


我们刚才提到过,快箱⾥的数据就是L2的历史数据实体。所以在被恶意审查的情况下,通过慢箱可以让交易指令最终包含进L2账本中,这涵盖了强制提款等逃离Layer2的场景。


由此可以看出,对任何⼀个⽅向和层次的交易,排序器最终都⽆法永久审查你。 


慢箱Inbox的几个核心函数:


depositETH(),最简单的充值ETH的函数。


createRetryableTicket(),可用于ETH和ERC20以及消息的充值。相较depositETH()而言,有更高的灵活性,例如可指定充值后L2的收款地址等。


forceInclusion(),也即强制归集功能,任何⼈都可以调⽤。该函数会校验,提交至慢箱合约中的某笔交易,是否过了24小时还没被处理。如果条件满⾜,则将对消息进⾏强制归集。


不过需要注意,force Inclusion函数实际上位于快箱合约中,只是为了⽅便理解,我们将其放在慢箱这⾥⼀起讲解。


出站箱Outbox


出站箱Outbox只与提现有关,可以理解为提现行为的记录和管理系统:


我们知道,Arbitrum官方桥的提现需要等待约7天的挑战期结束, Rollup Block 最终敲定后,提款行为才可以实施。⽤户在挑战期结束后,向Layer1上的Outbox合约提交相应的Merkle Proof,它再与其他职能的合约通信(如解锁其他合约中锁定的资产),最终完成提现。


OutBox合约会记录哪些L2到L1的跨链消息已经被处理过,以防止有人反复提交执行过的提现请求。它通过


mapping(uint256 => bytes32) public spent,记录提现请求的spent Index与信息对应关系,如果mapping[spentIndex] != bytes32(0)则该请求已被提现过。原理类似于防止重放攻击的交易计数器Nonce。


下⾯我们将以ETH为例完整讲解充值与提现的流程。ERC20与之不同的仅仅是⾛了Gateway,就不再赘述。


ETH充值


1. 用户调用慢箱的depositETH()函数。


2. 该函数会继续调用bridge.enqueueDelayedMessage(),在bridge合约中记录该消息,并将ETH发送往bridge合约。所有的ETH充值资金,都保管在bridge合约中,相当于一个充值地址。


3. 排序器监听到慢箱中的充值消息,将充值操作反映⾄L2数据库中,⽤户可以在L2网络看到自己充进来的资产。


4. 排序器将该笔充值记录包含进交易批次batch,提交给L1上的快箱合约。

3-cn.png

ETH提现


1. ⽤户在L2上调⽤ ArbSys合约的withdrawEth()函数 ,在L2上销毁相应数量的ETH。

2. 排序器将该提现请求发送⾄快箱。

3. Validator节点根据快箱中的交易序列,创建新的Rollup Block,其中会包含上述提款交易。

4. Rollup Block度过了挑战期并被确认后,⽤户可以在L1上调用Outbox.execute Transaction()函数,证明参数由前面提到的ArbSys合约给出。

5. Outbox 合约确认⽆误后,解锁bridge中相应数额的ETH发送给⽤户。

3-cn.png

快速提现


使⽤乐观Rollup官方桥提现就会出现等待挑战期的问题。我们可以⽤私营的第三方跨链桥来规避这个问题: 


原⼦锁交换。这种⽅式只是在双⽅在各⾃的链内进⾏了资产的互换,并且具有原⼦性,只要⼀⽅提供了Preimage,双⽅⼀定可以得到应有的资产。但问题是流动性⽐较稀缺,需要点对点地寻找对⼿⽅。


⻅证⼈跨链桥。⼀般类型的跨链桥都属于⻅证⼈桥。⽤户提交⾃⼰的提现请求,提现⽬的地指向第三方桥的运营者或流动性池。⻅证⼈发现跨链交易已提交到L1的快箱合约后,就可以直接在L1端向⽤户转账。这种⽅式本质上是⽤另⼀套共识系统来监视Layer2,并根据其已提交至Layer1上的数据进⾏操作。问题是,这种模式下的安全系数不如Rollup官方桥⾼。


强制提现


force Inclusion()强制归集功能用于对抗定序器的审查,任何L2本地交易、L1到L2交易和L2到L1交易,都可以使用该功能实现。定序器的恶意审查严重影响了交易体验,大部分情况下我们会选择提现离开L2,因此下面以强制提现为例介绍forceInclusion的用法。


回顾在ETH提现步骤中,只有步骤1、2是涉及到定序器审查的,所以只需要更改这两步:

3-cn.png

调用L1上慢箱合约中的inbox.sendL2Message(),输入参数就是在L2上调用withdrawEth()时需要输入的参数。该消息会共享给L1上的bridge合约。


等待24小时的强制归集等待期后,调用快箱中的force Inclusion()进行强制归集,快箱合约会检视bridge中是否有对应消息。


最终用户可以在Outbox中提现,其余步骤由同正常的提现相同。


另外,arbitrum-tutorials中也有使用Arb SDK的详细教程去指导用户如何通过forceInclusion()去进行L2本地交易和L2到L1交易。

声明:本网站所有相关资料如有侵权请联系站长删除,资料仅供用户学习及研究之用,不构成任何投资建议!