资产桥的作用
Rollup 的主要流程中,实际上不包含资产桥,也就是说即使没有资产桥,L2依然能正常运行但是此时L1与L2在数据上是完全独立的两条链,L1不理解L2上的数据(L1只保存L2压缩后的数据,不理解数据),L2上也不知道L1上发生了什么(只能拿到区块高度等一些基本信息)。完全可以把L2做是另外一条链。
在这种情况下如果需要做资产转移,就和普通的一层链之间的资产转移没什么区别.
而有了自己实现的资产桥就不一样,因为实际上L2的数据都是通过L1上的inbox(sequencer inbox)合约保存的,所以当我们在inbox合约中解析数据,L1上就可以看到L2上的部分数据
虽然这会增加L1上的手续费,但是这样可以降低跨链带来的安全性问题(跨链过程本质上是在L1上的inbox合约中,其他逻辑则完全嵌套在L2的主用逻辑中,也就是跨链的安全性=整个L2的安全性=aribtrum的any-trust模型)
arbitrum 的快箱&慢箱
在介绍资产桥之前,我们先来区分一下arbitrum的快箱和慢箱。
快箱 (Sequencer Inbox)
快箱是L2交易的入口(写入sequencer的交易最终会在L2上被处理,sequencer的处理实际上还没进入L2)
在Sequencer inbox中交易会迅速被validator打包(validator的打包逻辑就是在在inbox中拿数据,来打包)
慢箱(inbox)
慢箱中的交易是L1往L2上发送的交易,通过慢箱,我们可以在L1上改变L2的世界状态.
慢箱的实际价值有两个
L1向L2发送数据是,L2不需要验证L1的数据,L1的数据只能通过inbox进入L2,对数据的校验都发生在L1的inbox合约中
抗审查,因为L2的所有交易都是由sequencer打包的,而sequencer是一个中心化的节点,sequencer可以对L2上的交易进行恶意的审查从而拒绝部分交易(sequencer 不能修改交易内容,因为他没有指定账户的私钥).此时可以通过L1上的inbox合约强行把交易写入L2(实际上最终也是写入sequencer inbox),L2的区块是validator在Rbolck中确定的(sequencer不同意也无所谓),当交易通过慢箱写入L2后,sequencer只能接受这个交易(否则会因为与L2的状态不一致导致失去部分功能)
资产桥的运作
知道慢箱的处理逻辑之后,我们可以来看看资产桥是怎么运作的.
资产桥分为两种处理逻辑,L1到L2(充值),L2到L1(提现),当然arbitrum的资产桥不只是能做资产转移的操作,实际上也可以完成calldata的跨链操作(把calldata传递到L2指定的合约)
充值过程
在讨论充值问题之前,我们需要考虑下面几个
- ETH怎么铸造?
- ERC20怎么处理?
- L2上没有对应的ERC20合约怎么办?自动部署,还是交易直接失败?
- 怎么控制L2铸造的权限,L2上的代币最终是可以提现在L1上的,如果随便铸造,跟L1对不上账怎么办?
- 铸造的时候L2手续费暴涨,铸造失败怎么办?
arbitrum 的资产桥是典型的
锁定-铸造 销毁-解锁
模型,L1上锁定的代币,L2上怎么铸造.
gateway
要回答这些问题,我们先来看一下arbitrum的资产桥模型 gateway
gateway实现了L1 <–> L2资产合约的映射(ETH也使用合约的方式来映射)
arbitrum提供来了一些标准的ERC20 template,正常情况下,如果L1上的资产合约也是标准的ERC20,那么arbitrum会自动在L2上部署一个相同的ERC20合约(可能详细功能不同,但是能实现ERC20的逻辑),而这个映射出来的ERC20 通过gateway做权限验证,也就是只有gateway合约能在这个合约中铸造和销毁,这样保证了L1和L2上的账能对的上.
插一个小知识,arbitrum链上的交易手续费是使用ETH来支付的,但arbitrum本身不产生ETH(这点我不是很确定),所以在使用arbitrum之前,需要从以太坊上冲一些ETH到arbitrum上,这个充值交易的手续费在L1上支付,注意这里不是代付,是在交易到达L2后直接在L1中的msg.value中扣除。涉及到L1 <–> L2交易一个非常麻烦的问题 – 手续费处理。这里就不详细展开
retryable 可重试票据
可重试票据主要是用来解决L2上铸造失败的情况,L1上充值交易发送到L2上之后,可能因为L2上手续费超过 用户愿意支付的手续费阈值(在L1上发送充值交易时指定的)时可能导致交易的失败。这时候交易已经记录到L2上只是执行失败(calldata还在),用户可以在L2上手动重试,手动重试不能改变calldata,但是手续费是在重试交易中一起支付的。L1 -> L2的可重试票证只会保存7天,7天之后,资产将会永久的锁定在L1上(可以续费延期).
正常情况L1上的充值操作不需要用户去L2上触发铸造,L2会自动完成铸造.L2 -> L1就不行,必须去L1上手动提现,当然相对而言L2 -> L1的票据是永久有效的,用户不需要急着提现
ok,我们已经知道了资产桥的架构,现在来看一下充值的详细过程
充值过程,用户调用L1 inbox合约中的createRetryableTicket
方法创建可重试票据,指定L2上的接受者地址,token地址,手续费等,
inbox会将L1的资产锁定的L1上对应资产的gateway合约中,并将L2上的铸造请求的ticket写入sequencer inbox合约中
L2 订阅到sequencer inbox 中的铸造请求后会找到对应的gateway合约(这部分工作是gateway router做的),铸造代币
如果L2自动铸造失败,这是用户可以在L2 上手动重试,或者在L1上完成手动重试(避免排序器审查)
提现流程
在理解充值流程后,提现就很容易理解了
提现的过程实质上是操纵gateway合约完成代币销毁,并生成票据,将票据写回到L1上
这里简单解释一下写回操作:
写回操作是通过arbitrum的outbox实现的,由validator来调用L1上的outbox合约将数据写回到L1,但是写回操作并不直接执行这些数据,只是记录数据,最后的执行需要用户手动去触发,这也是为什么提现操作不会自动在L1上进行(目前猜测是因为L2->L1不好控制手续费,所以没有在这里做自动执行,并且,自动执行相当于是L2自动修改L1的状态,实际上是比较不可控的)
当充值操作写回到L1的outbox之后,用户就可以在L1上解锁资产
Q: 我冲了10WETH 可以提现20WETH吗?
这是可以的,如果你在L2上赚钱了(多赚了10WETH),只要L2提供的票据说你销毁了20WETH, 那么在L1上就会给你解锁20WETH, 桥只要保证总资产的帐对的上就可以.