1. 程式人生 > >Fabric--鏈碼的概念與使用

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

交易提交前根據背書策略進行檢查

驗證過程:

  1. 首先解析出交易結構, 並對交易結構格式進行校驗
  2. 檢查交易的讀集合中元素版本跟本地賬本中版本一致
  3. 檢查帶有合法的背書資訊(主要是檢查簽名信息)
  4. 通過則返回正確, 否則返回錯誤訊息

鏈碼生命週期

管理Chaincode的生命週期四個命令:

安裝, 例項化, 升級, 打包, 簽名

packageinstallinstantiateupgrade

未來還會支援stopstart命令, 來禁用和重新啟用鏈程式碼

鏈程式碼成功安裝和例項化後,鏈程式碼處於活動狀態(正在執行),可通過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-sampleschaincode-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.blockmyc.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