作者:羅奔奔,前Arbitrum技術大使,極客web3貢獻者

在上一篇文章《前Arbitrum技術大使解讀Arbitrum的組件結構(上) 》,我們介紹了Arbitrum核心組件中的排序器、Validator、SequencerInbox合約、Rollup Block、非互動式詐欺證明的作用,而在今天在的文章中,我們將重點介紹Arbitrum核心元件中與跨鏈訊息傳遞及抗審查交易入口相關的元件。

前Arbitrum技術大使解讀Arbitrum的組件結構(下)

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

前Arbitrum技術大使解讀Arbitrum的組件結構(下)

跨鏈與橋接的原理

跨鏈交易可分為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跨鏈的複雜度。

前Arbitrum技術大使解讀Arbitrum的組件結構(下)

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

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的。

前Arbitrum技術大使解讀Arbitrum的組件結構(下)

如果現在把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交易序列裡。

前Arbitrum技術大使解讀Arbitrum的組件結構(下)

我們剛才提到過,快箱⾥的資料就是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上的快箱合約。

前Arbitrum技術大使解讀Arbitrum的組件結構(下)

ETH提現

1. ⽤戶在L2上調⽤ ArbSys合約的withdrawEth()函數,在L2上銷毀對應數量的ETH。

2. 排序器將該提現請求發送⾄快箱。

3.Validator節點根據快箱中的交易序列,建立新的Rollup Block,其中會包含上述提款交易。

4. Rollup Block度過了挑戰期並被確認後,⽤戶可以在L1上呼叫Outbox.execute Transaction()函數,證明參數由前面提到的ArbSys合約給出。

5. Outbox 合約確認⽆誤後,解鎖bridge中對應金額的ETH發送給⽤戶。

前Arbitrum技術大使解讀Arbitrum的組件結構(下)

快速提現

使⽤樂觀Rollup官方橋提現就會出現等待挑戰期的問題。我們可以⽤私營的第三方跨鏈橋來規避這個問題:

  • 原⼦鎖交換。這種⽅式只是在雙⽅在各⾃的鏈內進⾏了資產的互換,並且具有原⼦性,只要⼀⽅提供了Preimage,雙⽅⼀定可以得到應有的資產。但問題是流動性⽐較稀缺,需要點對點地尋找對⼿⽅。
  • ⻅證⼈跨鏈橋。 ⼀般類型的跨鏈橋都屬於⻅證⼈橋。 ⽤戶提交⾃⼰的提現請求,提現⽬的地指向第三方橋的運營者或流動性池。 ⻅證⼈發現跨鏈交易已提交到L1的快箱合約後,就可以直接在L1端向⽤戶轉帳。這種⽅式本質上是⽤另⼀套共識系統來監視Layer2,並根據其已提交至Layer1上的資料進⾏操作。問題是,這種模式的安全係數不如Rollup官方橋⾼。

強制提現

force Inclusion()強制歸集功能用於對抗定序器的審查,任何L2本地交易、L1到L2交易和L2到L1交易,都可以使用該功能實現。定序器的惡意審查嚴重影響了交易體驗,大部分情況下我們會選擇提現離開L2,因此以下以強制提現為例介紹forceInclusion的用法。

回顧在ETH提現步驟中,只有步驟1、2是涉及定序器審查的,所以只需要更改這兩步:

前Arbitrum技術大使解讀Arbitrum的組件結構(下)

  • 呼叫L1上慢箱合約中的inbox.sendL2Message(),輸入參數就是在L2上呼叫withdrawEth()時需要輸入的參數。該訊息會分享給L1上的bridge合約。
  • 等待24小時的強制歸集等待期後,呼叫快箱中的force Inclusion()進行強制歸集,快箱合約會檢視bridge中是否有對應訊息。

最終用戶可以在Outbox提現,其餘步驟則由同正常的提現相同。

另外,arbitrum-tutorials中也有使用Arb SDK的詳細教學去指導用戶如何透過forceInclusion()去進行L2本地交易和L2到L1交易。