這一系列文章將圍繞以太坊的二層擴容框架,介紹其基本執行原理,具體操作細節,安全性討論以及未來研究方向等。本篇文章主要對 Plasma 一些關鍵操作的細節進行剖析。
在上一篇文章中我們已經理解了什麼是 Plasma 框架以及它是如何執行的,這一篇文章將對其執行過程中的一些關鍵部分,包括 Plasma 提交區塊的過程,當有惡意行為發生時如何構建防偽證明以及如何退出 Plasma 子鏈等進行剖析。需要注意的是,由於 Plasma 是一套框架,因此本文只剖析 Plasma 專案的共性,每一部分的實現細則還是需要參考實際的專案,例如 Plasma MVP(Minimal-Viable-Plasma)和 Plasma Cash 等。
存款(Deposit)
Plasma 的主要思想就是將大部分計算過程都轉移到鏈下進行,使用者只有在進入和退出 Plasma Chain 的時候需要跟主鏈上的智慧合約互動,這也是所有 Plasma 應用的標準流程。
使用者在將主鏈的資產(如以太幣或者其它 ERC20 合約釋出的 token)轉移到 Plasma Chain 的過程稱為存款(Deposit),具體做法是直接向主鏈上的 Plasma 合約傳送以太幣或 token。Plasma 合約收到 Deposit 交易後會在子鏈上建立跟 Deposit 數額一致的交易,並將其打包進區塊中,作為存款確認的證明。這個過程如下圖所示(來源自[[1]]。
當使用者看到子鏈上自己之前存款的交易被確認後,就可以在子鏈上使用這筆資產(給子鏈上的其他使用者傳送交易或者退出子鏈等)。
狀態確認(State Commitment)
當大部分都轉移到鏈下進行時,需要某種機制確保鏈下狀態的更新得到確認,這樣才能保證當有惡意行為發生時,主鏈可以保證使用者不會受到損失。這就是為什麼需要狀態確認(State Commitment),即子鏈週期性地將狀態更新情況提交到主鏈進行共識。
然而,將子鏈中的所有交易都同步到主鏈顯然違反了 Plasma 的初衷,在 Plasma 中,實際向主鏈提交的是 Merkle Tree 的根雜湊。因此子鏈中的實際交易情況被隱藏,在主鏈上只能看到子鏈區塊的雜湊值。
當有惡意行為發生時,子鏈網路中的所有使用者都可以向主鏈提交防偽證明,證明成立後,含有惡意交易的區塊將被回滾。
防偽證明(Fraud Proof)
Plasma 的一個關鍵設計之一就是允許使用者構造防偽證明(Fraud Proof)。防偽證明的意義在於只要釋出區塊的節點構造了含有惡意交易的區塊,那麼就要承擔被懲罰的風險。每當新的區塊被提交到主鏈上時,會留出一段時間給使用者提交防偽證明,如果在這段時間內沒有證明被提交,則認為新的區塊被驗證合法。如果有防偽證明檢測到區塊中存在惡意交易,則該區塊將被捨棄,回滾到上一個被驗證合法的區塊。Plasma 中的防偽證明主要有以下(但不限於)幾種:
- 資產可花費證明
- 交易簽名有效性證明
- 存取款證明
至於每種防偽證明的具體形式,則依賴於實際 Plasma 應用的實現細則。
如下圖所示(來源自[1]),子鏈中每個節點都存有 1-4 個區塊的資料。假設區塊 1-3 已經被驗證合法,而區塊 4 中存在惡意交易,那麼每個節點都可以使用 1-4 個區塊中的資料構造防偽證明提交到主鏈,主鏈驗證後將子鏈中的狀態回滾到區塊 1-3。
防偽證明還可以使用零知識證明(zk-SNARKs 或者 STARKs)來構造,但由於目前通過零知識證明生成證明的時間和空間還有待優化,目前設計的 Plasma 並不依賴零知識證明。零知識證明在 Plasma 中的應用是一個很有前景的研究方向,感興趣的讀者可以參考以太坊研究團隊關於這方面的研究[2])。
取款(Withdrawal)
取款(Withdrawal),顧名思義,就是從子鏈中的資產取回到主鏈上,因此取款也被稱為退出(Exit)。取款操作可以說是 Plasma 框架中最重要的一步,因為它確保使用者可以安全地將子鏈上的資產轉移到主鏈上。之前的存款以及狀態確認步驟已經產生了一些交易資料,並在主鏈上得到同步,使用者可以利用這些資料構造資產證明,之後執行簡單取款(Simple Withdrawal)操作退出子鏈。當有扣留(Withholding)攻擊發生(即子鏈上的礦工惡意扣留區塊,意圖雙花攻擊等)時,使用者可能無法成功獲取資料構造資產證明,這時需要執行批量取款(Mass Withdrawal)操作退出子鏈。
需要注意的是,當子鏈中有取款操作發生時,跟這個取款操作相關的賬號或者交易都將被禁止。
簡單取款(Simple Withdrawal)
執行簡單取款的條件是所要取回的資產已經在主鏈和子鏈上確認。
一個簡單取款的執行主要有以下幾個步驟:
- 向主鏈上的 Plasma 智慧合約傳送已簽名的取款交易。取款的數額可以包含多個輸出(UTXO模型),但所有輸出必須在同一個子鏈當中,而且每個輸出的餘額必須全部取出,不能只取出一部分。取款數額的一部分還需要被當作押金,作為惡意行為的懲罰。
- 當取款請求傳送後,需要等待一段“爭議期(Challenge Period)”,這期間其它節點可以構造證據證明該取款中的部分或全部數額已經被花費。如果爭議期內有節點提供證明成功,那麼取款被取消,而且押金被扣除。
- 接下來可能還要等待一段時間,直到所有區塊高度較低的取款操作都完成。這是為了保證所有取款操作按照“先來後到”的順序執行。
- 當爭議期結束後,如果沒有爭議被提出,則認為取款操作成立,取款者將子鏈資產成功取回到主鏈。
快速取款(Fast Withdrawal)
快速取款(Fast Withdrawal)跟簡單取款相比的差別主要是引入一箇中間人,白皮書上稱為 Liquidity Provider,這裡簡稱為 LP。如果一個使用者不想等待很長的爭議期(目前的實現至少要一週),那麼它可以選擇從 LP 這裡直接取款,只需要消耗一個交易確認的時間,代價是需要支付給 LP 一定的費用。由於 Plasma 白皮書上關於快速取款的描述太過晦澀,這裡主要參考 kfichter 提出的 Simple Fast Withdrawal[3] 來介紹快速取款是如何實現的。
為了實現快速取款,取款方和 LP 可以利用一個流動合約(liquidity contract)。假設取款方是 Alice,她想要執行快速取款將 10 以太幣從子鏈轉移到主鏈。她首先向流動合約傳送 10 以太幣,注意這裡的交易是在子鏈上進行的。當這個交易被子鏈打包成區塊後,Alice 可以呼叫合約中的某個退出函式,這時 Alice 將獲取一個代表她這筆資產的 token。Bob 作為 LP,他檢查了子鏈上資料之後證明 Alice 的取款沒有問題之後願意以 9 以太幣的價格購買這個 token。Alice 將 token 賣給 Bob,獲得了 9 以太幣,Bob 賺取了 1 以太幣。
需要注意的是,實現快速取款的前提條件是沒有拜占庭行為發生,即沒有扣留區塊攻擊發生,因為 LP 需要驗證取款方的交易歷史。
批量取款(Mass Withdrawal)
當子鏈中有拜占庭行為(例如,區塊扣留攻擊)發生時,將會影響以後生成防偽證明,因此網路中的每個使用者都有責任快速退出子鏈。雖然批量取款(Mass Withdrawal)操作不是必要選擇,但當大量使用者執行取款時很可能會造成主鏈擁塞,也會消耗更多的 gas,因此批量取款是當子鏈受到攻擊時更好的選擇。
批量取款操作由於所採用的模型(UTXO 模型或者賬戶模型)不同會有較大的差別,而且目前關於批量取款的操作細節也正在研討當中,因此這裡只對批量取款做簡單介紹,想要了解目前研究狀態可以參考[4]。
當子鏈中有拜占庭行為發生時,使用者之間可以共同協作執行批量取款。這時會有一個節點扮演取款處理人(Exit Processor)的角色,簡稱為 EP,負責當前某個批量操作(可以同時有多個批量取款操作發生,但同一個取款申請不能存在於多個批量取款),並且可以收取服務費作為報酬。EP 將構造一個點陣圖(bitmap,即一串0/1)記錄哪些資產要執行取款。之後 EP 將利用現有的區塊資料檢查每個取款是否合法,之後將構造一個批量退出初始化交易(Mass Exit Initiation Transaction,MEIT),並將其傳送到主鏈上。在 MEIT 被主鏈確認之前,每個使用者都可以對這個交易提出異議。當爭議期結束,MEIT 被主鏈確認,批量取款成功。
總結
本文主要對 Plasma 框架中一些關鍵操作進行了比較詳細的介紹,但如果不依託於某個實際的 Plasma 專案,對一些細節還是很難理解。因此在後面的文章中將會介紹 Plasma MVP 以及 Plasma Cash。
相關資源
- https://plasma.io/
- https://ethresear.ch/t/plasma-is-plasma/2195
- https://ethresear.ch/t/simple-fast-withdrawals/2128
- https://ethresear.ch/t/basic-mass-exits-for-plasma-mvp/3316
本文的作者是蓋蓋,他的公眾號: chainlab
深入淺出區塊鏈 - 系統學習區塊鏈,打造最好的區塊鏈技術部落格。