Fabric Chaincode測試狀態(tài)機

開發(fā)測試代碼

cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/go
mkdir fsmtest && cd fsmtest && vim fsmtest.go

package main

import (
    "fmt"
    "github.com/hyperledger/fabric/core/chaincode/shim"
    pb "github.com/hyperledger/fabric/protos/peer"
    "github.com/looplab/fsm"
)

type SimpleChaincode struct {
}

func InitFSM(initStatus string) *fsm.FSM {
    f := fsm.NewFSM(
        initStatus,
        fsm.Events{
            {Name: "Submit", Src: []string{"Draft"}, Dst: "Submited"},
            {Name: "Approve", Src: []string{"Submited"}, Dst: "L1Approved"},
            {Name: "Reject", Src: []string{"Submited"}, Dst: "Reject"},
            {Name: "Approve", Src: []string{"L1Approved"}, Dst: "Complete"},
            {Name: "Reject", Src: []string{"L1Approved"}, Dst: "Reject"},
        },
        fsm.Callbacks{},
    )
    return f
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
    return shim.Success(nil)
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    function, args := stub.GetFunctionAndParameters()
    fmt.Println("invoke is running " + function)
    if function == "Draft" {
        return t.Draft(stub, args)
    } else if function == "Submit" {
        return FsmEvent(stub, args, "Submit")
    } else if function == "Approve" {
        return FsmEvent(stub, args, "Approve")
    } else if function == "Reject" {
        return FsmEvent(stub, args, "Reject")
    }

    return shim.Error("Receive unknown function invocation")
}

func (t *SimpleChaincode) Draft(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    formNumber := args[0]
    status := "Draft"
    stub.PutState(formNumber, []byte(status))
    return shim.Success([]byte(status))
}

func FsmEvent(stub shim.ChaincodeStubInterface, args []string, event string) pb.Response {
    formNumber := args[0]
    bstatus, err := stub.GetState(formNumber)
    if err != nil {
        return shim.Error("Query form status fail, form number:" + formNumber)
    }

    status := string(bstatus)
    fmt.Println("Form[" + formNumber + "] status:" + status)
    f := InitFSM(status)
    err = f.Event(event)
    if err != nil {
        return shim.Error("Current status is " + status + " does not support event:" + event)
    }

    status = f.Current()
    fmt.Println("New status:" + status)
    stub.PutState(formNumber, []byte(status))
    return shim.Success([]byte(status))
}

func main() {
    err := shim.Start(new(SimpleChaincode))
    if err != nil {
        fmt.Printf("Error starting SimpleChaincode: %s", err)
    }
}

下載依賴包

go get github.com/looplab/fsm

修改docker-compose-cli.yaml

volumes:
  - /root/golang/src/github.com/looplab/fsm:/opt/gopath/src/github.com/looplab/fsm

啟動測試網(wǎng)絡(luò)

cd $GOPATH/src/github.com/hyperledger/fabric/examples/e2e_cli
./network_setup.sh up

進入fabric client

docker exec -it cli bash

安裝鏈碼

peer chaincode install -n fsmtest -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/fsmtest

實例化鏈碼

ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n fsmtest -v 1.0 -c '{"Args":[]}'

測試運行鏈碼

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n fsmtest -c '{"Args":["Draft","EXP1"]}'
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 00a Chaincode invoke successful. result: status:200 payload:"Draft"

peer chaincode invoke -o orderer.example.com:7050  --tls true --cafile $ORDERER_CA -C mychannel -n fsmtest -c '{"Args":["Submit","EXP1"]}'
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 00a Chaincode invoke successful. result: status:200 payload:"Submited"

peer chaincode invoke -o orderer.example.com:7050  --tls true --cafile $ORDERER_CA -C mychannel -n fsmtest -c '{"Args":["Approve","EXP1"]}'
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 00a Chaincode invoke successful. result: status:200 payload:"L1Approved"

peer chaincode invoke -o orderer.example.com:7050  --tls true --cafile $ORDERER_CA -C mychannel -n fsmtest -c '{"Args":["Approve","EXP1"]}'
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 00a Chaincode invoke successful. result: status:200 payload:"Complete"

peer chaincode invoke -o orderer.example.com:7050  --tls true --cafile $ORDERER_CA -C mychannel -n fsmtest -c '{"Args":["Approve","EXP1"]}'
Error: Error endorsing invoke: rpc error: code = Unknown desc = chaincode error (status: 500, message: Current status is Complete does not support event:Approve) - <nil>

參考文檔

在Fabric ChainCode中使用狀態(tài)機
http://www.cnblogs.com/studyzy/p/7492637.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容