這個目錄下面有兩個目錄:businesschannel和pocchannel。它們表明的是兩個通道,也就是兩個鏈的數據,每一個鏈如今只有一個區塊文件,blockfile_是文件名中固定的前綴,000000是固定的6位佔位符,下一個文件名會依次遞增。從這個目錄結構能夠看到,記帳節點在底層帳本數據存儲的時候就對不一樣鏈的數據進行了隔離。數據庫
排序節點會存儲全部鏈的帳本數據,排序節點除了能夠選擇序列化區塊文件的格式外,還支持JSON文件格式和內存數據結構的帳本數據,後面兩種都只在測試環境下使用。序列化區塊文件和JSON文件格式區塊文件的存儲目錄通常是/var/hyperledger/production/orderer/chains。其中,orderer/chain是固定的目錄後綴。一樣地,不一樣鏈的帳本數據存儲在以通道名稱爲目錄名稱的目錄中,以實現不一樣鏈帳本數據的物理隔離。內存數據的帳本數據沒有持久化的存儲,不一樣鏈的帳本數據存儲在不一樣的數據結構中。數組
記帳節點和排序節點都會給帳本數據創建索引,不一樣的是排序節點只會創建以BlockNum爲屬性的索引。網絡
索引文件存儲的目錄是/var/hyperledger/production/ledgersData/chains/index,其中,ldegersData/chains/index是記帳節點上固定的目錄後綴,排序節點上的目錄後綴是orderer/index。數據結構
下面是一個記帳節點上的索引數據的目錄:工具
root@peer0:/var/hyperledger/production/ledgersData/chains/index# tree區塊鏈
|--000002.1db測試
|--000007.logspa
|--CURRENT命令行
|--LOCK3d
|--LOG
--MANIFEST-000008
0 directories,6 files
索引數據是存儲在LevelDB數據庫裏的,數據庫的類型目前是不可選的。LevelDB是持久化的K-V數據庫,在保存索引的時候會加上ledgerid做爲前綴,固然生成的組合鍵在構造的時候是要先轉換成[]byte數組的。因爲索引數據存儲在同一個數據庫中,因此對於不一樣鏈的數據,索引數據的實現是邏輯隔離的,並不是是物理隔離的。
排序節點不須要查詢具體的交易信息和狀態數據,也不會存儲狀態數據及其歷史數據。
peer節點上狀態數據存儲的目錄是/var/hyperleder/production/ledgersData/stateLeveldb,其中,ledgesData/stateLeveldb是固定的後綴:
root@peer0:/var/hyperleder/production/ledgersData/stateLeveldb# tree
.
|--000002.ldb
|--000007.log
|--CURRENT
|--LOCK
|--LOG
--MANIFEST--000008
0 directories, 6 file
狀態數據也是基於K-V存儲的,同一個節點的狀態存儲在同一個數據庫中,沒有進行物理隔離。和索引數據不一樣的是,狀態數據是和chaincodeID相關的,不一樣chaincodeID的數據是邏輯隔離的,而chaincodeID一樣是以chainID爲前綴進行了邏輯隔離。
歷史數據存儲的目錄是/var/hyperleder/production/ledgersData/historyLeveldb,其中,ledgersData/historyLeveldb是固定的後綴:
root@peer0:/var/hyperleder/production/ledgersData/historyLeveldb# tree
.
|--000002.ldb
|--000010.ldb
|--000012.log
|--CURRENT
|--LOCK
|--LOG
|--LOG.old
--MANIFEST--000013
`--level-party.sock
0 directories, 9 file
歷史數據目前內置的數據庫是levelDB,也是不可替換的。記錄的是狀態數據的歷史記錄。同狀態數據同樣,經過在構建chaincodeID的時候增長ChainID前綴來邏輯隔離不一樣鏈的數據。
鏈碼是Hyperledger Fabric1.0提供的智能合約方案,實現了交易的模擬執行。鏈碼從多個緯度對多鏈提供了支持。好比鏈碼的生命週期管理、鏈碼和背書節點的通訊、鏈碼的部署方法等。
【1】智能合約在Hyperledger Fabric1.0上稱爲「鏈碼(chaincode)」,是獨立運行的應用程序,只接收啓支它的「背書節點」的指令,執行指定的業務邏輯。
【2】多鏈狀況,同一個智能合約可能會在不一樣的鏈上運行。
【3】爲重用智能合約代碼,智能合約的部署拆分紅「安裝」和「實例化」兩個步驟
安裝:只是將鏈碼的源代碼序列化後和鏈碼名稱、版本等封裝成ChaincodeDeploymentSpec保存到peer節點上,
鏈碼安裝跟具體的鏈沒有關係,也不須要ChainID參數。
不一樣鏈的鏈碼是沒有隔離的,即在一個鏈安裝的鏈碼可能和另外一個鏈的鏈碼產生衝突。
鏈碼安裝時會檢查是否存在相同名稱和版本的鏈碼,若不一樣的上層應用同時都部署了相同的鏈碼和版本,可能存在一個鏈碼安裝成功,另外一個鏈的鏈碼安裝失敗。
實例化和鏈碼升級是在指定鏈上操做的,實際過程分兩步:
(1)。調用系統鏈碼LSCC的部署操做,經過LSCC把鏈碼計算哈希後生成的chaincodeData存放到狀態數據庫中。
(2)。從文件系統中讀取保存的鏈碼源碼,生成鏡像後執行初始化操做。
鏈碼操做包括:初始化和調用。它們都是在具體鏈上操做的,鏈碼鏡像命名規則:
NetworkID-PeerID-ChaincodeName-ChaincodeVersion-SHA256(ChainID)
鏈碼鏡像名稱最後一部分是對ChainID計算SHA256哈希後再轉換成十六制的字符串,邏輯上不一樣鏈的鏈碼會有不一樣的鏡像名稱。
啓動的鏈碼容器命名和鏡像同樣,只會把「:」替換成「_」。這樣,不一樣鏈的鏈碼執行是能夠在不一樣的環境中隔離的。
實際在啓動鏈碼容器時並未指定ChainID參數,即目前不一樣鏈上相同鏈碼是運行在同一個容器中的。但即便運行在相同的鏈碼容器中,也會經過ChainID進行邏輯隔離。
http://keliu.me/2018/03/07/FabricChaincode/
鏈碼容器啓動後,會和啓動它的「背書節點」 創建gPRC鏈接。
應用程序/命令行經過gRPC鏈接給背書節點發送請求,背書節點校驗經過,經過鏈碼和背書節點創建gRPC鏈接將請求發送給鏈碼去執行。
鏈碼執行自己和具體鏈無關,鏈碼容器也不會在本地保存任何數據,是一個無狀態的執行環境。
須要訪問或寫入狀態數據時,經過創建好的gRPC鏈接發送請求給背書節點,再進行後續的業務邏輯處理。即在鏈碼這一端,是不區分鏈的,因此不一樣鏈才能夠共用相同的鏈碼容器。
可指定-C在指定的通道上操做,在入口處提供了對多鏈的支持。
系統鏈是一個特殊的鏈,含有系統層而全局配置區塊鏈網絡的聯盟及組織信息、MSP信息和策略信息等,只存在於排序服務中。
涉及一些信息修改,如增長一個組織,增長排序服務節點,這些都會在系統鏈上增長一個配置區塊,
整個系統有且只有一個系統鏈,系統鏈經過創世區塊配置,排序服務啓動時經過ORDER_GENERAL_GENESISFILE環境變量指定創世區塊文件並建立系統鏈。
系統鏈的名稱能夠在建立創世區塊的時候經過工具configtxgen的channelID參數指定,默認的系統鏈名稱是testchainid,
是不是系統鏈的判斷方法就配置區塊信息裏是否有聯盟信息配置項。