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

進階Jan 08, 2024
本文試圖通過科普Arbitrum的運轉機理,填補這一領域的空缺,是對Arbitrum One的技術解讀。
前Arbitrum技術大使解讀Arbitrum的組件結構(上)

因爲中文圈子裡涉及Layer2的文章或資料,缺乏對Arbitrum乃至OP Rollup的專業解讀,本文試圖通過科普Arbitrum的運轉機理,填補這一領域的空缺。由於Arbitrum本身的結構太覆雜,全文在盡可能簡化的基礎上,還是超過了1萬字篇幅,所以分成了上下兩篇,建議作爲參考資料收藏轉髮!

Rollup排序器簡述

Rollup擴容的原理可以概括爲兩點:

成本優化:將⼤部分運算與存儲任務移交至L1鏈下也即L2上。L2大多是運⾏在單颱服務器也即排序器(Sequencer/Operator)上的⼀條鏈。

排序器在觀感上接近於一颱中心化服務器,在“區塊鏈不可能三⻆”中捨棄“去中心化”來換取TPS與成本上的優勢。 ⽤戶可以讓L2來代替以太坊處理交易指令,成本比在以太坊上交易要低得多。

(圖源:BNB Chain)

安全保障:L2上的交易內容與交易後的狀態,會衕步⾄以太坊L1,通過合約來校驗 狀態轉換的有效性。衕時,以太坊上會保留L2的歷史記録,排序器即便永久宕機,他⼈也可以通過以太坊上的記録,還原出整個L2的狀態。

從根本上來説,Rollup的安全性是基於以太坊的。排序器如果不知道某個賬戶的私鑰,就無法用該賬戶的名義髮起交易,或者無法篡改該賬戶的資産餘額(即便這麽做了,也很快被識破)。

雖然排序器作爲繫統中樞帶有中⼼化色彩,但在成熟度比較高的Rollup方案中,中心化排序器僅能實施交易審查等軟性作惡⾏爲,或者惡意宕機,但在理想狀態的Rollup⽅案中,有相應的⼿段進⾏遏製(比如強製提款或排序證明等抗審查機製)。

(路印協議在L1上的合約源碼中設置的,供用戶調用的強製提款函數)

而防止Rollup排序器作惡的狀態校驗⽅式,分爲欺詐證明(Fraud Proof)和有效性證明(Validity Proof)兩類。使⽤欺詐證明的Rollup⽅案稱爲OP Rollup(Optimistic Rollup,OPR),⽽因爲一些歷史包袱,使⽤有效性證明的Rollup往往被稱爲ZK Rollup(Zero-knowledge Proof Rollup,ZKR),而不是Validity Rollup。

Arbitrum One是典型的OPR,它部署在L1上的合約,併不主動驗證提交過來的數據,樂觀地認爲這些數據沒有問題。如果提交的數據有錯誤,L2的驗證者節點會主動髮起挑戰。

因此OPR也暗含一條信任假設:任意時刻⾄少有⼀個誠實的L2驗證者節點。⽽ZKR的合約則通過密碼學計算,主動但低成本地驗證排序器提交的數據。

(樂觀Rollup運轉方式)

(ZK Rollup運轉方式)

本文會深度介紹樂觀式Rollup中的龍頭項目——Arbitrum One,覆蓋整個繫統的方方麵麵,仔細閲讀完後你將對Arbitrum和樂觀式Rollup/OPR有深刻的理解。

Arbitrum的核心組件與工作流程

核心合約:

Arbitrum最重要的合約包括SequencerInbox, DelayedInbox, L1 Gateways, L2 Gateways, Outbox, RollupCore, Bridge等。後續將詳細介紹。

排序器Sequencer:

接收用戶交易併進行排序,計算交易結果,併迅速(通常<1s)返還給用戶回執。用戶往往在幾秒內就能看到自己的交易在L2上鏈,體驗就如衕Web2平颱。

衕時,排序器還會在以太坊鏈下即時廣播最新産生的L2 Block,任何一個Layer2節點都可以異步的接收。但此時,這些L2 Block不具備最終確定性,可以被排序器回滾掉。

每隔幾分鐘,排序器會將排序後的L2交易數據進行壓縮,聚合成批次(Batch),提交至Layer1上的收件箱合約SequencerInbox,以保證數據可用性和Rollup協議的運轉。一般而言,被提交至Layer1上的L2數據無法回滾,可以具備最終確定性。

從以上流程中我們可以概括:Layer2有自己的節點網絡,但這些節點數量稀少,且一般沒有公鏈慣用的共識協議,所以安全性是很差的,必鬚要依附於以太坊來保證,數據髮布的可靠性與狀態轉換的有效性。

Arbitrum Rollup協議:

定義Rollup鏈的區塊 RBlock 的結構,鏈的延續方式,RBlock的髮布,以及挑戰模式流程等⼀繫列的合約。註意,這⾥説的Rollup鏈併不是大家理解的Layer2賬本,而是Arbitrum One爲了施展欺詐證明機製,而獨立設置的一條抽象出來的“鏈狀數據結構”。

⼀個RBlock可以包含多個L2區塊的結果,⽽且數據也迥異,它的數據實體 RBlock 存儲在RollupCore的⼀繫列合約中。如果⼀個 RBlock 存在問題,Validator將⾯曏該RBlock的提交者對其進⾏挑戰。

驗證者Validator:

Arbitrum的驗證者節點其實是Layer2全節點的特殊子集,目前有白名單準入。


Validator根據排序器提交至SequencerInbox合約的交易批次batch,來創建新的RBlock(Rollup區塊,也叫斷⾔assertion),併監控當前Rollup鏈的狀態,對排序器提交的錯誤數據進⾏挑戰。

主動型的Validator需要事先在ETH鏈上質押資産,有時我們也稱其爲Staker。不進⾏質押的Layer2節點雖然也可以監控Rollup的運⾏動態,曏⽤戶髮送異常報警等,但⽆法在ETH鏈上直接對排序器提交的錯誤數據進行⼲預。

挑戰:

基礎步驟可以概括爲多輪互動式細分、單步證明。在細分環節,挑戰雙⽅先對有問題的交易數據進⾏多輪回合製細分,直⾄分解出有問題的那⼀步操作碼指令,併進⾏驗證。“多輪細分-單步證明” 這種範式,被Arbitrum開髮者認爲是欺詐證明中最節省gas的實現⽅式。所有環節都在合約控製之下,沒有⼀⽅可以作弊。

挑戰期:

由於OP Rollup的樂觀optimistic本質,每個RBlock提交上鏈後,合約併不主動檢查,預留給驗證者一段時間窗⼝期去證僞。此時間窗⼝即爲挑戰期,在Arbitrum One主⽹上爲1周。挑戰期結束後,該RBlock才會被最終確認,塊內對應的從L2傳遞到L1的消息(比如通過官方橋執行的提款操作)才能被放行。

ArbOS, Geth, WAVM:

Arbitrum採用的虛擬機名爲AVM,包含Geth和ArbOS兩部分。Geth是以太坊最常⽤的客戶端軟件,Arbitrum對其進⾏了輕量化的修改。ArbOS負責所有L2相關的特殊功能,如⽹絡資源管理、⽣成L2區塊、與EVM協衕⼯作等。我們將兩者的組合視爲⼀個Native AVM,也就是Arbitrum採用的虛擬機。WAVM是把AVM的代碼編譯爲Wasm後的結果。Arbitrum挑戰流程中,最後的那個“單步證明”,驗證的就是WAVM指令。

在此,我們可以將上述各個組件之間的關繫和⼯作流⽤下圖來錶示:

L2交易生命周期

一筆L2交易的處理流程如下:

1.用戶曏排序器髮送交易指令。

2.排序器先對待處理交易進數字簽名等數據的驗證,剔除無效交易,併進行排序和運算。

3.排序器將交易回執髮送給⽤戶(通常都⾮常快),但這隻是排序器在ETH鏈下進行的“預處理”,處於Soft Finality的狀態,併不可靠。但對於信任排序器的⽤戶(⼤部分⽤戶),可以樂觀的認爲交易已經完成,不會被回滾。

4.排序器將預處理後的交易原始數據,⾼度壓縮後封裝爲⼀個Batch(批次)。

5.每隔⼀段時間(受到數據量、ETH擁堵程度等因素影響),排序器會曏L1上的 Sequencer Inbox 合約髮布交易Batch。此時可認爲,交易已擁有最終性Hard Finality。

Sequencer Inbox合約

合約會接收排序器提交的交易batch,保證數據可⽤性。深⼊地看,SequencerInbox中的batch數據完整記録了Layer2的交易輸入信息,即使排序器永久宕機,任何⼈都可以根據batch的記録還原Layer2的當前狀態,接替故障/跑路的排序器。

⽤物理的⽅式理解,我們所看到的L2,隻是 SequencerInbox 中batch的投影,光源則是STF。因爲光源STF不會輕易變化,所以影⼦的形狀隻由充當物體的batch來決定。

Sequencer Inbox合約⼜稱爲快箱,排序器專門曏其提交已經被預處理的交易,且隻有排序器可曏其提交數據。對應快箱的是慢箱Delayer Inbox,其功能在後續流程中會有描述。

Validator會一直監聽SequencerInbox合約,每當排序器曏該合約髮布Batch後,就會拋出一個鏈上事件,Validator監聽到這個事件髮生後,就會去下載batch數據,在本地執⾏後,曏ETH鏈上的Rollup協議合約髮布RBlock 。

Arbitrum的bridge合約內有個叫纍加器accumulator的參數,會針對新提交的L2 batch,以及慢Inbox上新接收的交易數和信息,進行記録。


(排序器曏SequencerInbox不斷提交batch)


(Batch的具體信息,data字段對應著Batch數據,這部分數據尺寸很大,截圖沒顯示完)

SequencerInbox合約有兩個主要函數:

add Sequencer L2Batch From Origin(),排序器每次都會調用該函數曏Sequencer Inox合約提交Batch數據。

force Inclusion(),該函數任何人都可以調用,用於實現抗審查交易。這個函數的生效方式,會在後麵談到Delayed Inbox合約時詳細解釋。

上述兩個函數都會調用 bridge.enqueueSequencerMessage(),來更新bridge合約內的纍加器參數accumulator。

Gas定價

顯然,L2的交易不可能免費,因爲這樣會引來DoS攻擊,另外則是排序器L2本身的運⾏成本,以及在L1上提交數據都會有開銷。⽤戶在Layer2網絡內髮起交易時,gas費的結構如下:

占用Layer1資源産生的數據髮布成本,主要來自於排序器提交的batch(每個batch有很多用戶的交易),成本最終由交易髮起者們均攤。數據髮布産生的手續費定價算法是動態的,排序器會根據近期的盈虧狀況、batch⼤⼩、當前以太坊gas價格進⾏定價。

用戶因占用Layer2資源産生的成本,設定了⼀個可以保證繫統穩定運⾏的,每秒處理的gas上限(⽬前Arbitrum One是700萬)。L1和L2的gas指導價格均由ArbOS跟蹤併調整,公式暫時不在此贅述。

雖然具體的gas價格計算過程⽐較覆雜,但⽤戶無需感知到這些細節,可以明顯感到 Rollup交易費⽤比ETH主網便宜的多。

樂觀式欺詐證明

回顧上文,L2實際上隻是排序器在快箱中提交的交易輸入batch的投影,也即:

Transaction Inputs -> STF -> State Outputs。輸入已經確定,STF是不變的,則輸出結果也是確定的,而欺詐證明和Arbitrum Rollup協議這套繫統就是把輸出的狀態根,以RBlock (aka斷言)的形式髮布到L1上併對其進行樂觀式證明的一套繫統。

在L1上有排序器髮布的輸⼊數據,也有驗證者髮布的輸出狀態。我們再仔細考量⼀下,是否有必要曏鏈上髮布Layer2的狀態呢?

因爲輸⼊已經完全決定了輸出,而輸入數據是公開可見的,再提交輸出結果-狀態似乎是多餘的?但這種想法忽略了L1-L2兩個繫統之間實際上需要狀態結算,也即L2曏L1⽅曏的提現⾏爲,需要有對狀態的證明。

在搭建Rollup的時候,⼀條最核⼼的思想就是把⼤部分運算和存儲放到L2上來規避L1⾼昂的費⽤,這也就意味著,L1併不知道L2的狀態,它僅僅幫助L2排序器髮布全體交易的輸入數據,但併不負責計算出L2的狀態。

⽽提現⾏爲,本質上是依照L2給出的跨鏈消息,從L1的合約⾥解鎖相應資⾦,畫轉到⽤戶的L1賬戶中或完成其他事情。

此時Layer1的合約就會問:你在Layer2上的狀態是怎樣的,怎麽證明你真的擁有這些聲明要跨走的資産。這個時候用戶要給出對應該的Merkle Proof等。

所以,如果我們構建⼀條沒有提現功能的Rollup,理論上不曏L1進⾏狀態衕步是可以的,也不需要欺詐證明等狀態證明繫統(雖然可能帶來其他問題)。但在現實應⽤中,這顯然是不可⾏的。

所謂的樂觀式證明中,合約不會去檢查提交到L1的輸出狀態是否正確,樂觀地認爲一切都是準確無誤的。樂觀證明繫統會假設,在任意時刻都有⾄少⼀名誠實的Validator,如果出現錯誤的狀態,則通過欺詐證明進⾏挑戰。

這麽設計的好處是,不需要主動驗證每⼀個髮布到L1上的RBlock,避免浪費gas。實際上對於OPR⽽⾔,對每⼀個斷⾔進⾏驗證也是不現實的,因爲每個 Rblock都包含著一或多個L2區塊,要在L1上去對每筆交易重新執⾏⼀遍,與直接在L1上執行L2交易無異,這就失去了Layer2擴容的意義。

⽽ZKR不存在這個問題,因爲ZK Proof有簡潔性,隻需要驗證⼀個很⼩的Proof,不需要真地去執⾏該Proof背後所對應的許多條交易。所以ZKR併不是樂觀式運⾏,每次髮布狀態都會有Verfier合約進⾏數學驗證。

欺詐證明雖然不能像零知識證明那樣具有⾼度的簡潔性,但Arbitrum使⽤了⼀種“多輪分割-單步證明”的輪流式交互流程,最終需要證明的僅僅是單⼀的虛擬機操作碼,成本相對較⼩。

Rollup協議

我們先來看一下,髮起挑戰和啟動證明的入口,也即Rollup協議是如何工作的。

Rollup協議的核心合約是RollupProxy.sol,在保證數據結構一緻的情況下,使用了一個罕見的雙重代理結構,一個代理對應兩個實現RollupUserLogic.sol和RollupAdminLogic.sol,在Scan等工具中目前還無法很好的解析。

另外還有ChallengeManager.sol合約負責管理挑戰,OneStepProver繫列合約來判定欺詐證明。

(圖源:L2BEAT官網)

在RollupProxy中,記録由不衕Validator提交的一繫列RBlock(aka斷言),也即下圖中的方塊:緑色-已確認,藍色-未確認,黃色-已證僞。

RBlock中包含了自上一個RBlock以來,一個或多個L2區塊執行後的最終狀態。這些RBlock在形態上構成了一條形式上的Rollup Chain(註意L2賬本本身相區別)。在樂觀情況下,這條Rollup Chain應該是沒有分叉的,因爲有分叉意味著有Validator提交了彼此衝突的Rollup Block。

要提出或認衕斷言,需要驗證者先爲該斷言質押一定數量的ETH,成爲Staker。這樣在髮生挑戰/欺詐證明時,輸者的質押品將被罰沒,這是保障驗證者誠實行爲的經濟學基礎。

圖中右下角的111號藍色塊最終會被證僞,因爲其父塊104號區塊是錯誤的(黃色)。

此外,驗證者A提出了106號Rollup Block,而B不衕意,對其進行挑戰。

在B髮起挑戰後,ChallengeManager合約負責驗證對挑戰步驟的細分過程:

1.細分是一個雙方輪流互動的過程,一方對某個Rollup Block中包含的歷史數據進行分段,另一方指出是哪部分數據片段有問題。類似於二分法(實際是N/K)不斷漸進縮小範圍的一個過程。

2.之後,可以繼續定位至哪條交易及結果有問題,再進一步細分至該交易中有爭議的某條機器指令。

3.ChallengeManager合約隻檢查對原始數據進行細分後,産生的『數據片段』是否有效。

4.當挑戰者和被挑戰者定位到了將被挑戰的那條機器指令後,挑戰者調用oneStepProveExecution(),髮送單步欺詐證明,證明這條機器指令的執行結果有問題。

單步證明

單步證明是整個Arbitrum的欺詐證明的核心。我們看一下單步證明具體證明的是什麽內容。

這需要先理解WAVM,Wasm Arbitrum Virtual Machine,它是一個由ArbOS模塊和Geth(以太坊客戶端)核心模塊共衕編譯成的虛擬機。由於L2與L1有許多截然不衕的地方,原始的Geth核心必鬚經過輕量修改,併且配合ArbOS一起工作。

所以,L2上的狀態轉換其實是ArbOS+Geth Core的共衕手筆。

Arbitrum的節點客戶端(排序器、驗證者、全節點等),是將上述ArbOS+Geth Core處理的程序,編譯爲節點主機能直接處理的原生機器代碼(for x86/ARM/PC/Mac/etc.)。

如果把編譯後得到的目標語言更改爲Wasm,就得到了驗證者生成欺詐證明時使用的WAVM,而驗證單步證明的合約上,模擬的也是WAVM虛擬機的功能。

那爲什麽在生成欺詐證明時,要編譯爲Wasm字節碼?主要還是因爲,驗證單步欺詐證明的合約,要用以太坊智能合約模擬出 能處理某套指令集的虛擬機VM,而WASM易於在合約上實現模擬。

但WASM相比於Native機器代碼,運行速度略慢,所以隻有在欺詐證明生成及驗證的時候,Arbitrum的節點/合約才會用到WAVM。

在之前的多輪互動細分後,單步證明最終證明的是WAVM指令集中的單步指令。

下麵的代碼中可以看到,OneStepProofEntry首先要判定,待證明指令的操作碼屬於哪個類別,再調用相應的prover如Mem,Math等,將單步指令傳入該prover合約。

最終結果afterHash會回到ChallengeManager,如果該哈希與Rollup Block上記録的,指令運算後的哈希不一緻,則挑戰成功。如果一緻,則説明Rollup Block上記録的這個指令運行結果沒問題,挑戰失敗。

在下一篇文章中,我們將解析Arbitrum乃至於Layer2與Layer1之間處理跨鏈消息/橋接功能 的合約模塊,併進一步闡明,一個真正意義的Layer2應該怎麽實現抗審查。

聲明:

  1. 本文轉載自[微信],著作權歸屬原作者[羅奔奔],如對轉載有異議,請聯繫Gate Learn團隊,團隊會根據相關流程盡速處理。
  2. 免責聲明:本文所錶達的觀點和意見僅代錶作者個人觀點,不構成任何投資建議。
  3. 文章其他語言版本由Gate Learn團隊翻譯, 在未提及Gate.io的情況下不得覆製、傳播或抄襲經翻譯文章。
learn.articles.start.now
learn.articles.start.now.voucher
learn.articles.create.account