Arbitrum的組件結構解讀(上)
BlockBeats 律動財經 2023-12-26 11:31
本文是 Arbitrum 前技術大使及智能合約自動化審計公司 Goplus Security 前聯合創始人羅奔奔對 Arbitrum One 的技術解讀。
因為中文圈子裡涉及 Layer2 的文章或資料,缺乏對 Arbitrum 乃至 OP Rollup 的專業解讀,本文試圖通過科普 Arbitrum 的運轉機理,填補這一領域的空缺。由於 Arbitrum 本身的結構太複雜,全文在儘可能簡化的基礎上,還是超過了 1 萬字篇幅,所以分成了上下兩篇,建議作為參考資料收藏轉發!
Rollup 排序器簡述
Rollup 擴容的原理可以概括為兩點:
成本優化:將大部分運算與儲存任務移交至 L1 鏈下也即 L2 上。L2 大多是運⾏在單台服務器也即排序器(Sequencer/Operator)上的⼀條鏈。
排序器在觀感上接近於一台中心化服務器,在「區塊鏈不可能三⻆」中捨棄「去中心化」來換取 TPS 與成本上的優勢。 ⽤戶可以讓 L2 來代替以太坊處理交易指令,成本比在以太坊上交易要低得多。
安全保障:L2 上的交易內容與交易後的狀態,會同步至以太坊 L1,通過合約來校驗狀態轉換的有效性。同時,以太坊上會保留 L2 的歷史記錄,排序器即便永久宕機,他⼈也可以通過以太坊上的記錄,還原出整個 L2 的狀態。
從根本上來說,Rollup 的安全性是基於以太坊的。排序器如果不知道某個帳戶的私鑰,就無法用該帳戶的名義發起交易,或者無法篡改該帳戶的資產餘額(即便這麼做了,也很快被識破)。
雖然排序器作為系統中樞帶有中心化色彩,但在成熟度比較高的 Rollup 方案中,中心化排序器僅能實施交易審查等軟性作惡行為,或者惡意宕機,但在理想狀態的 Rollup方案中,有相應的手段進行遏制(比如強制提款或排序證明等抗審查機制)。
而防止 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 中的龍頭項目——Arbitrum One,覆蓋整個系統的方方面面,仔細閱讀完後你將對 Arbitrum 和樂觀式 Rollup/OPR 有深刻的理解。
Arbitrum 的核心組件與工作流程
核心合約:
Arbitrum 最重要的合約包括 SequencerInbox, DelayedInbox, L1 Gateways, L2 Gateways, Outbox, RollupCore, Bridge 等。後續將詳細介紹。
排序器 Sequencer:
接收用戶交易並進行排序,計算交易結果,並迅速(通常 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 系列合約來判定欺詐證明。
在 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 應該怎麼實現抗審查。
暢行幣圈交易全攻略,專家駐群實戰交流
▌立即加入鉅亨買幣實戰交流 LINE 社群(點此入群)
不管是新手發問,還是老手交流,只要你想參與虛擬貨幣現貨交易、合約跟單、合約網格、量化交易、理財產品的投資,都歡迎入群討論學習!
- 加入鉅亨買幣LINE官方帳號索取免費課程
- 掌握全球財經資訊點我下載APP
文章標籤
上一篇
下一篇