Fabric--鏈碼的概念與使用
鏈碼的概念與使用
概念:
Chaincode: 鏈上程式碼, 簡稱鏈碼, 一般是指使用者編寫的應用程式碼
鏈碼被部署在Fabric網路節點上,
Peer 節點
– 背書節點
– commit節點
– Leader節點
– 錨節點
執行在隔離沙盒(當前為Docker容器)中,
並通過gRPC協議與相應的Peer節點進行互動, 以操作分散式賬本中的資料
protobuf
分類
鏈碼一般分為:
- 使用者鏈碼
- 系統鏈碼
使用者鏈碼
由應用開發人員使用Go(Java/JS)語言編寫基於區塊鏈分散式賬本的狀態及處理邏輯
執行在鏈碼容器中, 通過Fabric提供的介面與賬本平臺進行互動
系統鏈碼
負責Fabric節點自身的處理邏輯, 包括系統配置、背書、校驗等工作
系統鏈碼僅支援Go語言, 在Peer節點啟動時會自動完成註冊和部署
系統鏈碼共有五種型別:
配置系統鏈碼(CSCC)
CSCC: Configuration System Chaincode
負責賬本和鏈的配置管理
背書管理系統鏈碼(ESCC)
ESCC: Endorsement System Chaincode
負責背書(簽名)過程, 並可以支援對背書策略進行管理
對傳入的鏈碼提案的模擬執行結果進行簽名, 之後建立響應訊息返回給客戶端
生命週期系統鏈碼(LSCC)
LSCC: Lifecycle System Chaincode
負責對使用者鏈碼的生命週期進行管理
鏈碼生命週期包括安裝、部署、升級、許可權管理、獲取資訊等環節.
查詢系統鏈碼(QSCC)
QSCC: Query System Chaincode
負責提供賬本和鏈的資訊查詢功能
驗證系統鏈碼(VSCC)
VSCC: Verification System Chaincode
交易提交前根據背書策略進行檢查
驗證過程:
- 首先解析出交易結構, 並對交易結構格式進行校驗
- 檢查交易的讀集合中元素版本跟本地賬本中版本一致
- 檢查帶有合法的背書資訊(主要是檢查簽名信息)
- 通過則返回正確, 否則返回錯誤訊息
鏈碼生命週期
管理Chaincode的生命週期四個命令:
安裝, 例項化, 升級, 打包, 簽名
package
, install
,instantiate
,upgrade
未來還會支援stop
和start
命令, 來禁用和重新啟用鏈程式碼
鏈程式碼成功安裝和例項化後,鏈程式碼處於活動狀態(正在執行),可通過invoke
命令呼叫處理事務
鏈程式碼可以在安裝後隨時升級
安裝鏈碼
install命令將鏈碼的原始碼和環境等內容封裝為一個鏈碼安裝打包檔案(Chaincode Install Package, CIP), 並傳輸到背書節點.
背書節點解析後一般會儲存在$CORE_PEER_FILESYSTEMPATH/chaincodes目錄下
安裝鏈碼只需要與Peer互動
進入到sacc目錄
$ cd ~/hyfa/fabric-samples/chaincode/sacc/
構建Chaincode
$ go get -u --tags nopkcs11 github.com/hyperledger/fabric/core/chaincode/shim
$ go build --tags nopkcs11
命令解釋
go get: 根據要求和實際情況從網際網路上下載或更新指定的程式碼包及其依賴包,並對它們進行編譯和安裝
-u: 利用網路來更新已有程式碼包及其依賴包。預設情況下,該命令只會從網路上下載本地不存在的程式碼包,而不會更新已有的程式碼包
go build: 加上可編譯的go原始檔可以得到一個可執行檔案
如果在執行 go build --tags nopkcsll
命令時出現如下錯誤
$GOPATH/src/github.com/hyperledger/fabric/vendor/github.com/miekg/pkcs11/pkcs11.go:26:18: fatal error: ltdl.h: No such file or directory
compilation terminated.
解決方式: 安裝 libltdl-dev
$ sudo apt install libltdl-dev
使用開發模式測試
正常情況下chaincode由對等體啟動和維護。然而,在“開發模式”下,鏈碼由使用者構建並啟動
如果沒有安裝Hyperledger Fabric Samples請先安裝
如果沒有下載Docker images請先下載
跳轉至fabric-samples
的chaincode-docker-devmode
目錄
$ cd ~/hyfa/fabric-samples/chaincode-docker-devmode/
使用docker images
檢視Docker映象資訊(顯示本地Docker Registry)
$ sudo docker images
會看到如下輸出
REPOSITORY TAG IMAGE ID CREATED SIZE
hyperledger/fabric-tools latest b7bfddf508bc About an hour ago 1.46GB
hyperledger/fabric-tools x86_64-1.1.0 b7bfddf508bc About an hour ago 1.46GB
hyperledger/fabric-orderer latest ce0c810df36a About an hour ago 180MB
hyperledger/fabric-orderer x86_64-1.1.0 ce0c810df36a About an hour ago 180MB
hyperledger/fabric-peer latest b023f9be0771 About an hour ago 187MB
hyperledger/fabric-peer x86_64-1.1.0 b023f9be0771 About an hour ago 187MB
hyperledger/fabric-javaenv latest 82098abb1a17 About an hour ago 1.52GB
hyperledger/fabric-javaenv x86_64-1.1.0 82098abb1a17 About an hour ago 1.52GB
hyperledger/fabric-ccenv latest c8b4909d8d46 About an hour ago 1.39GB
hyperledger/fabric-ccenv x86_64-1.1.0 c8b4909d8d46 About an hour ago 1.39GB
......
使用三個終端
終端1 啟動網路
$ cd ~/hyfa/fabric-samples/chaincode-docker-devmode/
該目錄下有
myc.tx
檔案
啟動網路
$ sudo docker-compose -f docker-compose-simple.yaml up -d
終端2 建立並啟動鏈碼
開啟第二個終端, 進入到chaincode-docker-devmode
目錄
$ cd ~/hyfa/fabric-samples/chaincode-docker-devmode/
進入CLI
chaincode容器的作用是為發簡化的方式建立並啟動鏈碼
$ sudo docker exec -it chaincode bash
命令提示符變為:
[email protected]:/opt/gopath/src/chaincode#
編譯
進入sacc目錄編譯chaincode
root@858726aed16e:/opt/gopath/src/chaincode# cd sacc
root@858726aed16e:/opt/gopath/src/chaincode/sacc# go build
執行chaincode
CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=mycc:0 ./sacc
mycc: 鏈碼名稱
0: 鏈碼初始版本號
終端3 使用鏈碼
安裝及例項化
$ cd ~/hyfa/fabric-samples/chaincode-docker-devmode/
$ sudo docker exec -it cli bash
進入CLI容器後執行如下命令安裝及例項化chaincode
容器中已經有
myc.block
、myc.tx
兩個檔案, 可以直接使用
peer chaincode install -p chaincodedev/chaincode/sacc -n mycc -v 0
peer chaincode instantiate -n mycc -v 0 -c '{"Args":["a","10"]}' -C myc
呼叫
進行呼叫,將a
的值更改為20
peer chaincode invoke -n mycc -c '{"Args":["set", "a", "20"]}' -C myc
執行成功, 輸出如下內容
......
...... Chaincode invoke successful. result: status:200 payload:"20"
......
查詢
查詢a
的值
peer chaincode query -n mycc -c '{"Args":["query","a"]}' -C myc
執行成功, 輸出: Query Result: 20
打包鏈碼及簽名
通過將鏈碼相關資料進行封裝, 可以實現對其進行打包和簽名操作
打包
peer chaincode package -n mycc -p chaincodedev/chaincode/sacc -v 0 -s -S -i "AND('OrgA.admin')" ccpack.out
-s: 建立角色支援的CC部署規範包, 而不是原始的CC部署規範
-S: 如果建立CC部署規範方案角色支援,也與本地MSP簽名
-i: 指定例項化策略
打包後的檔案, 可以直接用於install操作, 如:
peer chaincode install ccpack.out
簽名
對一個打包檔案進行簽名操作(添加當前MSP簽名到簽名列表中)
peer chaincode signpackage ccpack.out signedccpack.out
升級鏈碼
退出終端3, 停止終端2的服務
終端2中重新執行chaincode
$ sudo docker exec -it chaincode bash
cd sacc
go build
CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=mycc:1 ./sacc
注意版本為 1.0
, 舊版本為 0
終端3
開啟終端3, 進入CLI容器
$ sudo docker exec -it cli bash
安裝及升級
peer chaincode install -p chaincodedev/chaincode/sacc -n mycc -v 1
peer chaincode upgrade -n mycc -v 1 -c '{"Args":["a", "100"]}' -C myc
注意版本號必須一致
在對某鏈碼程式碼升級前, 推薦先將所有該鏈碼的容器停止, 並從Peer上備份並移除舊鏈碼部署檔案. 之後先在個別Peer節點上部署新鏈碼, 對原有資料進行測試, 成功後再在其它節點上進行升級操作
查詢
查詢a
的值
peer chaincode query -n mycc -c '{"Args":["query","a"]}' -C myc
執行成功, 輸出: Query Result:100