Fabric2.0 新特性實踐:通道成員可擴展鏈碼

  承接上文:Hyperledger Fabric 2.0新特性,Fabric2.0版本允許組織去擴展鏈碼,也就是說通道成員之間的鏈碼包可能會不同,這麼做的好處是每個組織可以根據自身利益增加自己的業務邏輯。
  爲測試這一特性,本文將會對比Fabric1.4版本和Fabric2.0版本,閱讀過程中注意當前版本,及時切換到不同分支。

改造鏈碼

  測試網絡選用:fabric-samples/first-network
  鏈碼選用:sacc
  在本文中,我們基於sacc構建了另一個鏈碼sacc-check,相對於sacc增加了一個條件校驗:如果key爲age,則返回錯誤。
  進入fabric-samples/chaincode/sacc目錄,sacc.go原代碼:

// Set stores the asset (both key and value) on the ledger. If the key exists,
// it will override the value with the new one
func set(stub shim.ChaincodeStubInterface, args []string) (string, error) {
	if len(args) != 2 {
		return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value")
	}

	err := stub.PutState(args[0], []byte(args[1]))
	if err != nil {
		return "", fmt.Errorf("Failed to set asset: %s", args[0])
	}
	return args[1], nil
}

  我們稍作修改,增加前面提到的校驗:

// Set stores the asset (both key and value) on the ledger. If the key exists,
// it will override the value with the new one
func set(stub shim.ChaincodeStubInterface, args []string) (string, error) {
	if len(args) != 2 {
		return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value")
	}
    if args[0] == "age" {
        return "",fmt.Errorf("錯誤的key")
    }
	err := stub.PutState(args[0], []byte(args[1]))
	if err != nil {
		return "", fmt.Errorf("Failed to set asset: %s", args[0])
	}
	return args[1], nil
}

基於1.4版本測試

  按照上節修改鏈碼

cd fabric-samples/chaincode
cp -r sacc sacc-check
cd sacc-check
vim sacc.go

  進入fabric-samples/first-network目錄執行,默認通道testchannel,鏈碼mycc:

./byfn.sh up

  peer0.org1.example.com安裝鏈碼sacc

 docker exec cli peer chaincode install -n sacc -v 1.0 -p github.com/chaincode/sacc

  peer0.org2.example.com安裝鏈碼sacc

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer chaincode install -n sacc -v 1.0 -p github.com/chaincode/sacc-check

  可通過以下命令查看鏈碼是否已安裝成功,查詢結果中Id是不同的。

# peer0.org1.example.com
docker exec cli peer chaincode list --installed
# peer0.org2.example.com
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer chaincode list --installed

  實例化鏈碼

docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C testchannel -n sacc -v 1.0 -c '{"Args": ["name","kc"]}' -P "AND('Org1MSP.member','Org2MSP.member')"

  調用合約查詢

# peer0.org1.example.com
docker exec cli peer chaincode query -C testchannel -n sacc -c '{"Args":["query","name"]}'
# peer0.org2.example.com
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer chaincode query -C testchannel -n sacc -c '{"Args":["query","name"]}'

  在peer0.org1.example.com查詢返回結果:kc,在peer0.org2.example.com返回錯誤:

Error: endorsement failure during query. response: status:500 message:"failed to execute transaction 0b0523dac965b32fff0fc0faadb3270646efc256198b6b8a42856006ccdb2ddd: [channel testchannel] failed to get chaincode container info for sacc:1.0: could not get chaincode code: chaincode fingerprint mismatch: data mismatch" 

  報錯原因:鏈碼不匹配。可見在1.4版本中是不支持組織安裝不同鏈碼的。

基於2.0.1版本測試

  Fabric 2.0 啓用了新的鏈碼週期,我們按照下圖進行測試:
在這裏插入圖片描述
  測試網絡仍然選擇first-network,通道mychannel

cd fabric-samples/first-network
./byfn.sh up

  首先按上文編輯鏈碼:

cd fabric-samples/chaincode
cp -r sacc sacc-check
cd sacc-check
vim sacc.go

  生成vendor目錄:

cd chaincode/sacc
GO111MODULE=on go mod vendor
cd ../sacc-check
GO111MODULE=on go mod vendor

  打包鏈碼:

docker exec cli peer lifecycle chaincode package sacc.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/sacc/ --label sacc_1
docker exec cli peer lifecycle chaincode package sacc-check.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/sacc-check/ --label sacc_1
docker exec cli ls

  執行結果如下圖所示:
在這裏插入圖片描述
  安裝鏈碼:

# peer0.org1.example.com
docker exec cli peer lifecycle chaincode install sacc.tar.gz
# peer0.org2.example.com
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer lifecycle chaincode install sacc-check.tar.gz

  查詢已安裝鏈碼,得到packageID(注意此處兩個節點返回的packageID是不同的):

# peer0.org1.example.com
docker exec cli peer lifecycle chaincode queryinstalled
# peer0.org2.example.com
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer lifecycle chaincode queryinstalled

  peer0.org1.example.com返回結果:Package ID:sacc_1:a615a5892af0e8ab0a17851e76f995582138f6e8853a2fa782f50a05c82390d2, Label: sacc_1
  peer0.org2.example.com返回結果:Package ID:sacc_1:153bdd87b0d61052590bd154d6418acc9eaf7752b68b1ef40a231391172875ce, Label: sacc_1
  組織同意鏈碼定義:

#Org1
docker exec cli peer lifecycle chaincode approveformyorg --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name sacc --version 1 --sequence 1 --waitForEvent --package-id sacc_1:a615a5892af0e8ab0a17851e76f995582138f6e8853a2fa782f50a05c82390d2
#Org2
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer lifecycle chaincode approveformyorg --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name sacc --version 1 --sequence 1 --waitForEvent --package-id sacc_1:153bdd87b0d61052590bd154d6418acc9eaf7752b68b1ef40a231391172875ce

  提交鏈碼定義:

docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --channelID mychannel --name sacc --version 1 --sequence 1

  調用合約,此處參數傳入“name”:

docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -C mychannel -n sacc -c '{"Args":["set","name","kc"]}'

  合約調用成功後,執行查詢操作:

# peer0.org1.example.com
docker exec cli peer chaincode query -C mychannel -n sacc -c '{"Args":["query","name"]}'
# peer0.org2.example.com
docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer chaincode query -C mychannel -n sacc -c '{"Args":["query","name"]}'

  查詢結果如下圖所示:
在這裏插入圖片描述
  sacc-check/sacc.go我們做了校驗:不能通道調用鏈碼設置"age",我們這裏做個測試

docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -C mychannel -n sacc -c '{"Args":["set","age","30"]}'

  下圖顯示了執行結果:這裏報錯“錯誤的key”,由此我們完成了測試。在這裏插入圖片描述

總結

  Fabric2.0這一特性,使得不同組織可以根據自身利益安裝智能合約。當然最終合約調用是否成功和背書策略也有關係,在上節演示時,我們使用的是默認的背書策略即大多數組織同意,由於我們選用的是兩組織的first-network網絡,因此此處需要兩個組織均同意,由此上節交易不能通過。在實際應用場景中,需要綜合考慮相關問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章