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