- Hyperledger Fabric技術內幕:架構設計與實現(xiàn)原理
- 李鑫
- 3737字
- 2019-03-28 10:05:43
1.3 Hyperledger Fabric源碼分析說明
1.3.1 源碼分析思路
本書以Hyperledger Fabric初始化啟動流程、交易處理流程等流程為主線,分析Fabric核心模塊,介紹其核心設計思想,如表1-5所示。
表1-5 Hyperledger Fabric源代碼主要目錄文件說明表

□ 核心模塊:擔任功能節(jié)點角色的模塊,提供核心功能服務,包括Orderer排序節(jié)點與Peer節(jié)點(包含Endorser背書節(jié)點與Committer記賬節(jié)點),將在第2章至第5章中分析各個模塊的初始化啟動流程、處理交易流程以及與其他模塊間的交互過程,并介紹其核心功能的設計與實現(xiàn)細節(jié)。
□ 公共模塊:為核心模塊和其他模塊提供基礎支持服務,包括bccsp、common、core、events、gossip、msp、protos等目錄代碼。其中,第6章介紹了Gossip消息模塊,為Peer節(jié)點提供安全、可靠、可擴展的P2P數(shù)據(jù)分發(fā)協(xié)議。第7章介紹了公共功能模塊,包括賬本數(shù)據(jù)存儲模塊、安全服務模塊、事件模塊等,為其他模塊提供底層存儲機制、安全機制、異步通信機制等。
□ 輔助模塊:為其他模塊提供輔助性工具、運行環(huán)境、測試用例、文檔等,不作為分析重點,視情況分析以幫助理解其他模塊。
同時,分析代碼時應注意Hyperledger Fabric代碼的常用慣例,這樣做將有助于理解數(shù)據(jù)結構與代碼功能,比較典型的情況包括:
□ 同一個模塊的相關代碼可能存在于其他多個模塊相同模塊名稱的目錄下,需要結合相關目錄下的代碼共同研究,如分析Peer節(jié)點需要結合fabric/peer、core/peer、core/chaincode、protos/peer等目錄。
□ mocks目錄下通常包含模擬功能模塊源碼以用于測試環(huán)境或數(shù)據(jù),test名稱目錄通常包含測試代碼與數(shù)據(jù),sample名稱目錄通常包含示例代碼。
□ Fabric中經(jīng)常采用提供者模式(Provider Pattern)來分離接口定義與具體實現(xiàn)。通常,核心數(shù)據(jù)結構都存在XXX接口類型、xxxImpl/YXXX接口實現(xiàn)類型、XXXProvider提供者接口類型、xxxProviderImpl/YXXXProvider提供者接口實現(xiàn)類型等。注意,接口實現(xiàn)類型名稱大多數(shù)是將接口類型名稱XXX的第一個有效單詞變?yōu)樾懽帜竫xxImpl或直接在前面添加實現(xiàn)功能名稱(可能會對XXX略作修改)為YXXX,具體說明如下。
○ XXX接口類型通常用于定義該模塊提供的功能方法接口,大多數(shù)是Interface接口并且沒有定義屬性字段,xxxImpl/YXXX實現(xiàn)類型會具體實現(xiàn)對應的接口方法和定義屬性字段。例如,deliverServiceImpl類型實現(xiàn)了DeliverService接口類型,LedgerCommitter類型實現(xiàn)了Committer接口類型。
○ XXXProvider提供者類型本身通常不會直接實現(xiàn)核心數(shù)據(jù)結構,而只是提供生成或獲取XXX接口類型或實現(xiàn)類型的方法描述,由xxxProviderImpl/YXXXProvider提供者類型實現(xiàn)對應的方法,可以直接獲取實際功能的接口或實現(xiàn)對象,如blocksProviderImpl類型實現(xiàn)了BlocksProvider接口類型。
□ XXXSupport類型通常都是對XXX類型進行操作的支持對象,一般會包含XXX類型對象、相關輔助工具以及資源。
□ 代碼中defaultXXX類型的數(shù)據(jù)結構通常都是XXX實現(xiàn)類型,其通常作為核心數(shù)據(jù)結構的默認初始對象。
□ 本文在分析時使用“→”符號表示程序執(zhí)行路徑上的方法或函數(shù)調用關系。
□ 以大寫字母開頭的結構字段與方法、數(shù)據(jù)結構類型與函數(shù)通常是公共的,可以提供給外部程序公開調用。以小寫字母開頭的結構字段與方法、數(shù)據(jù)結構類型與函數(shù)通常都是私有的,一般提供給內部模塊調用。
本書為防止分析函數(shù)調用過深,從而影響到主線流程的分析,考慮到篇幅有限,并確保清晰簡潔,在分析時將遵循如下原則。
□ 所有代碼清單首行標注的源碼文件位置均默認處于fabric源碼目錄下。
□ 盡可能在一個章節(jié)內分析屬于同一個功能模塊的代碼,有可能屬于同一個功能模塊的相關代碼分布在不同的包或模塊中。對不復雜的跨功能模塊函數(shù)調用操作,文中摘選核心代碼片段直接解釋說明,但將其相對獨立完整的模塊執(zhí)行流程仍保留在獨立章節(jié)中進行分析,如Endorser背書流程等,適當添加引用章節(jié)號以便于索引。
□ 與邏輯主線相關度不高的繁瑣底層細節(jié)操作,或者較少代碼的操作,如簡單的參數(shù)合法性檢查、錯誤檢查、打印處理信息等,限于篇幅,都不提供代碼清單或直接省略。
□ 文中有時會將過長的源代碼分割開來在同一個章節(jié)中進行解析,這些代碼在源代碼中可能屬于同一個函數(shù)中連續(xù)執(zhí)行的程序。
□ 文中標注了重要變量的原始數(shù)據(jù)結構類型,以方便讀者在源碼中進行檢索查詢。
Hyperledger Fabric 1.1.0實現(xiàn)了很多實驗新特性,在正式發(fā)布版本中,這些新特性都處于關閉狀態(tài)或者將參數(shù)默認設置為空,其目的是不影響后續(xù)版本代碼的功能升級,同時又能兼容當前發(fā)布版本的穩(wěn)定性。Fabric源碼采用了Makefile管理源碼構建工作,很多實驗新特性的源碼都存在正式代碼與實驗代碼兩個版本。用戶可以在使用make工具編譯源代碼時添加打開實驗版本標志位metadata.Experimental為true,那么在編譯Docker鏡像時就會自動添加gotags,即打開實驗版本“experimental”選項,從而支持測試很多新特性功能,如鏈碼API支持隱私數(shù)據(jù)、Java鏈碼實例化與調用等。本書不會專門對所有實驗版本新特性進行深入分析,但會解析重大的版本新特性設計,如支持隱私數(shù)據(jù)集合(Private Data Collection, PDC)新特性,即通道內隱私數(shù)據(jù)的細粒度隱私保護機制。Hyperledger Fabric 1.2.0及以后版本已經(jīng)開始支持新特性,讀者可以對照學習。
事實上,F(xiàn)abric社區(qū)一直以來就在積極討論增強通道內隱私保護的新特性,如FAB-1151、FAB-2961、FAB-4976、FAB-8718等。Fabric 1.0.0中引入了多通道(Multiple-channel)機制實現(xiàn)了隔離數(shù)據(jù)特性,防止通道外的節(jié)點非法獲取這些受保護的數(shù)據(jù),起到了保護通道內公共數(shù)據(jù)隱私性的目的。但是,這種設計機制仍然存在以下不足之處。
□ Orderer排序節(jié)點保存了所有通道的賬本數(shù)據(jù),實際上該節(jié)點不讀取使用任何賬本數(shù)據(jù),僅僅為所有通道保存賬本數(shù)據(jù)和提供訪問服務。如果存在隱私數(shù)據(jù),則同樣會暴露給Orderer節(jié)點。
□ 通道內的Peer節(jié)點擁有該通道上所有組織的賬本數(shù)據(jù),包括與本地節(jié)點無關的交易數(shù)據(jù)。
□ 通道隔離機制提供的數(shù)據(jù)粒度較粗。如果所有組織之間都需要共享彼此的隱私數(shù)據(jù),又不希望其他組織看見自己的所有數(shù)據(jù),則每個組織之間都需要構建通道,大約需要構建O(n2)量級的通道數(shù)量。同時,通道暫時還不支持刪除操作,缺乏靈活性。
□ 缺乏動態(tài)訪問控制機制,即在運行過程中還不支持動態(tài)控制節(jié)點對數(shù)據(jù)的訪問權限。
目前,F(xiàn)abric社區(qū)正在努力推進工作以增強Endorser背書環(huán)節(jié)、Orderer排序環(huán)節(jié)以及Committer提交賬本環(huán)節(jié)中的數(shù)據(jù)隱私性,存在采用加密機制或Hash機制(可以結合加鹽即隨機字符串或HMAC等機制提高安全強度)兩種較為成熟和靈活的方案。但前者需要解決密鑰的分發(fā)與管理問題,可能帶來設計上新的復雜性,這也是Fabric 1.1.0在實驗版本中開始支持隱私數(shù)據(jù)集合及Side DB數(shù)據(jù)庫的基本動機。
新特性采用了Hash機制,即背書節(jié)點對交易提案執(zhí)行結果中的私有數(shù)據(jù)(即隱私數(shù)據(jù))計算哈希值,簽名后返回客戶端以驗證背書節(jié)點結果的一致性。同時,將隱私數(shù)據(jù)明文通過Gossip消息協(xié)議傳播給授權組(以靜態(tài)或動態(tài)方式指定)的Peer節(jié)點集合,其他節(jié)點只能接收到隱私數(shù)據(jù)哈希值作為交易證據(jù),且不需要創(chuàng)建獨立的通道,從而實現(xiàn)比通道更細粒度與低開銷的數(shù)據(jù)隱私保護機制。另外,新特性包括隱私數(shù)據(jù)庫(Side DB數(shù)據(jù)庫)、transient隱私數(shù)據(jù)存儲對象(封裝了transient隱私數(shù)據(jù)庫)等。當節(jié)點提交賬本時,將隱私數(shù)據(jù)讀寫集更新到隱私數(shù)據(jù)狀態(tài)數(shù)據(jù)庫中,將區(qū)塊數(shù)據(jù)即公有數(shù)據(jù)(公共數(shù)據(jù)與隱私數(shù)據(jù)哈希值)讀寫集更新到區(qū)塊數(shù)據(jù)文件中。
Fabric 1.2.0及其后續(xù)版本(推薦使用隱私數(shù)據(jù)的生產(chǎn)環(huán)境采用)開始在正式版中支持通道隱私數(shù)據(jù)集合新特性,在1.1.0實驗版本的基礎上對隱私數(shù)據(jù)添加了隱私數(shù)據(jù)集合配置信息,并保存到transient隱私數(shù)據(jù)庫,同時在賬本的隱私數(shù)據(jù)庫中添加了區(qū)塊有效范圍信息,另外,還支持服務發(fā)現(xiàn)(Service Discovery,以簡化客戶端應用程序)、可插拔的背書及驗證系統(tǒng)鏈碼(Pluggable E/V Syscc,將原先的ESCC與VSCC系統(tǒng)鏈碼實現(xiàn)為靈活的插件對象)等新特性。Fabric 1.3.0支持CouchDB分頁機制、Java語言鏈碼支持、基于通道的事件服務等新特性。有興趣的讀者可以通過Jira(https://jira.hyperledger.org/)查看項目更多的開發(fā)計劃與任務進展情況。
1.3.2 配置機制
Fabric配置機制包括配置文件、配置環(huán)境變量與配置命令行選項參數(shù),如表1-6所示。Fabric通過Viper組件管理配置項的解析、設置與獲取等操作,Viper組件可以讀取系統(tǒng)環(huán)境變量、yaml/json配置文件(orderer.yaml和core.yaml)等與綁定命令行選項參數(shù),解析并轉換為配置項鍵值對再存儲到Viper組件中,從而靈活支持多種配置方式。通常,F(xiàn)abric調用InitViper()函數(shù)初始化Viper組件的配置文件路徑以及指定配置文件名稱,默認在$FABRIC_CFG_PATH(如/etc/hyperledger/fabric)路徑下查找配置文件,在找不到文件時依次查找當前目錄、默認開發(fā)配置目錄($GOPATH/src/github.com/hyperledger/fabric/sampleconfig)和系統(tǒng)默認配置路徑(/etc/hyperledger/fabric)下的配置文件,接著調用viper.SetConfigName()方法,指定配置文件名稱。然后,調用Viper組件的ReadInConfig()方法,從上述指定配置路徑上加載指定名稱的配置文件,解析成配置項鍵值對再存儲到Viper組件中。Viper組件的常用基本用法如下。
viper.SetConfigName("core") // 設置配置文件名稱為core viper.AddConfigPath("/etc/appname/") // 設置搜索的配置文件路徑,可以設置多個 viper.AddConfigPath("$HOME/.appname") viper.AddConfigPath(".") viper.ReadInConfig() // 查找并讀取配置文件 viper.Get("key") // 獲取配置項key對應的屬性值 viper.Set("key", "value") // 設置配置項key的值為value
表1-6 Hyperledger Fabric配置機制列表

用戶可以通過設置環(huán)境變量來改變配置項的屬性值,環(huán)境變量與配置文件中的配置項名稱是嚴格對應的。例如,orderer.yaml配置文件中General配置下的LogLevel默認為info級別,若設置環(huán)境變量ORDERER_GENERAL_LOGLEVEL=NOTICE,則將日志級別更改為NOTICE級別。注意,Peer節(jié)點和Orderer節(jié)點相關環(huán)境變量分別是以CORE_和ORDERER_前綴開頭的大寫字符串。
另外,用戶可以通過設置命令行選項參數(shù)來改變配置項的屬性值,F(xiàn)abric采用Cobra組件處理命令行請求,通過重置命令行選項參數(shù)來綁定Viper組件指定的配置項,以改變指定配置項的屬性值。如代碼清單1-20所示,在Peer節(jié)點的啟動階段,Cobra組件創(chuàng)建主命令選項mainFlags及其logging-level選項,接著Viper組件將其綁定到自身的logging_level配置項,這樣,用戶就可以在peer命令行中設置當前模塊的日志級別。
因此,設置命令行選項參數(shù)、環(huán)境變量、配置文件在設置配置項時的優(yōu)先級是依次降低的。
代碼清單1-20 main()主程序的源碼示例
peer/main.go文件 func main() { …… // 定義命令行選項集合 mainFlags := mainCmd.PersistentFlags() …… // 設置logging-level選項 mainFlags.String(“l(fā)ogging-level”, “”, “Default logging level and overrides, see core.yaml for full syntax”) viper.BindPFlag(“l(fā)ogging_level”, mainFlags.Lookup(“l(fā)ogging-level”)) // Viper組件配置綁定的命令行選項 …… }
- 碼上轉型:傳統(tǒng)企業(yè)互聯(lián)網(wǎng)+實戰(zhàn)
- 社群營銷(微課版)
- 新興電子商務消費者信任和購買行為研究
- 創(chuàng)業(yè)生態(tài)系統(tǒng)的網(wǎng)絡特性與新企業(yè)績效
- 淘寶網(wǎng)店大數(shù)據(jù)營銷:數(shù)據(jù)分析、挖掘、高效轉化
- 電商運營與推廣:操作實戰(zhàn)+案例分析+策略技巧
- 在家就能做的99種網(wǎng)上生意
- 一本書玩轉電商、微商軟文營銷
- 電子商務與現(xiàn)代物流
- 互聯(lián)網(wǎng)市場營銷實戰(zhàn)手記
- 解讀物聯(lián)網(wǎng)
- 運營無憂:淘寶天貓運營與推廣實操
- 區(qū)塊鏈:量子財富觀
- 微信力量
- 營銷一板磚