1. fabric服務架構
api: 服務的grpc接口和http接口
sdk:不同開發(fā)語言的軟件工具開發(fā)包 fabric-go-sd
事件: 鏈碼中定義某些事件來進行區(qū)塊鏈操作
身份:聯(lián)盟鏈的身份控制(用戶身份注冊證書勒魔,交易簽名證書,加密傳輸?shù)膖ls證書)
賬本:區(qū)塊高度 區(qū)塊哈希查詢賬本 交易id查詢區(qū)塊以及交易
交易: 交易背書==》交易排序(區(qū)塊打包)==》交易分發(fā)
智能合約:交易調(diào)用智能合約服務
2.fabric網(wǎng)絡拓撲結構
包括:
客戶端
peer節(jié)點(錨節(jié)點/背書節(jié)點/提交節(jié)點)
Orderer
CA(可選)
3.交易流程
客戶端構造交易提案弟胀,發(fā)送給一個或多個Peer節(jié)點孵户,交易提案中包含本次交易要調(diào)用的合約標識检柬、合約方法和參數(shù)信息以及客戶端簽名等何址。(根據(jù)背書策略)
peer背書節(jié)點收到交易提案后會模擬交易執(zhí)行用爪,然后將原始交易提案和執(zhí)行結果打包到一起项钮,進行簽名打包發(fā)回客戶端烁巫,其中模擬執(zhí)行交易期間產(chǎn)生的數(shù)據(jù)修改不會寫到賬本上
客戶端收到各個peer節(jié)點應答后打包到一起組成一個交易簽名宠能,提交交易給Orderer
Orderer對接收到的交易進行共識排序阿弃,然后按照區(qū)塊生成策略,將一批交易打包到一起脾还,生成新的區(qū)塊鄙漏,廣播區(qū)塊給peer節(jié)點怔蚌。
peer節(jié)點收到區(qū)塊后桦踊,對區(qū)塊交易進行校驗籍胯,檢查交易的輸入輸出是否服務當前區(qū)塊鏈狀態(tài)芒炼,完成后將區(qū)塊术徊,寫入賬本(世界狀態(tài))
-
同步區(qū)塊信息到其他節(jié)點并更新世界狀態(tài)
注意:peer記賬節(jié)點更新世界狀態(tài)如果存在錯誤的交易信息就不會更新世界狀態(tài)但是會存入?yún)^(qū)塊信息中
4.peer
-
讀集子寓,寫集和版本號
讀集:讀取的已經(jīng)提交的狀態(tài)值斜友,這里的已提交是指“確認高度"區(qū)塊之前的數(shù)據(jù)屬于已提交的數(shù)據(jù)鲜屏,對fabric來說就是上一個被提交的區(qū)塊的狀態(tài)值国拇,這樣做是為了防止區(qū)塊鏈分叉酱吝。
寫集:將要更新的狀態(tài)鍵值對或狀態(tài)鍵值對的刪除標記忆嗜,這里如果涉及同一個數(shù)據(jù)的多次更新則只會保留最后一次的值,即交易是最小的原子單位不能再細分(與數(shù)據(jù)庫事務的原子性相似)
版本號:由區(qū)塊高度和交易編號組成闪湾,用來標記一筆交易中讀的交易所對應的版本號响谓,用于驗證讀操作是否有效。
-
交易驗證:包括簽名驗證跋炕、權限驗證等 最重要的是交易讀寫集的驗證
交易讀寫集的驗證就是判斷交易中讀集的版本號是否等于世界狀態(tài)的版本號辐烂,這里的世界狀態(tài)受已提交的交易影響纠修,也受到未提交交易即當前區(qū)塊中該筆交易之前的交易的影響扣草。例如:一個區(qū)塊中的兩個交易1、2密浑,1對某個鍵值對進行了修改粗井,2對該修改的鍵值對進行讀那么交易2就是一筆無效交易浇衬〕掌ⅲ可以看出區(qū)塊驗證保證了寫優(yōu)先梳星,讀到的數(shù)據(jù)一定是最新的數(shù)據(jù)赞赖。 例如:
世界狀態(tài):(k1,1,v1)(k2,1,v2) (k3,1,v3) (k4,1,v4)
交易1: write(k1,v1') write(k2,v2')
交易2:Read(k1),write(k3,v3') 交易2無效(因為讀取的k1的值(交易1中存在修改)和世界狀態(tài)的不一樣)
交易3:write(k2,v2'')
交易4: write(k2,v2''') read(k3) 由于交易2無效所以交易4有效
交易5:write(k5,v5) read(k4)
1.4源碼的事務控制 /fabric/core/ledger/kvledger/txmgmt/txmgr/txmgr.go
1.4源碼的讀寫集 /fabric/core/ledger/kvledger/txmgmt/rwsetutil/rwset_builder.go
-
世界狀態(tài): leveldb存儲的是區(qū)塊索引辕近,couchDB支持模糊查詢
世界狀態(tài)存儲是的是交易執(zhí)行后的所有鍵值的最新值匿垄,它是區(qū)塊鏈中的一個快照椿疗,查詢區(qū)塊的時候可以提升鏈碼的執(zhí)行效率(不需要每次查詢區(qū)塊)漏峰,peer節(jié)點每次啟動的時候就會檢查世界狀態(tài)與區(qū)塊存儲的內(nèi)容是否一致,支持levedb和couchdb届榄,
1.4源碼leveldb:/fabric/core/ledger/kvledger/txmgmt/statedb/statecouchdb
1.4源碼couchb: /fabric/core/ledger/kvledger/txmgmt/statedb/stateleveldb
-
歷史狀態(tài)存儲可選
記錄某個鍵在某個區(qū)塊中的某條交易中改變浅乔,只會記錄改變的動作不會記錄具體的改變,讀取的時候首先獲取鍵值對的改變位置铝条,然后再從區(qū)塊中讀取交易靖苇。使用levelDB記錄
1.4源碼位置:/fabric/core/ledger/kvledger/history/historydb/historydb.go
-
區(qū)塊存儲
區(qū)塊以文件的形式存儲在系統(tǒng)中(文件名為blockfile_xxxxxx),區(qū)塊大小可以按照指定大小修改班缰,賬本的最大容量等于
塊大小 * 1000000
1.4源碼位置:/fabric/common/ledger/blockledger/ledger.go
存儲位置參數(shù) peer.fileSystemPath
默認存儲位置:/var/hyperledger/production/ledgersData/chains/chains/通道名
-
區(qū)塊讀取
目前已實現(xiàn)的有區(qū)塊文件流贤壁、區(qū)塊流及區(qū)塊迭代器這三個類,分別用于讀取文件塊脾拆、從文件塊中讀取區(qū)塊包帚、在整個鏈條上讀取區(qū)塊等谋梭。
-
區(qū)塊索引:
用于快速定位區(qū)塊踢步,查詢條件(索引值)可以是區(qū)塊高度兼丰、區(qū)塊哈希蟆技、交易哈希等,區(qū)塊的位置由區(qū)塊文件編號、文件內(nèi)偏移量、區(qū)塊數(shù)據(jù)長度標記的(從那個文件讀爽航,從文件的哪個位置開始讀,讀多少的長度)
-
區(qū)塊提交
首先把區(qū)塊保存到區(qū)塊文件中,peer會對區(qū)塊中的交易進行驗證,保存后更新區(qū)塊索引及世界狀態(tài)(只有有效交易才會更新世界狀態(tài)),更新歷史狀態(tài)(可選如果智能合約有需要的話)這三步的同步非常重要,在peer節(jié)點啟動時都會檢查這三者是否同步睬塌,如果不一致則以區(qū)塊文件為標準進行同步硫兰。 注意:即使是無效交易也會被存儲在區(qū)塊中泳赋,與區(qū)塊哈希有關,因為區(qū)塊哈希是在orderere產(chǎn)生的如果在peer處刪除那么區(qū)塊哈希就會改變掸绞,但是不會改變世界狀態(tài)俺抽。
賬本存儲:相當于區(qū)塊文件和世界狀態(tài)的存儲
5.Orderer
排序服務:
Broadcast的主要功能是接收來自客戶端的交易請求,對客戶端發(fā)送過來的數(shù)據(jù)格式校驗萍歉,同事對客戶端的權限進行檢查侣颂,然后嘗試請求打包給共識組件進行排序憔晒。(處理交易澎蛛,通道創(chuàng)建和更新,鏈碼實例化和初始化)
1.4源碼位置:/fabric/orderer/common/broadcast/broadcast.go Handle
Deliver負責處理peer或者客戶端獲取區(qū)塊文件請求,客戶端發(fā)來請求之后,檢查對應通道的orderer節(jié)點中是否存在薄啥,當網(wǎng)絡中生成新的區(qū)塊,或者客戶端視圖獲取通道內(nèi)的創(chuàng)世區(qū)塊或具體區(qū)塊的時候都是通過Orderer的Deliver模塊進行處理炭菌,客戶端來獲取區(qū)塊文件的時候罪佳,或發(fā)送一個區(qū)塊序列號區(qū)間給Deliver,而Deliver會根據(jù)區(qū)間來從自己本地讀取區(qū)塊文件黑低,每次自增+1的形式給客戶端返回指定區(qū)塊
1.4源碼位置 /fabric/common/deliver/deliver.go Handle
共識組件:
solo:只有一個orderer節(jié)點通過golang的mutext赘艳,將排序函數(shù)加鎖和解鎖,才用簡單的數(shù)組模式克握。不涉及Order節(jié)點之間的同步數(shù)據(jù)蕾管。一般用于測試環(huán)境
1.4源碼位置:fabric/orderer/consensus/solo/chain.go main
raft:存在2n+1個orderer節(jié)點(至少3個),fabric的raft機制中存在領導者(Leader)菩暗,跟隨者和候選者三種角色,領導者負責區(qū)塊排序掰曾,跟隨者將會實時從領導者處接收區(qū)塊文件使自己的狀態(tài)和領導者的狀態(tài)保持一致。候選者是指通道內(nèi)的所有Orderer節(jié)點(沒有領導節(jié)點的時候)
如果領導節(jié)點宕機停团,內(nèi)部會通過選舉產(chǎn)生新的領導節(jié)點(選舉通過內(nèi)部投票的方式)旷坦,領導節(jié)點主要負責同步區(qū)塊文件,位置內(nèi)部穩(wěn)定佑稠。當存活的orderer小于50%則整個網(wǎng)絡無法進行交易秒梅。
存在問題:當網(wǎng)絡流量大的時候,跟隨者需要實時同步數(shù)據(jù)舌胶,鏈路維護以及最新排序狀態(tài)捆蜀,會占用大部分網(wǎng)絡流量。
1.4源碼位置:fabric/orderer/consensus/etcdraft/chain.go serveRequest
kafka: order節(jié)點解析數(shù)據(jù)封裝為kafka的喜愛幔嫂,發(fā)送交易到kafka集群辆它,與kafka建立長連接,定期交換數(shù)據(jù)保持連接穩(wěn)定性和消息的及時性履恩,kafka會為每個通道建立對應的topic 用來區(qū)分通道和區(qū)塊鏈的關系锰茉,kafka集群部署,不同kafka之間通過kafka自己內(nèi)部進行同步 切心。order節(jié)點通過監(jiān)聽方式洞辣,當區(qū)塊文件高度超過時間或者區(qū)塊高度得到滿足之后咐刨,就會拉取交易到orderer節(jié)點本地,然后打包分發(fā)給peer節(jié)點(原理和raft類似)
1.4源碼位置:fabric/orderer/consensus/kafka/chain.go startThread
多通道數(shù)據(jù)隔離:
1.4源碼位置:fabric/orderer/common/multichannel/registrar.go Initialize
6.智能合約(鏈碼)
鏈碼
一個fabric中間件扬霜,自己擁有獨立的docker執(zhí)行環(huán)境定鸟,與背書節(jié)點grpc連接
生命周期:
打包,安裝著瓶,實例化联予,升級,交互
鏈碼交互流程:
1.4 源碼go語言鏈碼docker打包: /fabric/core/chaincode/platforms/golang/platform.go GenerateDockerBuild
系統(tǒng)鏈碼
系統(tǒng)鏈碼在 peer 服務啟動時隨 peer 節(jié)點注冊材原,同 peer 節(jié)點一起運行沸久。系統(tǒng)鏈碼為固定的 5 個:lscc、qscc余蟹、cscc卷胯、vscc、escc威酒,這 5 個鏈碼功能固定窑睁,分別用于鏈碼生命周期管理、區(qū)塊/交易查詢葵孤、通道配置管理担钮、交易背書和交易驗證。
1.LSCC:鏈碼實例化尤仍,升級
LSCC 用于管理鏈碼的生命周期——在peer上安裝箫津、在通道上部署和升級、用戶從運行中的鏈碼獲取信息宰啦。它提供了八個方法: install, deploy, upgrade, getid, getdepspec,getccdata, getchaincodes, getinstalledchaincodes苏遥。
1.4源碼位置:fabric/peer/chaincode/instantiate.go
1.4源碼位置:fabric/peer/chaincode/upgrade.go
2. CSCC:某條鏈的配置
CSCC 管理peer上通道相關的信息以及執(zhí)行通道配置交易。它提供五個方法:JoinChain,
GetConfigBlock, GetConfigTree,SimulateConfigTreeUpdate, GetChannels赡模。
3. QSCC:查詢賬本存儲
QSCC 將特定的方法暴露給用戶暖眼,使得用戶可以查詢在block storage中存儲的區(qū)塊和交易。它提供五個方法:(i) GetChainInfo, (ii) GetBlockByNumber, (iii) GetBlockByHash, (iv) GetTransactionByID, (v) GetBlockByTxID纺裁。
1.4源碼位置:fabric/peer/chaincode/query.go
-
ESCC:交易模擬后的結果進行打包簽名
背書節(jié)點在執(zhí)行交易之后,將它的前面放在transaction response message中司澎。其中欺缘,transaction response message也包括交集執(zhí)行的結果,如交易狀態(tài)挤安、合約事件和read/write set等谚殊。一個調(diào)用功能可以包含5-7個參數(shù),即Header蛤铜、ChaincodeProposalPayload嫩絮、ChaincodeID丛肢、Response、simulation result剿干、events蜂怎、payload visibility。
1.4源碼位置:fabric/core/endorser/endorser.go
5. VSCC:交易驗證 根據(jù)合約的背書策略驗證每個交易的簽名集合
1.4源碼位置:fabric/core/committer/txvalidator/validator.go
鏈碼編程接口
Init() : 鏈碼初始化接口
Invoke():鏈碼交易接口
1.4 源碼位置 /fabric/core/chaincode/shim/interfaces.go Chaincode