實戰:區塊鏈hyperledger fabric 初體驗 - 3: 鏈碼實例安裝、實例化、調用及代碼
進入到cli容器裏面
1. 鏈碼安裝
以在org1, peer0 為例
1.1 設置環境變量
export CORE_PEER_LOCALMSPID=Org2MSP export CORE_PEER_ADDRESS=peer1.org2.example.com:7051 export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/users/[email protected]/msp |
1.2 安裝鏈碼
# peer chaincode install -n test02 -v 1.0 -p examples/chaincode/go/chaincode_example02 |
修改相關環境變量和參數,重復步驟1.1 和1.2,在{org1, peer1},{org2, peer0},{org2, peer1}上安裝鏈碼
2.鏈碼實例化
以下過程在任意一個節點執行一次就行。
peer chaincode instantiate \ -o orderer.example.com:7050 \ -C "businesschannel" \ -n test02 \ -v 1.0 \ -c '{"Args":["init","a","100","b","200"]}' \ -P "OR ('Org1MSP.member','Org2MSP.member')" \ --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem |
3.測試鏈碼
3.1 查詢初始值
# peer chaincode query -C "businesschannel" -n "exp02" -c '{"Args":["query","a"]}' |
# peer chaincode query -C "businesschannel" -n "exp02" -c '{"Args":["query","b"]}' |
3.2 轉賬:從"a" 的賬戶轉賬10到"b" 的賬戶
peer chaincode invoke \ -o orderer.example.com:7050 \ -C "businesschannel" \ -n "test02" \ -c '{"Args":["invoke","a","b","10"]}' \ --tls true \ --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem |
3.3 查詢轉賬結果
# peer chaincode query -C "businesschannel" -n "test02" -c '{"Args":["query","a"]}' |
查詢另一個節點{org2,peer1} 的賬本
export CORE_PEER_LOCALMSPID=Org2MSP export CORE_PEER_ADDRESS=peer1.org2.example.com:7051 export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/users/[email protected]/msp export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.cr |
結果一致。
4.代碼解析
4.1 引入必要的包
import ( "fmt" "strconv" "github.com/hyperledger/fabric/core/chaincode/shim" pb "github.com/hyperledger/fabric/protos/peer" ) |
"github.com/hyperledger/fabric/core/chaincode/shim":shim包提供了鏈碼與賬本交互的中間層。
4.2 初始化
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { ...... //提取參數 var A, B string // Entities var Aval, Bval int // Asset holdings ...... // 初始化鏈碼 Aval, err = strconv.Atoi(args[1]) ...... B = args[2] Bval, err = strconv.Atoi(args[3])...... // 把狀態寫入賬本 ...... err = stub.PutState(B, []byte(strconv.Itoa(Bval))) ...... return shim.Success(nil) } |
4.3 Inovke方法
獲取function值
function, args := stub.GetFunctionAndParameters() |
根據function值不同,執行不同的分支處理邏輯。
if function == "invoke" { // Make payment of X units from A to B return t.invoke(stub, args) } else if function == "delete" { // Deletes an entity from its state return t.delete(stub, args) } else if function == "query" { // the old "Query" is now implemtned in invoke return t.query(stub, args) } |
query分支
func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { ...... A = args[0] // 從賬本獲得狀態值Avalbytes, err := stub.GetState(A) ...... } |
invoke分支
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { ...... //從賬本獲取"a"的值 Avalbytes, err := stub.GetState(A) ...... //從賬本獲取"b"的值 Bvalbytes, err := stub.GetState(B) ...... //執行轉賬 Aval = Aval - X ...... //結果計入賬本 err = stub.PutState(A, []byte(strconv.Itoa(Aval))) ...... err = stub.PutState(B, []byte(strconv.Itoa(Bval))) ......} |
delete分支
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { ...... //刪除一個實體 err := stub.DelState(A) |
}
實戰:區塊鏈hyperledger fabric 初體驗 - 3: 鏈碼實例安裝、實例化、調用及代碼