比特幣被認為是區塊鏈技術 1.0 時代的代表平台,隨著以智能合約為主要特徵的以太坊平台的誕生,區塊鏈技術進入了 2.0 時代,而開源項目 Hyperledger Fabric 平台則標誌著區塊鏈技術 3.0 時代的到來。最新發布的 Fabric v1.4.1(LTS)提出了很多新的設計概念,添加了諸多新的特性,提供了高度模組化和可配置的架構,支持通用編程語言(如 Java、Go 和 Node.js)編寫智能合約,支持可拔插的共識協議,使得基於該平台開發企業級應用得以變為現實,平台的關注度也越來越高。本章將帶領讀者走進 Hyperledger Fabric 的世界,探究基本的運行原理,從而加深對該平台的了解,為後續學習基於 Fabric 的應用開發技術打下基礎。
Hyperledger 項目是致力於推進區塊鏈數字技術和交易驗證的開源項目,目標是讓開源社區成員共同合作,建設開放平台,滿足不同行業的用戶需求,並簡化業務流程。該項目通過創建分佈式賬本的公開標準,以實現虛擬和數字形式的價值交換。
在區塊鏈技術的支撐下,比特幣等 “數字加密貨幣” 成為熱點,它們的活躍用戶數量及交易量與日俱增,發展速度遠遠超出人們的估計。許多創業者、公司和金融機構漸漸意識到了區塊鏈技術的價值,普遍認為它可以有更大的應用前景,而不僅僅局限於 “數字加密貨幣” 領域。
為此,Vitalik 創立了 Ethereum 項目,希冀打造一個圖靈完備的智能合約編程平台,讓區塊鏈愛好者可以更好更簡單地構建開發區塊鏈應用。繼而,市場中湧現出了很多新型區塊鏈應用,比如資產登記、預測市場、身份認證等各類應用。但是,當時的區塊鏈技術自身仍存在著一些無法克服的問題。比如,首先交易效率低下,比特幣整個網絡只能支持每秒 7 筆左右的交易;其次,對於交易的確定性還無法得到很好的保證;最後,達成共識所採用的挖礦機制會造成很大的資源浪費。這些問題導致了當時的區塊鏈技術無法滿足大多數商業應用的需求。
因此,設計並實現一個滿足商業需求的區塊鏈平台成為當時區塊鏈發展的一個關鍵。在社會各界的強烈呼聲中,Linux 基金會開源組織於 2015 年 12 月啟動了名為 Hyperledger 的開源項目,意在通過各方合作,共同打造區塊鏈技術的企業級應用平台,以此來促進跨行業區塊鏈的發展。
Hyperledger 在成立之初,就吸引了很多著名企業加入,如 IBM、思科、Intel 等科技互聯網巨頭,同時富國銀行、摩根大通這類金融行業大鱷也成為第一批加入的成員。它的開發社區目前已經發展到超過 270 個組織。值得一提的是,項目成員中超過 1/4 的成員來自於中國的公司,比如趣鏈科技、小蚁、布比等新創區塊鏈公司,同時也有萬達、華為、招商銀行等知名企業的參與。從成員陣容來看,Hyperledger 開源項目聲勢異常浩大,匯集了眾多的各行各業企業精英,集體進行合作探討解決方案,推進企業級區塊鏈平台的發展。
Hyperledger 項目首次提出和實現完備的成員權限管理、創新的共識算法和可插拔的框架,對區塊鏈相關技術和產業的發展都將產生深遠的影響。實際上這已經說明區塊鏈技術不單純是一個開源技術了,它已經被其他行業的主流機構及市場正式認可。
Hyperledger 項目是一個大型的開源項目,希望通過各方合作,共同促進和推進區塊鏈技術在商業應用方面的發展。在組成結構上,包含了很多相關的具體子項目。這些子項目可以是一個獨立的項目,也可以是與其他項目關聯的項目,比如構建工具、區塊鏈瀏覽器等。Hyperledger 對於子項目的形式並沒有給出太大的約束,只要是有與之相關的好的想法,都可以向 Hyperledger 委員會發出申請提案。
項目官方地址托管在 Linux 基金會網站,代碼托管在 Gerrit 上,並通過 GitHub 提供代碼鏡像。為了更好地管理子項目和發展項目,Hyperledger 項目成立了一個稱為技術指導委員會(Technical Steering Committee,TSC)的機構,這也是 Hyperledger 項目的最高權力機構,子項目的管理以及整個項目生態的發展等重要決定都將由它執行。Hyperledger 項目在管理所屬子項目時採用了一種生命週期的形式,賦予每個項目一個生命週期,方便項目的運行和管理。整個生命週期分為 5 個階段,分別是提案(proposal)階段、孵化(incubation)階段、活躍(active)階段、棄用(deprecated)階段以及最後終止(end of Life)階段。每個項目在開發運行過程中,一個時間點只會對應著一個階段。當然,項目不一定會按照以上階段順序發展,項目可能會一直處於某個階段,也可能會因為一些特殊原因在多個階段之間進行變換。所有的項目需要重視包括交易、合同、一致性、身份、存儲的技術場景在內的模組化設計,還需實現代碼可讀性以保障新功能和模組都可以很容易添加和擴展,並且需要不斷增加和演化新的項目來滿足日益深入的商業化需求和逐漸豐富的應用場景。
Fabric 是一種區塊鏈技術的實現,也是一種基於交易調用和數字事件的分佈式共享賬本技術。比起其他的區塊鏈技術實現,它採用了模組化的架構設計,支持可插拔組件的開發與使用。其總賬上的數據由多方參與節點共同維護,並且一旦被記錄,賬本上的交易信息永遠無法被篡改,並支持通過時間戳進行溯源查詢。對於其他公有鏈而言,Fabric 引入了成員管理服務,因此每個參與者均需要提供對應的證書證明身份才允許訪問 Fabric 系統,同時引入多通道多賬本的設計來增強系統的安全性和私密性。與以太坊相比,Fabric 採用了強大的 Docker 容器技術來運行服務,支持比以太坊更便捷、更強大的智能合約服務,以太坊只能通過提供的 Solidity 語言進行合約編寫,而 Fabric 支持多語言的合約編寫,例如 Go、Java 和 Node.js。除此之外,Fabric 還提供了多語言的 SDK 開發接口,讓開發者可以自由、便捷地使用其所提供的區塊鏈服務。本章後面將會深入分析 Fabric 的架構和運行。
Iroha 是一個受 Fabric 架構啟發而提出的分佈式賬本項目,該項目在 2016 年 10 月 13 日通過技術指導委員會的批准,進入孵化階段,2017 年 5 月 18 日搬出孵化區。它旨在為 C++ 和移動應用開發人員提供 Hyperledger 項目的開發環境。該項目希望用 C++ 實現 Fabric、Sawtooth Lake 和其他潛在區塊鏈項目的可重用組件,並且這些組件可以用 Go 語言進行調用。也就是說,Iroha 是對現有項目的一个補充,其長期的目標是實現一個健全的可重用組件庫,使 Hyperledger 技術項目在運行分佈式賬本時,能自由地選擇並使用這些可重用的元素。
Sawtooth Lake 於 2016 年 4 月 14 日通過 TSC 批准,2017 年 5 月 18 日搬出孵化區,是一個由 Intel 發起的模組化分佈式賬本平台實驗項目,它專為多功能性和可擴展性而設計。Sawtooth Lake 提供了一個構建、部署和運行分佈式賬本的模組化平台,同時支持許可鏈和非許可鏈的部署。它包含了一個新的共識算法 PoET。PoET 與比特幣採用的工作量證明算法一樣,都是按照一定規則隨機選取出一個節點,由該節點來作為區塊的記帳者,而其他節點則負責驗證該區塊和執行結果。不同的是,PoET 不需要消耗大量的算力和能耗,但是需要 CPU 硬件支持 SGX(software guard extensions)特性。由於 PoET 算法的硬件限制,因此目前暫時僅適合在生產環境中使用 PoET 算法。
Blockchain Explorer 項目旨在為 Hyperledger 創建一個用戶友好的 Web 應用程序,用於查詢 Hyperledger 區塊鏈上的信息,包括區塊信息、交易相關數據信息、網絡信息、合約代碼以及分佈式賬本中存儲的相關信息。項目於 2016 年 8 月 11 日通過 TSC 批准,之後項目啟動進入孵化階段。
Cello 項目於 2017 年 1 月 5 日通過 TSC 的批准,進入孵化狀態。Cello 項目致力於提供一種區塊鏈即服務(blockchain as a service,BasS),以此減少手動操縱(創建和銷毀)區塊鏈的工作量。通過 Cello,操作者可以使用儀表盤(dashboard)來簡單地創建和管理區塊鏈,同時用戶(合約代碼開發者)可以通過單個請求立即獲取區塊鏈信息。也就是說,為操作者提供了一個簡易便捷的區塊鏈操作平台。
Hyperledger Fabric 是分佈式賬本技術(DLT)的獨特實現,它可在模組化的區塊鏈架構基礎上提供企業級的網絡安全性、可擴展性、機密性以及高性能。當前 Fabric 的最新版本為 v1.4.1(LTS),相比先前的 v0.6 版本,v1.4 版本針對安全、保密、部署、維護、實際業務場景需求等方面進行了很多改進,例如架構設計上的 Peer 節點的功能分離、多通道的隱私隔離、共識的可插拔實現等,功能上引入了 Raft 崩潰容錯共識服務,改進可維護性和可操作性,加入私有數據支持等,都為 Fabric 提供了更好的服務支持。因此,本書後面關於 Fabric 的內容均將基於 v1.4 版本進行描述。
Hyperledger Fabric v1.4 具有以下特性。
-
身份管理(identity management)。Fabric 區塊鏈是一個許可鏈網絡,因此 Fabric 提供了一個成員服務(member service),用於管理用戶 ID 並對網絡上所有的參與者進行認證。在 Hyperledger Fabric 區塊鏈網絡中,成員之間可以通過身份信息互相識別,但是他們並不知道彼此在做什麼,這就是 Fabric 提供的機密性和隱私性。
-
隱私和保密(privacy and confidentiality)。Hyperledger Fabric 允許競爭的商業組織機構和其他任意對交易信息有隱私和機密需求的團體在相同的許可鏈網絡中共存。其通過通道來限制消息的傳播路徑,為網絡成員提供了交易的隱私性和機密性保護。在通道中的所有數據,包括交易、成員以及通道信息都是不可見的,並且未訂閱該通道的網絡實體都是無法訪問的。
-
高效的性能(efficient processing)。Hyperledger Fabric 按照節點類型分配網絡角色。為了提供更好的網絡並發性和並行性,Fabric 對事務執行、事務排序、事務提交進行了有效的分離。於排序之前執行事務可以使得每個 Peer 節點同時處理多個事務,這種並發執行極大地提高了 Peer 節點的處理效率,加速了交易到共識服務的交付過程。
-
函數式合約代碼編程(chaincode functionality)。合約代碼是通道中交易調用的編碼邏輯,定義了用於更改資產所有權的參數,確保數字資產所有權轉讓的所有交易都遵守相同的規則和要求。
-
模組化設計(modular design)。Hyperledger Fabric 實現的模組化架構可以為網絡設計者提供功能選擇。例如,特定的身份識別、共識和加密算法可以作為可插拔組件插入 Fabric 網絡中,基於此,任何行業或公共領域都可以採用通用的區塊鏈架構,並確保其網絡可跨市場、監管和地理邊界進行互操作。
-
可維護性和可操作性(serviceability and operations)。日誌記錄的改進以及健康檢查機制和運營指標的加入,使得 v1.4 版本在可維護行和可操作性上實現了巨大飛躍。新的 RESTful 運營服務為生產運營商提供三種服務來監控和管理對等節點和共識服務節點運營。第一種服務使用日誌記錄 /logspec 端點,允許操作員動態獲取和設置對等節點和共識服務節點的日誌記錄級別;第二種服務使用健康檢查 /healthz 端點,允許運營商和業務流程容器檢查對等節點和共識服務節點的活躍度和健康情況;第三種服務使用運營指標 /metrics 端點,允許運營商利用 Prometheus 記錄來自對等節點和共識服務節點的運用指標。
-
錨節點
Gossip 協議使用錨節點確保不同組織中的對等節點彼此了解。當提交包含錨節點更新的配置塊時,對等節點能探測到錨節點並能獲知錨節點已知的所有對等節點。由於組織間通過 Gossip 通信,因此通道配置中必須定義至少一個錨節點。每個組織都提供一組錨節點則可實現高可用性和減少冗餘。
-
訪問控制列表
訪問控制列表(ACL)將對特定對等節點資源(如系統合約代碼 APIs 或事務服務)的訪問與策略(指定所需的組織或角色的數量和類型)相關聯。ACL 是通道配置的一部分,可使用標準配置更新機制更新。
-
區塊
區塊包含一組有序的交易,由共識系統創建,由對等節點驗證。在通道中以加密的方式先與前序區塊鏈接,然後連接到後序區塊。第一個區塊被稱為創世區塊。
-
區塊鏈
區塊鏈是一個交易日誌,由交易區塊經過哈希連接結構化得到。對等節點從共識服務收到交易區塊後,基於背書策略和並發衝突,標註區塊的交易為有效或者無效,並將區塊追加到對等節點文件系統的哈希鏈中。
-
智能合約
智能合約是由區塊鏈網絡外部客戶端調用的代碼,可以用於管理世界狀態中鍵值對的訪問和修改,安裝在對等節點上,並在通道上實例化。智能合約也被稱為合約代碼。
-
通道
通道是構建在 Fabric 網絡上的私有區塊鏈,由配置塊定義,保障數據的隔離及隱私性。所有對等節點共享通道中特定的賬本,交易方與賬本的交互必須通過通道的正確性驗證。
-
提交
一個通道中的每個對等節點都會驗證交易區塊的有序性,然後將區塊提交(寫或附加)至該通道上賬本的各個副本。對等節點也會標記交易是否有效。
-
並發控制版本檢查
並發控制版本檢查(CCVC)可以保持通道中的對等節點狀態同步。對等節點並行地執行交易,在交易提交至賬本之前,對等節點會檢查交易在執行期間讀取的數據是否被修改。如若被修改,則引發 CCVC 衝突,該交易就會在賬本中被標記為無效,其值不會更新到狀態數據庫中。
-
配置區塊
包含系統鏈(共識服務)或通道定義成員和策略的配置數據。對某個通道或整個網絡的配置修改(比如,成員離開或加入)將導致生成一個新的配置區塊並追加到適當的鏈上。這個配置區塊會包含創始區塊的內容加上增量。
-
共識
共識用於確認交易的排序以及交易集本身的正確性。
-
意集
在 Raft 共識服務中,同意集是通道上積極參與共識機制的排序節點。如果系統通道上存在其他排序節點,但是不屬於通道的一部分,則這些排序節點不屬於通道的排序集。
-
聯合體
聯合體是區塊鏈網絡上無序組織的集合。這些集合組建並加入通道,且擁有自己的對等節點,雖然區塊鏈網絡可以擁有多個聯合體,但大多數網絡只有一個聯合體。在通道創建時,所有加入通道的組織必須是聯合體的一部分。未在聯合體中定義的組織可能會被添加到現有通道中。
-
世界狀態
世界狀態也被稱為賬本的當前狀態,表示區塊鏈交易日誌中所有 key 的最新值。對等節點將最近處理過的每筆交易對應修改的 value 值更新到账本的世界狀態。由於世界狀態可以直接訪問 key 的最新值,而不是通過遍歷整個交易日誌,所以合約代碼必須先知道 key-value 的世界狀態,然後針對這個世界狀態執行交易提案。
-
動態成員管理
Fabric 支持在不影響整個網絡操作性的情況下,動態添加 / 移除成員、對等節點和共識服務節點。動態成員管理在業務關係調整或因各種原因需添加 / 移除實體時至關重要。
-
創世區塊
創世區塊是初始化區塊鏈網絡或通道的配置區塊,也是區塊鏈上的第一個區塊。
-
Gossip 協議
Gossip 數據傳輸協議有 3 項功能:管理對等節點,發現通道上的成員;通道上的所有對等節點間廣播賬本數據;通道上的所有對等節點間同步賬本數據。
-
賬本
賬本由區塊鏈和世界狀態組成。區塊鏈不可變,一旦將一個區塊添加到鏈中,它就無法更改。而世界狀態是一個數據庫,包含已由區塊鏈中驗證和提交事務集添加、修改或刪除的鍵值集合的當前值。網絡中每個通道都有一個邏輯賬本,實際上,通道中每個對等節點都維護著屬於自己的賬本副本,這些副本通過共識過程與其他對等節點的副本保持一致,邏輯上是單一的,但在一組網絡節點(對等節點和共識服務)中分布著許多相同的副本。術語分佈式賬本技術(DLT)通常與這種賬本相關聯。
-
追隨者
在基於領導者的共識協議(如 Raft)中,追隨者複製由領導者生成的日誌條目的節點。在 Raft 中,追隨者也會收到領導者的 “心跳” 信息,如果領導者在可配置的時間內停止發送這些信息,追隨者將發起領導者選舉,其中一名追隨者會被選為領導者。
-
領導者
在基於領導者的共識協議(如 Raft)中,領導者負責提取新的日誌記錄,將其複製到追隨者共識節點,並且管理記錄何時被認為是已提交。
-
主要對等節點
每個組織可以在它們訂閱的通道上擁有多個對等節點,它們中至少有一個作為主要對等節點,以便代表該組織與網絡共識服務通信。共識服務向通道上主要對等節點提供塊,然後將其分發給同一組織內的其他對等節點。
-
日誌記錄
日誌記錄是 Raft 共識服務中的主要工作單元,從領導者分發給追隨者。這些記錄的完整序列稱為 “日誌”。如果所有成員就記錄及其排序達成一致,則該日誌被認為是一致的。
-
成員服務提供組件
成員服務提供組件(MSP)是指為客戶端節點和對等節點提供證書的系統抽象組件。客戶端節點用證書來認證他們的交易;對等節點用證書認證其交易(背書)。該接口與系統的交易處理組件密切相關,旨在使已定義的成員身份服務組件以這種方式順利插入,而不會修改系統的交易處理組件的核心。
-
成員管理服務
成員管理服務在許可區塊鏈上認證、授權和管理身份。在對等節點和排序服務節點中運行成員管理服務的代理。
-
排序服務或共識服務
將交易排序放入區塊的節點的集合。排序服務獨立於對等節點流程之外,並以先到先得的方式為網絡上所有的通道做交易排序。排序服務支持可插拔實現,目前默認實現了 Solo 和 Kafka。
-
組織
組織也稱為 “成員”,由區塊鏈服務提供商邀請加入區塊鏈網絡。組織通過將其 MSP 添加到網絡加入網絡。組織的交易端點是對等節點,一群組織形成一個聯合體。雖然網絡上的所有組織都是成員,但並非每個組織都會成為聯盟的一部分。
-
節點
維護賬本並運行合約容器來對賬本執行讀寫操作的網絡實體。節點由成員擁有和維護。
-
策略
-
策略是由數字標識(digital identity)的屬性組成的表達式,如 Org.Peer 和 Org2.Peer,用於限制對區塊鏈網絡上資源的訪問。策略可以在引導共識服務或創建通道之前定義,也可以在實例化通道上的合約代碼時指定。
-
私有數據
私有數據是存儲在每一個授權對等節點的私有數據庫中的機密數據,在邏輯上與通道賬本數據分開。對私有數據的訪問僅限於私有數據集上定義的組織。未經授權的組織只能在通道賬本上擁有私有數據的哈希值,作為交易數據的證據。此外,為了進一步保護隱私,私有數據的哈希值通過共識服務而不是私有數據本身傳遞,從而使得私有數據對共識服務節點保密。
-
私有數據集
私有數據集用於管理通道上兩個或多個希望與該通道上其他組織保密的組織,描述了通道上有權存儲私有數據的組織子集,只有這些組織能與私有數據交易。
-
Raft
Raft 是 v1.4.1 新增的功能,基於 Raft 協議 etcd 庫的崩潰容錯(CFT)共識服務實現。Raft 遵循 “領導者和追隨者” 模型。與基於 Kafka 的共識服務相比,Raft 共識服務更容易設置和管理,並且允許組織為分佈式共識服務貢獻節點。
-
Hyperledger 是當前業界較為認可的聯盟鏈實現,作為其最重要的子項目,Fabric 備受關注。從孵化到發展至今,Fabric 的架構設計也在演進過程中逐漸地改進與完善。前面已經對 Fabric 做了基本內容與功能的介紹,接下來將開始深入探索 Fabric,對 Fabric 最新的總體架構進行分析,並通過與過往架構對比的方式探討 Fabric 新架構的特點和優勢。
Fabric 在架構設計上採用了模組化的設計理念,從圖 4.1 所示的整體邏輯架構來看,Fabric 主要由 3 個服務模組部組成,分別是成員服務(membership service)、區塊鏈服務(Blockchain service)和合約代碼服務(Chaincode service)。其中,成員服務提供會員註冊、身份管理和認證服務,使平台訪問更加安全,且有利於權限管理;區塊鏈服務負責節點之間的共識管理、賬本的分佈式計算、P2P 網絡協議的實現以及賬本存儲,作為區塊鏈的核心組成部分,為區塊鏈的主體功能提供底層服務支撐;合約代碼服務則提供一個智能合約的執行引擎,為 Fabric 的合約代碼(智能合約)程序提供部署運行環境。同時在邏輯架構圖中,還能看到事件流(event stream)貫穿三大服務組件間,它的功能是為各個組件的異步通信提供技術支持。在 Fabric 的接口部分,提供了 API、SDK 和 CLI 這 3 種接口,用戶可以用來對 Fabric 進行操作管理。
展示了 Fabric 運行架構。v0.6 版本的結構非常簡單,應用 - 成員管理 - Peer 呈現三角形關係,系統所有的業務功能均由 Peer 節點完成。但是 Peer 節點承擔了太多的業務功能,暴露出了擴展性、可維護性、安全性、業務隔離等方面的諸多問題。因此,在 v1.4 版本中,官方對架構進行了改進和重構,將共識服務部分從 Peer 節點中完全分離出來,獨立形成一個新的節點,提供共識服務和廣播服務。v1.4 版本還引入了通道的概念,實現多通道結構和多鏈網絡,帶來了更為靈活的業務適應性。同時還支持更強的配置功能和策略管理功能,進一步增強系統的靈活性。
運行時架構(v1.4)
相比 v0.6 版本,新的架構使得系統在很多方面有很大的提升,主要有以下幾大優勢。
-
合約代碼信任的靈活性(chaincode trust flexibility)。v1.4 版本從架構上,將合約代碼的信任假設(trust assumptions)與共識服務(ordering service)的信任假設進行了分離。新版本的共識服務可以由一組單獨的節點(orderer)來提供,甚至允許出現一些失效節點或惡意節點。而對於合約代碼程序而言,它可以指定不同的背書節點,這極大地增強了合約代碼的靈活性。
-
可擴展性(scalability)。在新的架構下,負責為指定合約代碼背書的背書節點與共識節點是一種正交的關係,所以相比 v0.6 架構的所有業務功能都在 Peer 節點上執行,v1.4 版本架構的擴展性有了很大的提升。尤其是當不同的合約代碼所指定的背書節點不存在交集時,系統可以同時進行多個合約代碼程序的背書操作,這很好地提高了系統處理的效率。
-
機密性(confidentiality)。Mutichannel 的設計使得對內容和執行狀態更新有機密性需求的合約代碼的部署變得容易了。同時增加了對私有數據的支持,並且正在開發的零知識證明(ZKP)將在未來可用。
-
共識模組性(consensus modularity)。v1.4 架構將共識服務從 Peer 節點分離出來獨自成為共識節點,共識服務被設計為可插拔的模組化組件,允許不同共識算法的實現來應用於複雜多樣的商業場景。
成員服務可以為 Fabric 的參與者提供網絡上的身份管理、隱私性、保密性和認證服務。下面重點介紹 PKI 體系的相關內容及用戶的註冊過程。
-
PKI 體系
PKI(public key infrastructure,公鑰基礎設施)的目標就是實現不同成員在不見面的情況下進行安全通信,Fabric 當前採用的模型是基於可信的第三方機構,也就是證書頒發機構(certification authority,CA)簽發的證書。CA 會在確認申請者的身份後簽發證書,同時會在線提供其所簽發證書的最新吊銷信息,這樣使用者就可以驗證證書是否仍然有效。證書是一個包含公鑰、申請者相關信息以及數字簽名的文件。數字簽名保證了證書中的內容不能被任何攻擊者篡改,而且驗證算法可以發現任何偽造的數字簽名。這樣公鑰和身份被捆綁在一起,不能篡改,也不能偽造,就可以實現成員管理。
成員服務將 PKI 體系和去中心化共識協議結合在一起,將非許可區塊鏈轉變為了一個許可區塊鏈。在非許可區塊鏈中,實體不需要經過授權,網絡中的所有節點並不存在角色區別,都是統一的對等實體,都擁有平等提交交易及記帳的權利。而在許可區塊鏈中,實體需要註冊來獲取長期的身份證書(例如註冊證書),這個身份證書可以根據實體類型來進行區分。對於用戶而言,在註冊時,交易證書頒發機構(transaction certificate authority,TCA)會給註冊的用戶頒發一個匿名的證書;而對於交易來說,需要提交的交易需通過交易證書的認證,並且交易證書會一直存儲於區塊鏈上以供認證服務追溯交易使用。實際上,成員服務是一個認證中心,負責為用戶提供證書認證和權限管理的功能,對區塊鏈網絡中的節點和交易進行管理和認證。
在 Fabric 的系統實現中,成員服務由幾個基本實體組成,它們互相協作來管理網絡上用戶的身份和隱私。這些實體有的負責驗證用戶的身份,有的負責在系統中為用戶註冊身份,有的為用戶在進入網絡或者調用交易時提供所需的證書憑據。PKI 是一個基於公鑰加密的框架體系,它不僅可以確保網絡上的數據安全交換,而且還可以用來確認管理對方的身份。同時在 Fabric 系統中,PKI 還被運用于管理密鑰和數字證書的生成、分發以及撤銷。
通常情況下,PKI 體系包含證書頒布機構(CA)、註冊機構(RA)、證書數據庫和證書存儲實體。其中,RA 是一個信任實體,它負責對用戶進行身份驗證以及對數據、證書或者其他用於支持用戶請求的材料進行合法性審查,同時還負責創建註冊所需的註冊憑證。CA 則會根據 RA 的建議,給指定用戶頒發數字證書,這些證書由根 CA 直接或分層進行認證。
對圖中的實體進行進一步介紹說明。
-
Root Certificate Authority:根 CA,代表 PKI 體系中信任的實體,同時也是 PKI 體系結構中的最頂層認證機構。
-
Enrollment CA(ECA):在驗證用戶提供的註冊憑證後,ECA 負責發出註冊證書(ECerts)。
-
Transaction CA(TCA):在驗證用戶提供的註冊憑證後,TCA 負責發出交易證書(TCerts)。
-
TLS CA:負責頒發 TLS(transport layer security,傳輸層安全協議)證書和憑據,以允許用戶使用其網路。
-
ECerts(enrollment certificates):ECerts 是長期證書,針對所有角色頒發。
-
TCerts(transaction certificates):TCerts 是每個交易的短期證書,由 TCA 根據授權的用戶請求頒發。用戶可以配置 TCerts 為不攜帶用戶身份的信息從而匿名地參與系統,還可以防止事務的可鏈接性。
-
TLS-Certs(TLS-Certificates):TLS-Certs 攜帶其所有者的身份,用於系統和組件之間進行通信以及維護網絡級安全。
-
CodeSignerCerts(Code Signer Certificates):負責對軟件代碼進行數字簽名,標識軟件來源及軟件開發者的真實身份,以此保證代碼在簽名之後不被惡意篡改。
金融 IC 卡系統中也使用了 PKI 體系,它的架構如圖 4.5 所示。與 Fabric 的 PKI 體系相比,它沒有 TCert,每次交易都是使用 ECert 完成的,所以這個系統中的交易是沒有匿名的。
前面介紹了成員服務的 PKI 體系的實體及其基本功能,接下來針對具體的用戶註冊流程做一個簡單的介紹。圖展示了一個用戶登記流程的高層描述,它分為兩個階段:離線過程與在線過程。
用戶註冊過程
-
離線過程
(1) 每個用戶或者 Peer 節點必須向 RA 註冊機構提供身份證件(ID 證明),同時這個流程必須通過帶外數據(out-of-band,OOB)進行傳輸,以提供 RA 為用戶創建(和存儲)賬戶所需的證據。
(2) RA 註冊機構返回用戶有關的用戶名和密碼,以及信任錨(包含 TLS-CA Cert)。如果用戶可以訪問本地客戶端,那麼客戶端可以將 TLS-CA 證書作為信任錨的一種方式。
-
在線過程
(1) 用戶連接客戶端以請求登錄系統,在這一過程中,用戶將用戶名和密碼發送給客戶端。
(2) 用戶端代表用戶向成員服務發送請求,成員服務接受請求。
(3) 成員服務將包含幾個證書的包發送給客戶端。
(4) 一旦客戶端驗證完成所有的加密材料是正確有效的,它就會將證書存儲於本地數據庫中並通知用戶,至此,用戶註冊完成。
區塊鏈服務包含 4 個模組:共識管理、分佈式賬本、賬本存儲以及 P2P 網絡協議。共識管理用於在多個節點的分佈式複雜網絡中使消息達成共識,分佈式賬本與賬本存儲負責區塊鏈系統中所有的數據存儲,比如交易信息、世界狀態、私有數據等。而 P2P 網絡協議則是網絡中節點的通信方式,負責 Fabric 中各節點間的通信與交互。
-
P2P 網絡
P2P 網絡這種分佈式應用架構是對等計算模型在應用層形成的一種組網或網絡形式,用於對等實體間分配任務和工作負載。彼此連接的多台計算機在 P2P 網絡環境中處於對等地位,有相同的功能,不分主從。一台計算機可作為服務器,設定供網絡中其他計算機使用的共享資源,又可以作為工作站來請求服務。一般來說,整個網絡不依賴專用的集中服務器,也沒有專用的工作站。而區塊鏈所處的分佈式環境中,各個節點間本應該是平等的,天然適合 P2P 網絡協議。
在 Fabric 的網絡環境中,節點是區塊鏈的通信實體。存在 3 類不同的節點,分別是客戶端節點(Client)、Peer 節點(Peer)以及共識服務節點(Ordering Service Node 或者 Orderer)。
客戶端節點代表著終端用戶實體。它必須連接到 Peer 節點後才可以與區塊鏈進行通信交互。同時客戶端節點可以根據它自己的選擇連接到任意的 Peer 節點上,創建交易和調用交易。在實際系統運行環境中,客戶端負責與 Peer 節點通信提交實際交易調用,與共識服務通信請求廣播交易的任務。
Peer 節點負責與共識服務節點通信來進行世界狀態的維護和更新。它們會收到共識服務廣播的消息,以區塊的形式接收排序好的交易信息,然後更新和維護本地的世界狀態與賬本。與此同時,Peer 節點可以額外地擔任背書節點的角色,負責為交易背書。背書節點的特殊功能是針對特定的交易設置的,在它提交前對其進行背書操作。每個合約代碼程序都可以指定一個包含多個背書節點集合的背書策略。這個策略將定義一個有效的交易背書(通常情況下是背書節點簽名的集合)的充要條件。需要注意的是,存在一個特殊情況,在安裝新的合約代碼的部署交易中,(部署)背書策略是由一個系統合約代碼的背書策略指定的,而不能自己指定。
共識服務節點 Orderer 是共識服務的組成部分。共識服務可以看作一個提供交付保證的通信組織。共識服務節點的職責就是對交易進行排序,確保最後所有的交易以同樣的序列輸出,並提供送達保證服務的廣播通信服務。關於共識服務。
節點的類型,再來看看網絡的拓撲結構。在 v0.6 版本中,整個網絡由兩類節點構成:VP(validating Peer)驗證節點和 NVP 非驗證節點。如圖所示,網絡中包含了 4 個驗證節點,並且每個節點還連接著 2 個非驗證節點,整個網絡的共識則由 4 個驗證節點構成。在 v1.4 版本中,網絡拓撲結構隨著網絡節點類型的變化也發生了很大的改變,其中共識服務節點一起組成共識服務,將共識服務抽離出來,而 Peer 節點中可以分為背書節點或者提交 Peer 節點,並且它們還可以進行分組,然後整個共識服務與 Peer 節點所構成的組一起形成新的完成網絡。
在 v1.0 之後的版本中,Fabric 引入了新的通道概念,共識服務上的消息傳遞支持多通道,使得 Peer 節點可以基於應用訪問控制策略來訂閱任意數量的通道。Peer 節點的子集可以被應用程序指定架設相關通道,指定相同通道的 Peer 節點組成集合,提交該通道的交易,而且只有這些 Peer 節點可以接收相關交易區塊,與其他交易完全隔離。Fabric 支持多鏈與多通道,即系統中可以存在多個通道以及多條鏈,如圖所示。應用根據業務邏輯決定將每個交易發送到指定的一个或多個通道,不同通道上的交易不會存在任何聯繫。
-
從 v1.2 開始,Fabric 能夠在賬本中創建私有數據集,允許通道上組織的子集能夠認可、提交或查詢私有數據,不用創建單獨的通道就能實現通道上的一組組織的數據向其他組織保密的功能。實際的私有數據存儲在授權組織的對等節點上的私有狀態數據庫中(有時候被稱為 side 數據庫或 SideDB),能被授權節點上的合約代碼通過 Gossip 協議訪問。共識服務不涉及其中也無法看到私有數據。由於 Gossip 協議在授權組織中對等分發私有數據,這需要在通道中建立錨節點,並在每個節點上配置 CORE_PEER_GOSSIP_EXTERNALENDPOINT,以便引導跨組織通信。私有數據的哈希值能夠被認可、排序並寫入通道上每個對等方的賬本中,可作為交易的證據,用於狀態驗證,還可用於審計。
總的來說,Fabric 在節點和網絡方面的一些重構和新特性使得 Fabric 的交易處理能力有了增強,而且很好地實現了隱私隔離。
-
共識服務
網絡中的 Orderer 節點聚集在一起形成了共識服務。它可以看作一個提供交付保證的通信組織。共識服務為客戶端和 Peer 節點提供了一個共享的通信通道,還為包含交易的消息提供了廣播服務的功能。客戶端連接到通道後,可以通過共識服務廣播消息將消息發送給所有的 Peer 節點。共識服務可以為所有消息提供原子交付保證,也就是說,在 Fabric 中共識服務保證了消息通信是序列化和可靠的。換句話說,共識服務輸出給所有連接在通道上的 Peer 節點相同的消息,並且輸出的邏輯順序也是相同的。
共識服務可以有不同的實現方式,在 v1.4 版本中,Fabric 將共識服務設計成了可插拔模組,可以根據不同的應用場景配置不同的共識選項。目前,Fabric 提供了 3 種模式實現:Solo、Kafka 和 Raft。
Solo 是一種部署在單個節點上的簡單時序服務,主要用於開發測試,它只支持單鏈和單通道。Kafka 是一種支持多通道分區的集群共識服務,可以支持 CFT(crash faluts tolerance)。它容忍部分節點宕機失效,但是不能容忍惡意節點。其基本實現基於 Zookeeper 服務,使用的分佈式環境中要求總節點數與失效節點數滿足n≥2f+1。Raft 遵循 “領導者和追隨者” 模型,每個通道都選舉一個 “領導者”,它的決定將被複製給 “追隨者”,支持 CFT。只要總節點數與失效節點數滿足n≥2f+1,它就允許包括領導者在內的部分節點宕機失效。與基於 Kafka 的共識服務相比,Raft 應該更容易設置和管理,並且它們的設計允許組織為分散的共識服務貢獻節點。
-
區塊鏈技術從其底層構造上分析,可以視為一種共享賬本技術。賬本是區塊鏈的核心組成部分,在區塊鏈的賬本中存儲了所有的歷史交易和狀態改變記錄。在 Fabric 中,每個通道都對應著一個共享賬本,而每個連接在共享賬本上的 Peer 節點,都能參與網絡和查看賬本信息,即它允許網絡中的所有節點參與和查看賬本信息。賬本上的信息是公開共享的,並且在每個 Peer 節點上都維持著一份賬本的副本。圖 4.9 展示了 Fabric 賬本的結構。
共享賬本結構
從圖中可以看出,共享賬本以文件系統的形式存儲於本地。共享賬本由兩部分組成:圖中鏈式結構的 Chain 部分和圖中右邊存儲狀態數據的 State 部分。其中,Chain 部分存儲著所有交易的信息,只可添加查詢,不可刪改。State 部分存儲著交易日誌中所有變量的最新值,因為它表示的是通道中所有變量鍵值對的最新值,所以有時稱為 “世界狀態”。
合約代碼調用執行交易來更改目前的狀態數據,為了使這些合約代碼高效交互,設計將最新的鍵值對數據存儲於狀態數據庫中。默認的狀態數據庫採用的是 Level DB,但是可以通過配置切換到 Couch DB 或者其他數據庫。
合約代碼服務提供了一種安全且輕量級的方式,沙箱驗證節點上的合約代碼執行,提供安全容器服務以及安全的合約代碼註冊服務。其運行環境是一個 “鎖定” 和安全的容器,合約代碼首先會被編譯成一個獨立的應用程序,運行於隔離的 Docker 容器中。在合約代碼部署時,將會自動生成一組帶有簽名的智能合約的 Docker 基礎鏡像。在 Docker 容器中,合約代碼與 Peer 節點的交互過程如圖所示。
步驟如下。
(1) Peer 節點收到客戶端發來的合約代碼執行請求後,通過 gRPC 與合約代碼交互,發送一個合約代碼消息對象給對應的合約代碼。
(2) 合約代碼通過調用Invoke()
方法,執行GetState()
操作和PutState()
操作,向 Peer 節點獲取賬本狀態數據庫和發送賬本預提交狀態數。若要讀取和寫入私有數據,則通過GetPrivateDate()
和PutPrivateDate()
方法。
(3) 合約代碼執行成功後,將輸出結果發送給 Peer 節點,背書節點對輸入和輸出信息進行背書簽名,完成後應答給客戶端。
架構解讀,可以得知合約代碼服務是 Fabric 架構中的核心組成部分,本節將進一步研究合約代碼服務中所運行的合約代碼,介紹如何編寫、部署及調用具體的合約代碼。
合約代碼是區塊鏈上運行的一段代碼,是 Fabric 中智能合約的實現方式。同時在 Fabric 中,合約代碼還是交易生成的唯一來源。共享總賬是由區塊連接而成的一條不斷增長的哈希鏈,而區塊中包含了以 Merkle 樹的數據結構表示的所有的交易信息,可以說交易是區塊鏈上最基礎的實體單元。那么交易又是怎樣產生的呢?交易只能通過合約代碼調用操作而產生,所以合約代碼是 Fabric 的核心組件,也是與共享賬本交互的唯一渠道。
目前,Fabric 支持使用 Java、Go 和 Node.js 語言通過實現接口的方式來編寫合約代碼。按照 Fabric 的設計,位於 /core/chaincode 目錄下的 shim 包是提供合約代碼開發的 SDK,理論上可以獨立使用,但目前或許因為需要調用某些其他依賴模組,還不能很好地獨立出來。
Fabric 中的合約代碼運行在 Peer 節點上,並且與合約代碼相關的操作諸如部署、安裝、調用等也都是在 Peer 節點上進行的。合約代碼通過 SDK 或者 CLI 在 Fabric 網絡的 Peer 節點上進行安裝和初始化,使用戶與 Fabric 網絡的共享賬本之間的交互成為可能。目前,合約代碼的節點運行模式有兩種:
一般模式和開發模式。
一般模式是系統默認模式,合約代碼運行於 Docker 容器中。運用 Docker 容器來運行 Fabric 系統,這樣就給 Fabric 系統和合約代碼的運行提供了一個隔離的環境,可以提高整個系統的安全性。但是在這種模式下,對於開發人員而言,開發調試過程非常複雜和麻煩,因為每次修改代碼之後都需要重新啟動 Docker 容器,這會極大地降低程序開發的效率。
因此,考慮到開發人員的效率問題,Fabric 提供了另外一種運行模式,即開發模式。在開發模式下,合約代碼不再運行於 Docker 容器中,而是直接在本地部署、運行、調試,極大地簡化了開發過程。
合約代碼是 Fabric 開發中最主要的部分之一,通過合約代碼可以實現對賬本和交易等實體的交互與操作,同時實現各種業務邏輯。目前,合約代碼支持使用 Go、Java 和 Node.js 語言進行編寫,通過實現合約代碼接口的方式來編寫合約代碼程序。下面以 Go 語言為例進行介紹。
合約代碼的結構主要包括以下 3 個方面。
- 在 Fabric v1.4 版本中,合約代碼接口包含兩個方法:
Init()
方法和Invoke()
方法。Init()
方法會在第一次部署合約代碼時進行調用,有點類似於類中的構造方法。就如同其方法名所表達的,Init()
方法中一般執行一些合約代碼需要的初始化操作。Invoke()
方法則是在調用合約代碼方法進行一些實際操作時調用,每次調用會被視為一次交易執行。詳細的交易流程將在 4.6 節進行介紹。Go 語言中的合約代碼接口代碼如下所示:
Type Chaincode interface {
// 初始化工作,一般情況下僅被調用一次
Init(stub ChaincodeStubInterface) pb.Response
// 查詢或更新world state,可被多次調用
Invoke(stub ChaincodeStubInterface) pb.Response
}
當合約的Init
或者Invoke
接口被調用時,Fabric 傳遞給合約shim.ChaincodeStubInterface
參數並返回pb.Response
結果,這些參數可以通過調用 API 方法去操作賬本服務,產生交易信息或者調用其他的合約代碼。
目前 API 方法定義在 /core/chaincode 目錄下的 shim 包中,並且可以由以下命令生成:
godoc github.com/hyperledger/fabric/core/chaincode/shim
主要的 API 方法可以分為 6 類,分別是 State 讀寫操作、Args 讀寫操作、Transaction 讀寫操作、PrivateData 讀寫操作、合約代碼相互調用以及 Event 設置。表 4.2 展示了這些方法及其對應的功能。
API 方法及功能
合約代碼是以protobuffer
的形式返回的,定義如下所示
message Response {
// 狀態碼
int32 status = 1;
// 響應碼信息
string message = 2;
// 響應內容
bytes payload = 3;
}
合約代碼還會返回事件信息,包括 Message events 和 Chaincode events,定義如下所示:
messageEvent {
oneof Event {
Register register = 1;
Block block = 2;
ChaincodeEvent chaincodeEvent = 3;
Rejection rejection = 4;
Unregister unregister = 5;
}
}
messageChaincodeEvent {
string chaincodeID = 1;
string txID = 2;
string eventName = 3;
bytes payload = 4;
}
一旦完成了合約代碼的開發,有兩種方式可以與合約代碼交互:通過 SDK 或者通過 CLI 命令行。通過 CLI 命令行的交互將在進行介紹,SDK 的交互可以參考
編寫完合約代碼之後,就要了解如何部署合約代碼以及如何調用合約代碼。要想進行部署合約代碼等相關操作,必然需要啟動 Fabric 系統。Fabric 提供了 CLI 接口,支持以命令行的形式完成與 Peer 節點相關的操作。通過 CLI 接口,Fabric 支持 Peer 節點的啟動停止操作、合約代碼的各種相關操作以及通道的相關操作。
當前 Fabric 所支持的 CLI 命令如表 4.3 所示
其中logging getlevel
、logging setlevel
及logging revertlevels
不推薦使用,將在後續的版本中刪除。
同時通過以下命令,可查看更多與peer
命令相關的信息。
# 此命令需要
cd /opt/gopath/src/github.com/hyperledger/fabric
build /bin/peer
# 或者進入啟動網絡後進入cli容器
docker exec -it cli bash
# 進入cli容器後運行peer命令
peer
在運行以上命令之後,將看到如圖
合約代碼執行過程如圖 4.12 所示,具體介紹如下。
-
客戶端(SDK/CLI)創建交易提案,包含合約代碼函數和調用參數,並以 proto 消息格式發送到背書節點。
-
背書節點調用 shim 包的方法創建合約代碼仿真交易執行內容。
-
背書節點初始化合約、調用參數,基於讀取和寫入的 key 生成讀寫操作集。
-
背書集群節點模擬提案執行:執行讀操作,向賬本發送查詢狀態數據庫的請求;模擬寫操作,獲取 key 的 value 值版本號,模擬更新狀態數據。
-
若返回執行成功,則執行背書操作;若返回失敗,則推送錯誤碼 500。
-
背書節點對交易結果執行簽名,將提案結果返回給客戶端(SDK/CLI),提案結果包括執行返回值、交易結果、背書節點的簽名和背書結果(同意或拒絕)。
合約代碼編寫的內容,可以查看項目 /examples/chaincode/ 下的示例合約代碼了解更多。
Hyperledger Fabric 官方文檔中的架構,分析 Fabric 中的交易背書過程,首先介紹了 Fabric 交易背書過程的機制,然後通過一個簡單的案例描述了其通用流程,之後詳細分析背書過程,最後簡單地介紹了 Fabirc 的背書策略以及驗證賬本和 PeerLedger 檢查點的使用。
在 Fabric 系統中,交易就是一次合約代碼的調用,可能有如下兩種類型。
-
部署交易:部署交易使用一個程序作為參數創建新的合約代碼,成功執行部署交易後,合約代碼被安裝到區塊鏈上。
-
調用交易:調用交易在先前部署的交易上下文中執行合約代碼以及它所提供的功能,當成功執行調用交易時,合約代碼執行指定的函數,可能修改相應賬本的狀態,並返回輸出。
區塊鏈中執行的交易會打包成區塊,區塊連接起來就形成了共享賬本中的哈希鏈。本節將介紹 Fabric 系統中一次交易的執行流程。為了更好地理解 Fabric 系統的交易背書過程,本節將先使用一個簡單的圖示案例來展示一次成功的交易執行過程。
首先在這個圖示案例中,需要做一些假設,也就是說真實開發時需要進行的配置工作。假設如下。
-
節點類型:E0、E1、E2、E3、E4、E5 均為 Peer 節點,其中特殊的是,E0、E1、E2 為此次交易的背書節點,Ordering Service 為共識服務節點組成的共識服務。
-
通道配置:本案例中存在兩個通道,其中 E0、E1、E2、E3 均連接在同一個通道 Channel1 中,而 E4 和 E5 位於另一個通道 Channel2 中。
-
背書策略:E0、E1 必須簽名背書,E2、E3、E4、E5 則不屬於策略。
做好假設之後,開始案例流程,如圖
(1) 客戶端應用通過 SDK 發送出一個交易提案(transaction propose)給背書節點 E0。它用來接收智能合約中相關功能函數的請求,然後更新賬本數據(即資產的鍵 / 值)。同時在發送前客戶端會將這一交易提案打包為一種可識別的格式(如 gRPC 上的 protocol buffer),並使用用戶的加密憑證為該交易提案簽名。
(2) 背書節點 E0 收到客戶端發送的交易提案之後,將先驗證客戶端簽名是否正確,然後將交易提案的參數作為輸入模擬執行,執行操作會生成包含執行返回值、讀操作集合和寫操作集合的交易結果(此時不會更新賬本),再對這個交易提案進行背書操作,附上 anchor 信息發送回客戶端。若這個交易提案中的數據帶有私有數據,那麼背書節點 E0 會先將私有數據存儲到本地的臨時數據庫中,再通過 Gossip 協議向其他授權對等節點傳播,只有傳播到一定數量,背書節點才能向客戶端返回交易結果,交易結果中不攜帶私有數據,只是私有數據鍵值對的哈希值。
(3) 客戶端想要進一步得到 E1 的認可,因此需要發送交易提議給 E1,並且此時可以決定是否附上從 E0 處得到的 anchor 信息。
(4) 背書節點 E1 與先前 E0 的方式一樣,驗證客戶端簽名,驗證之後模擬執行,再將驗證後的 Transaction-valid 信息發送回客戶端。
(5) 客戶端會一直等待,直到收集到了足夠的背書信息之後,將交易提案和結果以廣播的形式傳給共識服務。交易中包括 readset、背書節點的簽名、通道 ID 以及私有數據的哈希值。共識服務並不會讀取交易的詳細信息,而是對接收到的交易信息按通道分類進行排序,打包生成區塊,因此共識服務無法看到私有數據。
(6) 共識服務會將達成一致的交易打包進區塊並傳送給連接在這一通道上的所有節點,E4 和 E5 接收不到任何消息,因為它們沒有連接在當前交易的通道上。
(7) 各節點驗證收到的區塊,驗證是否滿足背書策略以及驗證賬本上的狀態值是否改變來判斷交易是否有效。驗證成功之後更新賬本和世界狀態,然後節點會通過事件機制通知客戶端交易是否已被加入區塊鏈和交易是否有效。若區塊中含有私有數據的哈希值,在驗證成功之後將臨時數據庫中的私有數據存入私有數據庫。
Fabric 中,交易是就指是一次合約代碼調用,下面將詳細分析一次交易背書的過程。
-
客戶端發送交易提議給指定背書節點
為了調用一個交易,客戶端會向它所選擇的一組背書節點發送一個 PROPOSE 消息(這些消息可能不是同時發送的,比如上一節的例子)。對於如何選擇背書節點集合,
client
可以通過 Peer 使用給定chaincodeID
的背書節點集合,反過來也可以通過背書策略獲取背書節點集合。例如,這個交易會被客戶端通過chaincodeID
發送給所有相關的背書節點。除此之外,某些背書節點存在離線或反對的可能,所以存在不簽署該交易的背書節點。提交客戶端會通過有效的背書節點來盡力滿足背書策略。本節將首先對 PROPOSE 消息的格式進行介紹,然後介紹提交客戶端和背書節點間可能的交互模式。
(1) PROPOSE 消息格式
一條 PROPOSE 的格式為PROPOSE = <PROPOSE, tx, [anchor]>
,包含兩個參數,tx
交易消息字段是必需的,anchor
是可選的參數。下面對這兩個參數進行詳細分析。
`