原文標題:《前Arbitrum 技術大使解讀Arbitrum 的組件結構(下)》
原文作者:羅奔奔,前Arbitrum 技術大使,極客Web3 貢獻者
本文為Arbitrum 前技術大使及智慧合約自動化審計公司Goplus Security 前共同創辦人羅奔奔對Arbitrum One 的技術解讀。
上一篇《Arbitrum 的元件結構解讀(上)》,我們介紹了Arbitrum 核心元件中的排序器、Validator、Sequencer Inbox 合約、Rollup Block、非互動式詐欺證明的作用,而在今天的文章中,我們將重點介紹Arbitrum 核心元件中與跨鏈訊息傳遞及抗審查交易入口相關的元件。

正文:先前的文章中,我們曾提到,Sequencer Inbox 合約專門在Layer1 上接收排序器發布的交易資料包Batch。同時,我們指出,Sequencer Inbox 又被稱為快箱,與之相對的是慢箱 Delayed Inbox(簡稱 Inbox)。下面,我們將對 Delayed Inbox 等與跨鏈訊息傳遞相關的元件進行細緻解讀。

跨鏈交易可分為L1 到L2(儲值)與L2 到L1(提現)。注意這⾥所說的儲值和提現未必與資產跨鏈相關,可以是不直接附帶資產的訊息傳遞。所以這兩個字只是表示跨鏈相關行為的兩個方向。
跨鏈交易與純L2 交易相比,跨鏈交易在L1 和L2 這兩個不同的系統中進行了資訊互換,因此過程更複雜。
另外,通常我們說的跨鏈行為,是在兩個毫不相關的網絡上,用見證人模式的跨鏈橋進行的跨鏈,這種跨鏈的安全性取決於跨鏈橋的運作者,歷史上基於見證人模式的跨鏈橋被盜事件頻繁發生。
而在Rollup 與ETH 主網之間的跨鏈行為,與上述跨鏈有本質不同,因為Layer2 的狀態是由記錄在Layer1 上的數據決定的,只要你使用的是Rollup 官方的跨鏈橋,其在運作結構上是絕對安全的。
這也凸顯出Rollup 的本質,它只是在用戶角度看,像⼀條獨立的鏈,但實際上所謂的「Layer2」只是Rollup 對使用者敞開的快速展示窗口,它的真實鍊式結構還是刻錄在Layer1 上。 所以,我們可以認為 L2 算半條鏈,或者說是「在 Layer1 上創造出的一條鏈」。
需要注意,跨鏈都是非同步和非原子性的,它不可能像在一條鏈上一樣做完一筆交易確認後就知道結果,也不能保證另一側一定會在某個時間點發生某些事。因此跨鏈有可能因為一些軟性問題而失敗,但只要使用正確的手段,諸如可重試票據(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 資產的跨鏈是複雜的。我們可以思考幾個問題:
·一個在 L1 上部署的代幣,它在 L2 上要如何部署?
·它的 L2 對應合約需要預先手動部署,還是系統可以自動為跨過來的、但尚未部署合約的代幣 自動部署資產合約?
·L1 上的 ERC-20 資產,在 L2 對應的合約位址是什麼?是否該和 L1 一致?
·在 L2 上原生發行的代幣,如何跨鏈至 L1?
·擁有特殊功能的代幣,如可調整數量的 Rebase 型代幣,自增長生息代幣,如何跨鏈?
我們不打算全部回答這些問題,因為展開太過複雜。這些問題僅是用來說明 ERC20 跨鏈的複雜性。

目前非常多擴容方案使用的都是白名單+手動清單的方案,來規避各種複雜的問題和邊界情況。
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 的。

如果現在把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 的跨鏈通訊邏輯,並允許開發者自訂與代幣邏輯相關的跨鏈行為,可滿足大部分需求。
與快箱也即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 只與提現有關,可以理解為提現行為的記錄和管理系統:
·我們知道,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,就不再贅述。
1. 使用者呼叫慢箱的 depositETH() 函數。
2. 函數會繼續呼叫 bridge.enqueueDelayedMessage(),在 bridge 合約中記錄該訊息,並將 ETH 發送至 bridge 合約。 所有的 ETH 儲值資金,都保管在 bridge 合約中,相當於一個儲值地址。
3. 排序器監聽到慢箱中的儲值訊息,將儲值操作反映⾄L2 資料庫中,⽤戶可以在L2 網路看到自己充進來的資產。
4. 排序器將該筆儲值記錄包含進交易批次 batch,提交給 L1 上的快箱合約。

p>
1. 使用者在L2 上呼叫ArbSys 合約的withdrawEth() 函數,在L2 上銷毀對應數量的ETH。
2. 排序器將此提現請求傳送至快箱。
3. Validator 節點根據快箱中的交易序列,建立新的 Rollup Block,其中會包含上述提款交易。
4. Rollup Block 度過了挑戰期並被確認後,⽤戶可以在L1 上呼叫Outbox.execute Transaction() 函數,證明參數由前面提到的ArbSys 合約給出。
5. Outbox 合約確認無誤後,解鎖 bridge 中對應金額的 ETH 傳送給使用者。

使用樂觀 Rollup 官方橋提現就會出現等待挑戰期的問題。我們可以用私人的第三方跨鏈橋來規避這個問題:
·原子鎖交換。這種方式只是在雙方在各自鏈內進行了資產的互換,並且具有原子性,只要⼀方提供了 Preimage,雙方⼀定可以得到應有的資產。但問題是流動性比較稀缺,需要點對點地尋找對手方。
·見證人跨鏈橋。 ⼀般類型的跨鏈橋都屬於見證人橋。使用者提交自己的提現請求,提現目的地指向第三方橋的運作者或流動性池。見證人發現跨鏈交易已提交到 L1 的快箱合約後,就可以直接在 L1 端向用戶轉帳。這種方式本質上是用另⼀套共識系統來監視 Layer2,並根據其已提交至 Layer1 上的資料進行操作。 問題是,這種模式的安全係數不如 Rollup 官方橋高。
force Inclusion() 強制歸集功能用於對抗定序器的審查,任何L2 本地交易、L1 到L2 交易和L2 到L1 交易,都可以使用該功能實現。定序器的惡意審查嚴重影響了交易體驗,大部分情況下我們會選擇提現離開 L2,因此以下以強制提現為例介紹 forceInclusion 的用法。
回顧在ETH 提現步驟中,只有步驟1、2 是涉及定序器審查的,所以只需要更改這兩步:

·調用L1 上慢箱合約中的inbox.sendL2Message(),輸入參數就是在L2 上呼叫withdrawEth() 時需要輸入的參數。該訊息會分享給 L1 上的 bridge 合約。
·等待24 小時的強制歸集等待期後,呼叫快箱中的force Inclusion() 進行強制歸集,快箱合約會檢視bridge 中是否有對應訊息。
最終使用者可以在 Outbox 中提現,其餘步驟由同正常的提現相同。
另外,arbitrum-tutorials 中也有使用 Arb SDK 的詳細教程去指導用戶如何透過 forceInclusion() 去進行 L2 本地交易和 L2 到 L1 交易。
原文連結
歡迎加入律動 BlockBeats 官方社群:
Telegram 訂閱群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方帳號:https://twitter.com/BlockBeatsAsia