Polkadot 中繼鏈提供了有效性驗證與可用性保障來實現與平行鏈安全共享。

原文標題:《Polkadot 系列(三)——如何實現共享安全性》
撰文:周蓉、江哲,均就職於趣鏈科技

說到 Polkadot,估計大家聽到它的最大的優點就是它給平行鏈提供的共享安全性,共享安全性保障了不因區塊鏈網絡分片而降低安全性。那麼共享安全性到底是如何實現的呢?

本文主要從 Polkadot 爲平行鏈提供的的有效性和可用性兩個保障幫你深度理解共享安全性。

回顧

首先還是先來回顧一下前文提及過的 Polkadot 四種角色:

驗證人(Validators)

它是中繼鏈全節點,中繼鏈會在驗證人池中通過隨機分組把驗證人指定給不同的平行鏈。驗證人會接受來自收集人打包的區塊並進行有效性驗證,然後結合共識算法對收集人提交的區塊進行確認。

收集人(Collators)

它是平行鏈的全節點,負責收集和執行平行鏈的交易併產生候選區塊,將區塊和證明提交給驗證人,並通過收集交易獲得手續費。收集人類似於 PoW 共識區塊鏈當中的礦工。

提名人(Nominators)

Polkadot 中數字貨幣 DOT 的持有人,它會選擇自己所信任的驗證人進行 DOT 質押,然後分享驗證人的收益。

釣魚人(Fishermen)

它也是平行鏈全節點,監控驗證人的非法行爲,若驗證人作惡(如批准了無效的平行鏈區塊),釣魚者可以向其他驗證人舉報並獲得相應報。

有效性驗證

有效性驗證指的是區塊鏈系統對賬本狀態變更的合法性校驗,實現全網的共識。

一條普通的區塊鏈,比如以太坊,每出一個區塊,區塊會廣播到全網的以太坊節點,這些節點會對區塊中的交易進行驗證和執行,確保最後生成的狀態根等信息和區塊頭中的信息一致。在 Polkadot 中,對平行鏈的區塊共識需要進行以下三個級別的有效性驗證:

第一級有效性驗證由平行鏈的驗證人實現,可以防止收集人作惡。

每隔一段時間(具體間隔時間由 BABE 共識算法確定),中繼鏈會通過隨機分組把驗證人池中的驗證人指定給不同的平行鏈,每個平行鏈會分配到多個驗證人。

平行鏈區塊上的收集人收集交易,產生區塊 B 以後,將區塊 B、有效性證明和一些相關數據發送給當前平行鏈的驗證人。這些平行鏈的驗證人收到區塊和數據後,驗證區塊,如果區塊無效,忽略該塊;如果區塊有效,則將收到的內容分成多個部分,構造一棵默克爾樹,然後將每一份內容、默克爾證明以及區塊信息組合,進行簽名並分發給其他驗證人驗證。

第二級有效性驗證由釣魚人保證,可以防止平行鏈驗證人作惡以及平行鏈驗證人和收集人聯合作惡。

釣魚人一般都是平行鏈的全節點。它首先需要在中繼鏈上放置押金,然後持續從收集人節點收集區塊,並驗證有效性。如果區塊中包含了無效交易,釣魚人將提交報告。如果事實證明它的判斷是正確的,它將獲得豐厚的獎勵,但如果它判斷錯誤,它將失去自己的押金。

第三級有效性檢查是非平行鏈驗證人執行的。

這些驗證人選擇過程是非公開的,且驗證人數量由釣魚人給出的無效報告和收集人給出的不可用報告的數量確定。如果檢測到無效的平行鏈區塊,則爲其簽名的驗證人將會受到懲罰,它的押金將會部分或全部扣除。

上面三個級別的有效性驗證中,釣魚人的有效性驗證比較好理解,因爲它本身就是平行鏈的全節點,擁有平行鏈的所有狀態數據,只需將收到的區塊交易重新執行一遍,便可以得到新的狀態數據和狀態根來驗證區塊的有效性。

可是驗證人是中繼鏈的全節點,它如何做到能夠驗證平行鏈的區塊呢,難道它維護所有平行鏈的狀態數據?這顯然是不可能的。

下面就重點介紹一下 Polkadot 驗證人到底是如何驗證平行鏈的區塊的。

平行鏈接入 Polkadot 時,需要向中繼鏈註冊一段 web assembly 代碼,叫做 STVF (State Transition Verification Function),驗證人將用 STVF 對平行鏈有效性進行驗證。

假設某個平行鏈 PC 上個已經確認的區塊是 B0,當前待出的區塊是 B1,上個區塊經由中繼鏈確認後,在中繼鏈上區塊 R0B 上記錄了 B0 的相關信息,如該平行鏈執行完 B0 以後的狀態根 R0。之後平行鏈收集人 C 打包了區塊 B1,得到該區塊的向其他平行鏈的跨鏈消息 M,並生成有效性證明π以及一些元數據 (PC.id, H(B0), H(R0B), Rin, Rout, . . .)。這裏的 Rin 是區塊 B1 執行之前的平行鏈的狀態根,Rout 是執行以後的狀態根,H(B0) 表示平行鏈區塊 B0 的哈希,H(R0B) 表示中繼鏈區塊 R0B 的哈希。

生成有效性證明的過程實質就是執行區塊中的交易,將執行過程中讀寫的狀態數據記錄下來,並結合區塊執行前後的兩個狀態根生成證明。

如果使用*xz 表示組成默克爾根 x 中的葉子 z 的 SPV 證明,那麼區塊 B 有效性證明數據就可以如下表示:

πB = U {*Rinx | B reads x } ∪ {*Routx | B writes x }

舉個例子,假設平行鏈提交的區塊 B 中包含兩筆交易:

  1. A 給 B 轉賬 50
  2. C 給 D 轉賬 10

執行過程中需要讀寫 A、B、C、D 四個賬戶的狀態。假設區塊執行之前該平行鏈中這四個賬戶的餘額都是 100,那麼有效性證明包含的便是下面兩張圖中標有顏色的這些數據,其中黃色部分是哈希值。

技術分析 Polkadot 如何爲平行鏈提供共享安全性?

技術分析 Polkadot 如何爲平行鏈提供共享安全性?

可以看到,不管平行鏈本身的狀態數據有多少,由於區塊的有效性證明數據都是由該區塊的交易涉及的狀態讀寫集的 SPV 組成,因此它的大小是有限的。

之後收集人 C 將區塊 B1、交易的有效性證明π、該平行鏈的出隊列中的消息集合 M 以及元數據一起發給其中一個驗證人,驗證人再將這些信息分發給這條平行鏈的其他驗證人。每個驗證人加載該平行鏈的 STVF 對收到的平行鏈區塊進行有效性驗證。

STVF 的核心也是執行平行鏈區塊中的交易,過程中需要讀取證明數據中的讀集合,同時會產生寫集合,並最後生成的寫集合和證明數據中的內容進行比對;此外還可以通過收到的元數據中的信息進行一些其他的驗證,如根據 H(R0B) 查找到該區塊中保存的 B0 的狀態根 R0,將 R0 和收到的 Rin 進行比較。若這些信息都符合,則該區塊通過驗證。

最初收到平行鏈區塊的那個驗證人將生成一個 Candidate Receipt,裏面會記錄該平行鏈區塊 B1 相關的信息,如平行鏈 PC 的 id、收集人 C 的 id、區塊 B1 的哈希、區塊 B1 執行前後的狀態根等,簽名並廣播給中繼鏈所有節點(可以認爲這是中繼鏈的交易)。當這個 Candidate Receipt 最終被中繼鏈出塊確認以後,平行鏈 PC 的區塊 B 也被最終確認了。

這種有效性驗證方法可以保證平行鏈單個區塊的狀態轉換是有效。如果平行鏈從第一個區塊開始,都由中繼鏈進行有效性驗證並確認區塊,那麼可以保證平行鏈整條鏈的有效性。

可用性保障

可用性保障指的是區塊鏈系統在部分節點作惡的情況下,依然可以對業務系統提供可用服務保障。

在 Polkadot 中,假設這麼一種場景:平行鏈收集人打包了區塊 B 並提交給了驗證人,驗證人收到了該區塊,通過了有效性驗證,並且區塊最終被中繼鏈確認了。

但是該收集人節點作惡,沒有把區塊廣播給平行鏈的其他節點,那麼該平行鏈的其他節點無法得到該區塊,無法更新本地的狀態數據,該平行鏈也就無法出塊了。

爲了防止這種情況發生,通過驗證以後,驗證人會將平行鏈區塊 PC 和有效性證明通過糾刪碼技術分成 n 個片段(n 的數量是全網驗證人的數量),並將這些片段廣播給全網的所有驗證人,每個驗證人獲得一個片段並會保存一段時間。

之後只需要得到 n/3 的片段,便可以恢復出原始數據。這種情況下,即使收集人節點作惡,平行鏈其他節點依然可以從中繼鏈的驗證人中獲得上個區塊的糾刪碼片段並恢復出區塊。

技術分析 Polkadot 如何爲平行鏈提供共享安全性?

總結

通過上面對 Polkadot 有效性和可用性的介紹可以看到,中繼鏈提供了種種措施來保障平行鏈的安全:隨機分配的平行鏈驗證人進行區塊的驗證、釣魚人的監督、非平行鏈驗證人的再次驗證、中繼鏈對平行鏈區塊數據的備份……。

這種設計方式在保障整個區塊鏈系統橫向擴容分片的過程中不會降低某單一分片的安全性。對平行鏈來說,它享受了中繼鏈提供的安全性,僅需安心關注自己的區塊鏈業務即可,極大便利了區塊鏈業務的開發,降低了單一平行鏈對安全的額外投入。

參考文獻:

[1] Availability and Validity
https://research.web3.foundation/en/latest/polkadot/Availability_and_Validity.html

[2] The Path of a Parachain Block
https://polkadot.network/the-path-of-a-parachain-block/

[3] J. Burdges, A. Cevallos, P. Czaban, R. Habermeier, S. Hosseini, F. Lama, H. K. Alper, X. Luo, F. Shirazi, A. Stewart, and G. Wood. Overview of polkadot and its design considerations. arXiv preprint arXiv:2005.13456, 2020.

來源鏈接:mp.weixin.qq.com