以路印协议 V3 和 Arbitrum 为例,解析 强制提款/逃生舱/强制包含交易 功能的重要性
在现实世界中,几乎每一栋高楼大厦都有一个不可或缺的要素:安全出口。当火灾地震等突发事件降临时,安全出口就是保障人们生命安全的救命稻草。而在以太坊 Layer2 这个承载了百亿美元资产的托管平台体系中,可以让用户把资产安全撤回至 Layer1 的 “强制提款” 功能,已然成为不可或缺的必备设施。
Vitalik 在最近的文章 “Different types of layer 2s” 中也强调,用户能否顺利的把资产从 Layer2 撤回至 Layer1,是一个非常重要的安全指标。
但 “顺利提款” 问题在过去似乎没有得到大多数人的重视,甚至许多 Layer2 项目方都没有上线 “强制提款” 或 “逃生舱” 功能。在 L2 生态体系未成火候的时代,漠视 “无需许可的提款” 似乎不成问题。但如今 Layer2 已经承载了 120 多亿美元的资产,已然变成了一栋 “太大而不能倒” 的大厦。如果这样的一栋摩天大楼没有安全出口,后果简直是不可想象的。
抱着让广大读者重视 Layer2 安全风险的目的,《极客 web3》将在下文以路印协议 V3 和 Arbitrum 为例,为大家阐明为何 forced withdraw 与 escape hatch 等 “无需许可的提款功能” 是 Layer2 不可缺少的一环。
(根据 L2BEAT dYdX 浏览器显示,迄今为止 dYdX 强制交易/提款功能,总计被使用过 152 次,超过 100 万美元的大额提款多达 7 笔)
抗审查性是大问题:如果 Sequencer 故意拒绝你的请求,怎么办
过去关于 Layer2 的科普文章往往有一个问题,就是大多数时候都着重强调 “安全性” 与表面上的 “可用性”,却忽略了 “抗审查性”。即便是在谈论去中心化排序器方案时,很多人注意到的也是 MEV 是否去中心化,而不是抗审查性的改善。
换句话说,大多数人往往注重 Layer2 的状态转换是否有效,排序器能不能盗币,欺诈证明/有效性证明系统有没有投入使用,却忽略了一个不该被忽视的风险:如果 Sequencer 一直拒绝你的交易请求,或者干脆长时间故障,甚至停机,这个时候怎么办?
要知道,在 Solana 宕机期间,曾有人因为资产面临清算而无法及时补仓,使得几百万美元的资产面临风险。此类拒绝用户请求的场景一旦发生,造成的经济损失并不可小视。
即便只有个别人可能遭遇此类情况,但如果落到了一些手握大量资金的鲸鱼身上,整个市场都可能连带遭殃(假设某人在以太坊上的 Defi 借贷协议有几亿美元资产可能在一周内被清算,但他因为用了 Tornado 而被 OFAC 列入制裁名单。此人大部分资金都在 OP 上,而 OP 排序器配合 OFAC 拒绝它的请求)
我们不妨把这个问题投射到 avalanche 或 polygon 等独立于以太坊的公链上去分析。如果 Avalanche 上超过 2/3 的 Validator 共识节点决定对你展开交易审查,那么它们可以拒绝把你发起的 Txn 打包进区块里,或者不承认包含你的 Txn 的区块。这个时候,你的钱基本就被埋在了这条链里出不来:
除非你能拉拢一些 Validator,使得参与审查攻击的 Validator 不足 2/3,或者你能号召一些人通过社会共识的方法,把 Avalanche 分叉。显然在这个时候,你还是有办法把资金快速撤出 Avalanche 的,并且我们要考虑到,超过 2/3 的 Validator 联合起来对某个地址发起交易审查,本身就需要一段时间去达成,这会给被审查的用户留下充沛时间 “逃出生天”。
但在 Layer2 上,这种情况可能大不相同。Layer2 的 Sequencer 一般都是由官方自己在运行,如果 Sequencer 想要对你展开审查攻击,它可以把你的钱 “冻结在 Layer2”,也就是彻底拒绝你发起的,把资产从 L2 跨到 L1 的交易请求。显然按照 L2 的运作机理,如果你不能绕开排序器执行提款操作,是完全可能被 Sequencer 把资产冻结在 L2 不能转移走的。
那么该怎么解决这种问题呢?其实说白了就是,怎么实现 “无需许可” 的提款功能,让用户在被 Sequencer 或 Layer2 项目方审查的情况下,安然无恙的把资产撤回到 Layer1 上?有一些项目方提出了去中心化 Sequencer 的方案,但这治标不治本,如果这些数量极为有限的排序器联合起来审查你,还是可以把你的资产 “冻结”,况且 POS 节点的反女巫也是个棘手的问题(参考 Multichain 事件)。
真正最有效的办法,是直接在 L1 链上设置一个 “出口”,让用户在长时间得不到 Sequencer 响应时,通过 L1 上的专用出口把资金从 L2 撤出。
路印协议 V3 版本的强制提款与破产清算模式
这里我们以路印协议的 V3 版本为例,它针对用户发起的强制提款分列了两种不同情况,第一种情况是:
用户直接在 Layer1 上通过 ExchangeV3 合约中的 forcedWithdraw 函数发起强制提款,声明自己在路印协议的 L2 账户是哪个,以及要提走哪种 Token。之后,ExchangeV3 合约会抛出一个链上事件,提示有人发起了强制提款请求。由于路印协议的所有节点(包括 Sequencer)都运行着 Geth 客户端,所以会从以太坊区块中获知,有人发起强制提款并触发了对应的链上事件。
要注意的是,强制提款不会被立刻处理,而是置入 pendingForcedWithdrawals 队列,处于待处理状态。Sequencer 注意到有人在 Layer1 发起强制提款后,一般会在 15 天内触发 ExchangeV3 合约中的 Process 函数,在以太坊链上把 Token 转给提款发起者(从 L2 项目方在以太坊链上的存款地址,给提款者转钱)。
如果 Sequencer 在 15 天内没有响应用户的强制提款请求,用户可以调用 notifyForcedRequestTooOld 函数,让 ExchangeV3 合约抛出名为 WithdrawalModeActivated 的事件,通知路印协议的全节点,破产清算模式被激活了。
如果破产清算模式被激活,此时路印协议 V3 会停止接收 Sequencer 提交的新 L2 区块,也就是说这个时候路印协议整个就停止了运转。这个过程会持续至少 30 天。
但在破产清算模式下,用户依然可以在 Layer1 上把自己的资产提走,只不过需要提交 merkle proof 证明自己的资产状况/状态,在 L2 的状态树上是可查的。(证明自己在 Layer2 的资产余额,和自己发起提款时声明的金额是一致的)
路印协议的这种破产清算模式,在 L2BEAT 上也被称作 Escape Hatch 逃生舱机制。这种模式的触发有个先决条件,就是排序器在规定的时间内没有响应用户的强制提款请求,或者 Sequencer 长期故障或停机。此时用户可以通过手动触发的方式,让 Rollup 合约进入冻结模式/停止运转。然后用户可以构造 merkle Proof 证明自己在 Layer2 上的资产情况,从 L2 项目方在 L1 的存款地址中,把属于自己的那部分资产提走。
在 StarkEx 的文档中,还为这一过程画了专门的示意图。如果 L2 用户在 L1 提交的 Forced Withdrawal 请求在 7 天窗口期结束时,未得到定序器响应,则该用户可以调用 freeze Request 功能让 L2 进入冻结期。此时,L2 定序器将无法在 L1 上更新 L2 的状态,L2 状态冻结后要过 1 年才能解冻。之后用户可以提交 merkle proof 并提款。
但要构造 Merkle Proof,需要先获知完整的 L2 状态树,也就是需要找一个 L2 全节点索要数据,同时需要一段代码来生成 merkle Proof,显然这需要一定的技术门槛。为了方便广大用户,L2BEAT 此前曾声明,Layer2 应该设置一批权限开放且代码开源的全节点,帮用户获知 L2 上全体账户的状态(包含余额、交易次数等)。这一举动其实也说明了强制提款与逃生舱机制的重要性。
Arbitrum 的 “强制包含交易” 功能
但强制提款/逃生舱似乎不是唯一的抗审查解决方案。比如,Arbitrum 采用了 “强制包含交易” 的方式,用户可以先在 L1 上的 delayed Inbox 合约提交需要被 Sequencer 处理的 Txn/withdraw,如果 Sequencer 超过 24 小时没有处理,用户可以调用 L1 上 Sequencer Inbox 合约的 force Inclusion 函数,让 Txn 直接被包含进 Arbitrum 的交易序列中(抛出一个链上 event 告知 Arbitrum 全节点,几笔 delayed Inbox 上有记录的 Txn 需要被包含进 L2 的账本中)。
相比之下,Arbitrum 的方法要更简单些,但这种方法还是略带不足:因为它只抛出一个链上事件告诉 Arbitrum 节点,有几笔被排序器忽略了的交易需要被包含进 L2 最长链中,而不是像路印协议和 StarkEx 的 破产模式/逃生舱 那样允许用户直接在 L1 上把钱提走。如果 Arbitrum 的挑战者节点联合起来发动审查攻击,似乎还是可以让用户的钱被冻结在 L2。
所以说 Arbitrum 的 force Inclusion 还不够 permissionless,虽然只要有一个诚实节点愿意发布欺诈证明,就可以指出排序器忽略了某个用户的 forceInclusion 请求,但这还是引入了一定程度的信任假设,只不过程度很轻微。
更确切的说,“需要被强制包含的交易” 是要被至少 1 个 ARB 的挑战者节点认可的,这些节点目前有 9 个,它们有权决定给哪些 L2-L1 之间的跨链消息放行,现在也只有它们能发布欺诈证明。只要这 9 个节点联合串谋,理论上还是可以让用户的 “强制交易” 无效。
所以,目前 Arbitrum 的强制包含交易/提款,不像路印和 StarkEx 的破产清算模式那样无需 L2 节点许可。但 L2BEAT 还是对 Arbitrum 的这个方案给予了很高的评价。因为在未来,Arbitrum 会上线名为 BOLD 的 Permissionless 的欺诈证明发布机制,挑战者节点届时将难以或无法串谋(现在其实就很难串谋)。
按照 L2BEAT 的数据,目前 TVL 超过 5000 万美元,且没有针对 Sequencer Failure 或 Proposer Failure 中的某项提供应对举措的,包括:OP Mainnet、Base、zkSync Era、Mantle、Starknet、Linea、Polygon zkEVM、Metis。这些 L2 都可以在极端情况下导致用户资产被冻结在 L2 提不出来。
所以显而易见,强制提款或破产清算模式有其存在的必要性,虽然目前它只是依靠用户-排序器这个对手方之间的博弈来发挥作用,还称不上真正意义的 “随时可提款”(Arbitrum 有 24 小时延时且可能失败,路印最长 15 天延时,StarkEx 有 7 天最大延时),但显然 “有总比没有好”。而且强制提款的延时问题,相信可以在未来靠着更精巧的机制设计被妥善解决(目前主要顾及到某些 MEV 科学家可能利用 forceInclusion 发起抢跑交易,所以要引入延时。具体详情可以阅读各大 L2 项目方的官方资料)
随着去中心化 Sequencer 被越来越多 L2 纳入路线图,以及 Vitalik 为首的以太坊基金会不断向人们加强对 Layer2 安全性的教育,类似强制提款的抗审查交易功能势必会被越来越多人所重视,这将使得以太坊 Layer2 体系更接近一个抗审查、去信任化的金融基础设施体系。如果 Layer2 实现了去信任化的资金进入进出方式,相信将会有更多做市商与流动性提供者进入 L2 基础设施,为整个 web3 的 mass adoption 向前推进一步。