区块链 PoS 共识——Tendermint
導言
歡迎查閱 Tendermint 指南!本指南是新手學習 Tendermint 最好的材料
什么是 Tendermint?
Tendermint 是一種能夠為多臺機器安全和保證數據一致性復制應用程序的軟件。從安全性層面看,分布式系統中即使 1/3 的隨機節點即使宕機了,Tendermint 依然能夠保證分布式系統正常運行。另外在數據一致性方面,故障的節點能夠看到相同的事務日志并計算出相同的狀態。安全且保持一致性復制是分布式系統的基本問題, 在很多應用程序中起著關鍵性的作用,比如貨幣系統、選舉和基礎設備編排等系統。
分布式系統需具備容忍節點離線或出錯,也就是拜占庭容錯。拜占庭容錯理論歷史悠久,區塊鏈技術落地成功的案例、比如比特幣、以太坊的成功促使該理論在計算機領域的實現得以流行。區塊鏈技術著重結合對等網絡(P2P) 和密碼認證對拜占庭容錯加以進化。 交易被批量打包成塊,每個塊通過加密哈希連接上一個塊從而形成鏈,這也是把該技術命名為 區塊鏈 (BlockChain) 的原因。
Tendermint 包含兩個組件: 區塊鏈共識引擎 (blockchain consensus engine)、 通用應用接口(generic application interface) 共識引擎被稱為 Tendermint Core ,確保交易記錄在任何一個節點都能一致被排序。通用應用接口被稱為 應用區塊鏈接口 (Application BlockChain Interface) 簡稱為 ABCI , 交易能夠被任何編程語言處理。大部分區塊鏈和共識方案預先打包內置狀態機(比如存儲鍵值對或者通過腳本),而開發者通過 Tendermint 可以對任意編程語言編碼的應用實現 BFT 狀態機復制, 并且開發環境對開發者也很適合。
Tendermint 以易用、易懂、高性能為設計原則,對各種分布式應用程序都有用。
Tendermint 與同類軟件對比
Tendermint 與兩類軟件相似。一類是分布式鍵值對存儲軟件,例如 Zookeeper, etcd, 和 consul, 但他們使用了 non-BFT 共識。 另外一類就是區塊鏈技術。區塊鏈技術包含加密貨幣,例如比特幣和以太坊,還包含非傳統類的分布式賬本,譬如 Hyperledger 的 Burrow
Zookeeper, etcd, consul
Zookeeper, etcd 和 consul 都是典型的鍵值對存儲和 non-BFT 共識算法的實現。Zookeeper 使用 Zookeeper Atomic Broadcast 版本的 Paxos 算法;etcd 和 consul 使用 比較新和簡單的 Raft 共識算法。非拜占庭容錯共識實現的分布式集群中,假設包含 3-5 個節點,可以允許一半的節點離線,但是如果出現一個拜占庭錯誤節點(作惡節點)足以摧毀該分布式系統。
三者都各有特色稍微不同地實現了鍵值對存儲,但都重點圍繞著給分布式系統提供基礎服務,例如動態配置、服務發現、鎖、領導節點選舉 (leader-election)
Tendermint 和上述類型的軟件本質作用差不錯,但有兩個重要的不同點:
- 支持拜占庭容錯算法,意味著智能容忍三分之一以內的節點錯誤,這個錯誤包括任意節點離線和節點作惡
- 獨立于特定類型軟件,例如鍵值存儲類。而 Tendermint 只是關注任意狀態機復制,開發者根據軟件需求業務邏輯,例如通過狀態機復制實現鍵值對存儲、加密貨幣乃至分布式電子投票平臺等分布式應用。
比特幣、以太坊及其他加密貨幣
Tendermint 誕生于傳統的加密貨幣之后。相比于比特幣的工作量證明 (Proof of Work) ,它實現的共識算法更高效和安全。早期的 Tendermint 內置了簡單的數字貨幣并實現了共識功能。 節點需要繳納保證金,如果作惡保證金就會被沒收。Tendermint 實際上也是一種股權證明 (Proof of stake)
加入可股權證明算法之后,Tendermint 演變為區塊鏈共識引擎,允許任何機器都可以加入作為節點的分布式系統。這也意味這 Tendermint 可以作為其他區塊鏈項目即插可用的共識引擎, 替換原有的共識模塊。也就是說,舉個例子你可以使用 Tendermint 共識運行任何語言實現的以太坊節點源碼作為 ABCI 應用(上文提到,最終實現了一種基于股權證明共識以太坊。 事實上,我們基于以太坊實現了上述的 demo
the Cosmos network 共識算法就是內置了 Tendermint
其他區塊鏈項目
Fabric 采用了與 Tendermint 相似的方法,但是它更偏向于如何管理狀態,并要求所有的應用行為能夠運行在 docker 容器中,我理解 Fabric 的 chaincode 就像以太坊的智能合約。它基于 PBFT 實現。在 Tendermint 中,可以把這種基于容器的行為作為 ABCI 應用。
Burrow 實現了以太坊虛擬機和交易機制,并擴展了名字注冊 (name-registery),許可權限、原生合約提供多種方式調用區塊鏈接口 (REST 和 JSON-RPC)。 它使用 Tendermint 作為共識引擎,提供的特殊的應用狀態(這里的狀態由賬戶、驗證人集合、和名字注冊)
ABCI 概述
通用區塊鏈接口 ABCI 允許任意類型編程語言編寫的拜占庭容錯復制類的應用程序。
初衷
迄今為止,實現區塊鏈的源碼都是一個巨大的應用(譯者注:這里的說法有點絕對,17 年國內有一家公司開源的 CITA 代碼把區塊鏈各個功能模塊拆分單獨部署),也就是一個應用包含了所有的功能模塊,包含 P2P 網絡,"mempool" 廣播交易,共識模塊,賬戶余額,圖靈完備的合約模塊和用戶用戶權限模塊等。
CITA將單個節點按照功解構為交易共識、合約引擎、鏈 式存儲、網絡同步、服務網關等多個松耦合的微服務,一方面利用云計算基礎設 施來按需提升性能,另一方面,各個組件可獨立替換升級。一個軟件代碼過于龐大會導致組件復用和維護過于復雜,特別是當代碼模塊封裝不夠好的情況下更糟糕;
另外會限制大一統架構會限制編程語言的使用,譬如在以太坊中,它支持圖靈完備的字節碼虛擬機,它限制開發者必須要可以編譯為那種類型字節碼的語言,當前只有 Serpent 和 Solidity 滿足。
所以,基于上述兩種缺陷,Tendermint 從特定區塊鏈應用(例如 Bitcoin-core 和 go-ethereum) 的把共識引擎和 P2P 網絡分離。區塊鏈應用的細節抽象為一個接口,并通過 socket 協議實現。
所以就有了接口的概念,通用區塊鏈接口 (ABCI) , 和實現接口的 Tendermint Socket Protocol (簡稱為: TSP 或 Teaspoon)
ABCI 介紹
Tendermint Core 也就是共識引擎,通過 一種滿足 ABCI 規范的 socket 協議和應用通信。
用比特幣作為例子,比特幣加密貨幣區塊鏈中每個節點都維護一份公鏈完整的所有未交易輸出數據庫。如果想要在 ABCI 上實現一個比特幣類(Bitcoin-like)的系統,Tendermint 將會負責:
- 在節點間共享區塊和交易
- 給所有交易建立一個規范且不可篡改的順序
而區塊鏈應用 (也就是 bitcoin-coer) 負責:
- 維護 UTXO 數據庫
- 驗證交易的加密簽名
- 阻止交易花費尚未存在的交易
- 允許客戶端查詢 UTXO 數據庫
Tendermint 在應用(例如 Bitcoin-core) 進程和共識進程之間提供簡單的接口(例如 ABCI),以此分解龐大的區塊鏈應用軟件。
ABCI 由三種主要的消息類型組成,這些消息類型從 Tendermint-core 發往區塊鏈應用(例如 bitcoin-core),應用會對消息作出對應的響應。
消息的詳細說明可查閱:ABCI Message Types
DeliverTx 是應用中的很重要組成部分,它會傳遞鏈中的每筆交易。應用(例如 Bitcoin-core)需根據當前狀態,應用程序協議和交易的加密憑證來驗證來自 DeliverTx 消息傳遞過來的每筆交易。 每筆被驗證通過的交易然后更新應用的狀態,例如存儲交易鍵值對,或更新 UTXO 數據庫。
CheckTx 消息和 DeliverTx 類型相似,但它只是驗證交易的有效性。Tendermint Core mempool 首先通過 CheckTx 檢測交易的有效性,然后將有效的交易轉發給它的節點。例如,一個應用的驗證規則為檢測交易的遞增序列號,如果序列號是舊的,則 CheckTx 返回錯誤。
Commit 消息用以給當前應用狀態計算加密保證 (cryptographic commitment),加密保證被放入下一個區塊頭。節點狀態更新不一致表明鏈出現分叉。加密保證同時簡化了安全的輕節點客戶端開發,因為 Merkle-hash 證明可以通過檢測區塊哈希去驗證是否正確,而區塊已被 quorum 簽名。
多個 ABCI socket 可以連接到同一個應用上,Tendermint Core 新建三個 ABCI 連接應用:一個用以驗證被廣播到 mempool 中的交易;另一用以共識引擎去運行新區塊提議;最后一個 socket 連接被用于查詢應用狀態。
顯然在開發區塊鏈底層鏈時,開發者要對消息處理需十分嚴謹。但是 Tendermint 的 ABCI 的三種消息模型架構給消息處理提供了很不錯的范例。下圖展示了 ABCI 的消息流:
關于確定性的說明
區塊鏈處理交易的邏輯必須是確定的,否則 Tendermint Core 復制的節點之間將不會達成共識。
在以太坊平臺選用 Solidity 開發區塊鏈應用是很好的選擇,除其他因素外,它是一個完全確定的編程語言(也就是在各種環境下輸出都一樣,與之相反的例子就是普通編程語言多線程競爭問題導致輸出不確定),然而通過普通的編程語言如果知遵循規范話(譬如避免線程競爭), 也是可以做到在各種條件下同一輸入會得到確定的輸出。游戲程序員和區塊鏈開發者對在不確定的的情況情景下開發最終確定的程序比較熟悉,例如:
- 生成隨機數 (使用確定的種子)
- 線程競爭條件(避免多線程)
- 系統時鐘
- 未初始化的內存 (in unsafe programming languages like C or C++)
- 浮點數計算
- 隨機的語言特性(例如 Go 中迭代 Map 也是隨機的)
謹慎編碼可以避免寫出不確定輸出的代碼,同時創造特殊的語法檢測器或靜態分析器檢測確定性也是行得通的。將來我們團隊可能會開發這樣的工具。
共識概述
Tendermint 是一種易懂,大部分都是異步和拜占庭容錯的共識協議。它遵循的的一個簡單的狀態機,如下圖所示:
協議中的角色稱謂 驗證人 ;他們輪流對交易的區塊提議并對提議的區塊投票。區塊被提交到鏈上,且每個區塊就是一個區塊高度。但是區塊也有可能不被提交到鏈上,面臨這種情況時,協議將繼續下一輪對區塊提議和投票, 有權提議新塊的驗證人可以為當前區塊高度選擇區塊并對其投票,然后剩下的認證人投票,超過 2/3 的驗證人對同一個塊投票即可提交該區塊。驗證人對一個提議的區塊進行預投票和預提交 當超過 2/3 的驗證人在同一輪提議中對同一個塊投票,那么這個區塊才會被提交。
[這段在扯淡,不翻譯]
驗證人面臨當前的提議者離線或者網絡延遲,則會出現提交區塊失敗的情況。Tendermint 允許驗證人確認出現故障的驗證人可以被忽略。在進行下一輪投票之前,所有驗證人等待一小段時間接收提議者完成對塊的提議。驗證人依賴超時才進行下一輪操作體現了 Tendermint 是部分同步的協議, 而非全異步協議。完成對區塊提議之后,協議剩下的部分是完全是異步的,驗證人只要接收到超過 2/3 的驗證人集時就放棄當前一輪投票,執行下一步操作。Tendermint 足以簡單是因為提交區塊也使用了上述的機制,當超過三分之二的節點成功對提議的區塊投票時就表示區塊已經被提交, 剩下的馬上轉入下一個區塊的提議和投票。
假設少于三分之一的驗證有主觀惡意,Tendermint 就能保證共識算法就能保證系統安全。也就是說,多個驗證人永遠不會在同一高度提交區塊造成區塊沖突。Tendermint 確保系統安全是通過引入 鎖定 規則,一旦驗證者預提交了一個區塊,那么該驗證人就會被鎖定在這個區塊。然后:
Stake
在很多系統中,并不是所有的驗證人都在共識協議中有中同樣的投票權重。因此我們對 1/3 或 2/3 的驗證人并不十分感興趣,而是關心所有投票的占比,這個比例對于單個驗證人并不是均勻分布的,在數字貨幣系統中,可以依據幣量和幣齡分配投票權重。
因為 Tendermint 可以使用現有的區塊鏈項目作為 ABCI ,所以可以給基于 Tendermint 實現的系統定義一套數字貨幣,然后根據各個節點持有的幣量(根據持有幣的數量或者持幣的幣齡也可,在這需根據業務來定)計算節點的投票權重。 當投票權是基于節點持有的數字貨幣作為依據,那么這樣的系統就成稱為股權證明 (Proof of stake)。節點通過把持有的幣作為保證金之后就成為驗證人,如果作惡,這筆保證金就會被銷毀。 這就給協議的安全性加了經濟的因素,就像比特幣系統中的工作量證明依賴礦機算力一樣,增強了區塊鏈網絡的安全性,同時也可量化違反共識的成本,想要控制股權證明的分布式區塊鏈網絡,必須控制超過全網超過 2/3 的投票權重。
Cosmos Network 內置了加密貨幣的 ABCI 應用,使用股權證明機制
https://zhuanlan.zhihu.com/p/31667159
總結
以上是生活随笔為你收集整理的区块链 PoS 共识——Tendermint的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Proof-of-Stake (POS)
- 下一篇: Python之区块链入门,揭秘比特币