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

本文鏈碼實例爲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

圖片.png

修改相關環境變量和參數,重複步驟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

圖片.png

3.測試鏈碼

3.1 查詢初始值


# peer chaincode query -C "businesschannel" -n "exp02" -c '{"Args":["query","a"]}'

圖片.png


# peer chaincode query -C "businesschannel" -n "exp02" -c '{"Args":["query","b"]}'

圖片.png

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

圖片.png

3.3 查詢轉賬結果

# peer chaincode query -C "businesschannel" -n "test02" -c '{"Args":["query","a"]}'

圖片.png

查詢另一個節點{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

圖片.png

結果一致。

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)

}


未完待續......

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