作者:Nic Lin,imToken Labs 资深区块链工程师
本文受众:区块链开发者、对 Rollup 有所了解的区块链爱好者
本篇是 Rollup Bridge 介绍系列的第六篇。
Orbiter Finance 和这系列介绍过的 Hop Protocol 很相似,两者都透过 Rollup 本身和 L1 之间资讯传递的功能来达到跨 L2 转账的安全性:只要 Rollup 本身及其 L1<->L2 讯息传递的功能正常,就能确保使用者转账的安全性,而不需要去相信 validator(例如 Celer 的 PoS 链节点)不会作恶。
而 Hop Protocol 和 Orbiter Finance 主要的差异在于,Hop 仰赖合约送出的讯息能够正确地被 relay 到 L1 及目标 L2,Orbiter 则仰赖 L2 的交易能够正确在 L1 被读取。而他们的共同点则是有 challenge 机制,平常预期交易都是合法的,但当有人造假交易(Hop)或是拒绝完成交易(Orbiter)时,一定能够拿出证据证明,并惩罚造假的人。
概念来源
Hop 和 Orbiter 的概念其实都来自于 Vitalik 在 ethresearch 的一篇文章,这篇文章介绍的是如何在只有 Rollup B 支援智能合约功能时能够完成从 Rollup A 转账到 Rollup B 的操作(但从 B 转到 A 会比较麻烦)。大致上的运作方式是:使用者在 Rollup A 转账给流动性提供者(下文中均称为 Maker),Maker 在 Rollup B 上转账给使用者。如果 Maker 装死,则使用者可以在 Rollup B 上的合约申请 challenge,并提交自己在 Rollup A 转账给 Maker 的交易证明,证明自己在 Rollup A 的确有转账给 Maker。
注:这会需要 Rollup B 能够读取到 Rollup A 的区块或交易记录。
而 Orbiter 和当初概念不一样的地方就在于当 Maker 装死、使用者要 challenge 的时候,实际接受 challenge 并验证交易的合约不是在 Rollup B 上,而是在 L1。因为要能在 Rollup B 上验证交易,表示 Rollup B 一定要支援智能合约。但如果思考一下就会发现,如果 Rollup 的资讯都会写到 L1,而 L1 又有支援智能合约的话,那就干脆直接统一在 L1 验证交易就好了!
所以 Orbiter 实际上不需要 Rollup 支援智能合约,这也让 Orbiter 能够支援比 Hop 还多的 Rollup(虽然现在大部分 Rollup 都支援智能合约)。
注:Hop 支援的 Rollup 都必须要能支援智能合约。
架构
如同上面讲到的,Orbiter 在 Rollup 上不需要有合约,但在 L1 上它需要针对每个 Rollup 去写相对应的 SPV 合约,SPV 合约的功能就是证明一笔交易存在在该 Rollup 的区块或交易记录里。
另外在 L1 上的合约还会包含 Maker Deposit 合约(MDC)及 Event Binding 合约(EBC)
- Maker Deposit 合约负责管理 Maker 的押金,如果使用者 challenge 成功,会从 Maker 的押金中补偿给使用者。
- Event Binding 合约负责验证使用者在 Rollup A 送出的交易(Source Tx),包含验证交易格式是否正确,并且它会算出 Maker 在 Rollup B 「应该」要送出的交易(Target Tx)的格式内容。
注:会说「应该」是因为 Maker 有可能会装死。如果今天 Maker 被 challenge 了,他就要提出证据证明他在 Rollup B 上真的有转钱给使用者,而这笔转钱给使用者的交易的交易内容就必须要和 EBC 算出的 Target Tx 的内容一样。
底下是官方提供的流程图,Source Network 是 Rollup A、Target Network 是 Rollup B,Chain X 则是 L1。图中左边虚线包起来的部分会是正常的交易流程:Maker 在 Rollup B 上如实转钱给使用者,皆大欢喜;右边虚线包起来的部分则是 challenge 的过程,步骤比较繁琐。
流程
正常情况
- 使用者到 MDC 合约确认 Maker 资讯,包含押金数量、收取的手续费高低,及透过过往历史看到的 Maker 的表现
- 使用者在 Rollup A 转钱给 Maker(Source Tx)
- Maker 侦测到 Rollup A 有人成功转钱给他
- Maker 把 Source Tx 喂进去 EBC 合约,算出 Target Tx 的内容,例如 Target Tx 转给使用者的金额会是扣掉保留给自己的手续费的金额
不正常情况
接续自使用者在 Rollup A 转钱给 Maker 之后,Maker 没有在时限内在 Rollup B 转钱给使用者
- 使用者首先先到 Rollup A 的 SPV 合约证明 Source Tx 的存在,这个 proof 会存在 SPV 合约的 storage,等待 MDC 合约来查询(图例中的步骤 ⓵)
- 使用者接着到 MDC 合约申请仲裁(图例中的步骤 ⓶)
- MDC 合约收到仲裁申请后会去 SPV 合约拿 Source Tx 的 proof,并请 EBC 合约验证 Source Tx 的有效性,都确认没问题后就开始倒数,等 Maker 来回应(图例中的步骤 ⓷ 和 ⓸)
- 如果 Maker 过了一段时间都没有来回应,则使用者可以触发 MDC 合约作出仲裁,在 L1 上完成 Target Tx,从 Maker 的押金转给使用者,其中会包含补偿金(图例中的步骤 ⓹、⓺ 和 ⓻)
手续费
Maker 在存押金到 MDC 合约时,要指定他会收取的手续费比例(之后可以再来更改),所以 Target Tx 转的金额会以 MDC 合约里记录的手续费为准,例如假设 Maker 手续费指定为 1%,使用者在 Rollup A 送 1 Ether 到 Maker 地址,则 Maker 应该要在 Rollup B 送 0.99 Ether 给使用者。
如果被 challenge,Maker 要提供 Target Tx 到 Rollup B 的 SPV 合约。如果 Maker 转错转成 0.98 Ether,则 Maker 要自己认赔,因为 EBC 合约算出来 Target Tx 里转的金额就一定要是 0.99 Ether。
Maker 押金
为了避免出现多个使用者同时转钱给 Maker,导致 Maker 因为其押金小于总共收到的金额所以选择装死的情况,Orbiter 有针对不同 Rollup 订出不同押金规则:
1. 针对支援合约功能的 Rollup,我们可以把一个 Rollup 区块拆成更小的单位 slot。
- 假设可以拆成 5 个 slot,那 Maker 抵押的押金就是 5 倍的 limit。
- limit 是协议订的最高的转账金额上限。
2. 针对不支援合约功能的 Rollup,则要看那个 Rollup 一个区块最高可容纳多少笔交易(TPB,Transaction Per Block)。
- 例如 zkSync 1.0 的 TPB 约是 100(block size 390,tx size 4),那 Maker 抵押的押金就是 100 倍的 limit。
这两个规则都可以看出,Orbiter 为了防止 Maker 收到大于其押金金额的转账而有动机选择装死的情况,它参考的依据是一个区块最多可以塞多少笔交易,并假设最差的情况就是刚好一个区块塞满的交易都是转账给同一个 Maker 的交易,这种情况 Maker 的押金刚好能够 cover 所有的转账请求。
Maker APY
这个链接里有 Orbiter 团队利用过去一个月的数据来估算 Maker 的 APY:
可以看到,如果将这段时间的平均转账金额(0.17 Ether) 当作 limit 的话,在不同 Rollup 的 TPB 对应到的不同押金数量。再搭配上这段时间的流动性总额(90 Ether)及日均手续费获利(0.4085 Ether),可以算出预期的 APY。
可能的问题
不支援指定接收地址
Orbiter 目前还不支援指定 Rollup B 的接收地址,如果要支援指定接收地址,会需要挪用 Rollup 交易里其他栏位。像是目前 Orbiter 就挪用转账金额的最小的几个位元来当作不同 Rollup 的识别码。
经济激励机制尚不完整
使用者要 challenge Maker 是不需要放押金的(相比于 Hop 的 challenger 要放押金),表示使用者 challenge 的成本很小,这是否会让使用者有动机每次都去 challenge Maker,只要 Maker 忘记回应 challenge 或是 Maker 转账完就离线,那使用者就有机会获得额外的报酬。
但引入 challenger 押金的机制也会有一些问题,像是
- 使用者必须要在 L1 有钱才可以 challenge
- 而且 Orbiter 的补偿金是固定的,不像 Hop 的 challenge 机制里奖金和金额成比例
- 另外 Hop 里会有第三方有经济动机成为 challenger,但在 Orbiter 里只有使用者自己才有动机去 challenge,因为那笔转账会影响的只有使用者自己而已,不像 Hop 里造假影响的会是其他 Bonder
押金机制针对极端情况的处理还不完整
押金的参考依据是一个区块最多能塞下几笔交易,再假设最糟情况是一个区块都是转账给同一个 Maker,所以 Maker 的押金是 TPB*limit。
但这只要有交易还在 pending 中、没被完成(使用者转账给 Maker,但 Maker 还没转账给使用者),就能绕过这个押金机制的防护,因为 pending 中的交易是在之前的区块,如果在有 pending 交易的情况下出现最糟情况 - 区块里大家同时转账给该 Maker,则这时候 Maker 收到的总金额就会超过他的押金,他就有动机装死了。
我们可以反过来请使用者在看到一个 Maker 有 pending 交易时,先不要动作,等到 pending 交易都完成后再转账给 Maker。但第一个问题是如果有很多人同时要透过同一个 Maker,使用者会不知道要等多久。第二个问题是如果使用者都等待其他人的交易处理完才转账,那表示基本上一个区块就只会有一个转账,那这样设置 TPB*limit 的押金机制就没有意义了。
不过这其中当然还有可以更细致的调整可以尝试,例如依照使用者的风险承担程度,去决定当前 pending 金额占 Maker 押金多少百分比的情况下,使用者愿意送出交易。就看未来 Orbiter 团队会怎么设计。
如果要接上的 Rollup 可以接受 Invalid Tx,且要支援 native asset 以外(例如 ERC20)的转账,会有挑战性
针对会收入 Invalid Tx 的 Rollup,而且要转账的不是 native asset 而是 ERC tokens 时,会有点棘手,因为这种情况下协议不只要能证明交易存在,还要能证明执行成功(协议要去比对交易前后的 state 变化,确认 Maker 余额有增加),因为交易存在不等于交易执行成功,就像当前在区块链你可以看到失败的交易还是会被收入到区块里面。
如果不证明交易执行成功会发生什么事?攻击者可以做一笔 Invalid Tx 夹带在其他使用者的 Valid Tx 后,然后去 challenge Maker。
注:Invalid Tx 和 Valid Tx 的转账内容一样,只是攻击者余额不够所以交易会失败。
考慮以下三種驗證機制
1. 如果协议像当前的设计,只验证交易存在、发生过。那攻击者只要证明 Invalid Tx 被收录在 Rollup 的区块里就好,challenge 一定可以成功,表示 Maker 要平白无故赔钱给攻击者。
所以我们除了验证交易存在,还要验证 state 的变化,确保 Maker 的余额有增加。
2. 协议除了验证交易存在,还验证区块前后的 state 变化,确认 Maker 的余额是否真的增加了。但攻击者这时候只需要将 Invalid Tx 和使用者的 Valid Tx 夹带在同一个区块就可以,因为协议单靠区块前后 state 变化,分不出 Maker 余额增加是因为使用者的 Valid Tx 还是攻击者的 Invalid Tx。
3. 协议除了验证交易存在之外,还要能验证交易前后的 state 变化。如此协议才能确认交易真的有导致 Maker 的余额增加。
加入 3. 这样的验证机制除了会更复杂之外,这会需要 Rollup 本身有 commit 每一笔交易的 post-state root。如果没有的话,就只能退而求其次,在那个 Rollup 上只开放 native asset 的转账,因为 native asset 的转账失败不会被收录到区块里(就像你做单纯 Ether 转账,只要你 Ether 不够,交易是一定不会被收进区块,否则这就会是一个 DoS 风险:攻击者只要一直送出会失败的 Ether 转账就好)。
Hop 和 Orbiter 比较
- Orbiter 能够支援没有智能合约功能的 Rollup
- Orbiter 架构会比 Hop 简单,合约也比 Hop 少很多
- Orbiter 主要只会 focus 在 native asset 的转账(受限于交易证明难度),Hop 则是除了 native asset 外,也能支援 ERC token 转账
- Hop 需要仰赖 AMM 有足够的流动性,否则除了 Bonder 向使用者收的手续费外,AMM 的价格太差还会导致使用者换不到或损失更多钱
- 极端情况下,Orbiter 使用者可能因为 Maker 装死、押金也不够付,所以拿不到钱,但 Hop 只要 Rollup 运作正常,使用者就一定能拿到该拿的钱
- Orbiter 的 Maker 的在 L1 的押金是没办法挪作他用的,而且会是一笔不小的金额,而 Hop 对 Bonder 则没有这个要求,除非真的发生 challenge
风险提示:本文内容均不构成任何形式的投资意见或建议。imToken 对本文所提及的第三方服务和产品不做任何保证和承诺,亦不承担任何责任。数字资产投资有风险,请谨慎评估该等投资风险,咨询相关专业人士后自行作出决定。