1. 程式人生 > >實戰:區塊鏈hyperledger fabric 初體驗 - 3: 鏈碼實例安裝、實例化、調用及代碼

實戰:區塊鏈hyperledger fabric 初體驗 - 3: 鏈碼實例安裝、實例化、調用及代碼

區塊鏈 hyperledger fabric blockchain

本文鏈碼實例為Fabric 官方實例examples/chaincode/go/chaincode_example02,實現簡單的轉賬功能


進入到cli容器裏面

$ docker exec -it fabric-cli bash

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
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt

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')" \
--tls true \
--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 {

......

//提取參數

_, args := stub.GetFunctionAndParameters()
var A, B string // Entities
var Aval, Bval int // Asset holdings

......

// 初始化鏈碼

A = args[0]
Aval, err = strconv.Atoi(args[1])

......

 B = args[2]

Bval, err = strconv.Atoi(args[3])

......

// 把狀態寫入賬本

err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
......
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
Bval = Bval + 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: 鏈碼實例安裝、實例化、調用及代碼