fabric 智能合约做模块化开发

序言

fabric1.0 开发chaincode的例子中一个chaincode都是由一个go文件组成,当做模块化开发时总不能多个人使用同一个go文件吧?

仔细研究了fabric1.0中的examples\chaincode\go\utxo 的例子,是可以是实现 一个chaincode由多个go文件组成的。

仿照utxo的例子,写一个实现了机构注册和机构查询的简单的功能,由2个go文件组成,第一个go文件是chaincode的main函数文件,第二个go文件实现了真正的功能,以此类推,再多的功能可以由第3个,第n个go文件实现,不同类型的go文件放到不同的子目录中,从而实现了chaincode的模块化开发。

1)建立主目录和子模块目录

       在GOPATH目录下 建立一个测试目录 mytest.com,在mytest.com下建立orgbase子模块目录

2)建立chaincode主程序

     在mytest.com目录下建立一个testmain.go的chaincode主程序文件,

     文件中必须包含main函数,Init函数和Invoke函数,文件内容如下:

package main

import (

"fmt"

"mytest.com/orgbase"

"github.com/hyperledger/fabric/core/chaincode/shim"

pb "github.com/hyperledger/fabric/protos/peer"

)

/*

定义SimpleChaincode

*/

type SimpleChaincode struct {

}

/*

主程序初始化

*/

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {

return shim.Success(nil)

}

/*

机构开户

*/

func (t *SimpleChaincode) orgReg(stub shim.ChaincodeStubInterface, args []string) pb.Response {

return orgbase.OrgReg(stub, args)

}

/*

机构查询

*/

func (t *SimpleChaincode) orgQry(stub shim.ChaincodeStubInterface, args []string) pb.Response {

return orgbase.OrgQry(stub, args)

}

/*

所有的程序入口都在这里定义

*/

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {

function, args := stub.GetFunctionAndParameters()

if function == "orgReg" {

return t.orgReg(stub, args)

} else if function == "orgQry" {

return t.orgQry(stub, args)

}

jsonResp := "{\"errCode\":\"0\",\"errMsg\":错误的函数名称,请检查\"}"

return shim.Success([]byte(jsonResp))

}

/*

启动主程序

*/

func main() {

err := shim.Start(new(SimpleChaincode))

if err != nil {

fmt.Printf("Error starting Simple chaincode: %s", err)

}

}

3)建立模块子程序

   在 orgbase子目录下建立orgmanage.go文件,文件内容如下:

package orgbase

import (

"encoding/json"

"fmt"

"time"

"github.com/hyperledger/fabric/core/chaincode/shim"

pb "github.com/hyperledger/fabric/protos/peer"

)

/*

机构开户

*/

func OrgReg(stub shim.ChaincodeStubInterface, arg []string) pb.Response {

_, args := stub.GetFunctionAndParameters()

var orgId string

var orgPk string

var Aval string

var err error

orgId = args[0]

orgPk = "org_" + orgId

Aval = args[1]

var dat map[string]interface{}

if err := json.Unmarshal([]byte(Aval), &dat); err != nil {

jsonResp := "{\"errCode\":\"001\",\"errMsg\":\"系统错误\"}"

return shim.Success([]byte(jsonResp + err.Error()))

}

if len(dat["orgId"].(string)) == 0 {

return shim.Success([]byte("{\"errCode\":\"001\",\"errMsg\":\"orgId is null\"}"))

}

if len(dat["oraName"].(string)) == 0 {

return shim.Success([]byte("{\"errCode\":\"001\",\"errMsg\":\"oraName is null\"}"))

}

Avalbytes, _ := stub.GetState(orgPk)

if Avalbytes != nil {

jsonResp := "{\"errCode\":\"001\",\"errMsg\":\"该机构ID已经存在\"}"

return shim.Success([]byte(jsonResp))

}

err = stub.PutState(orgPk, []byte(Aval))

if err != nil {

jsonResp := "{\"errCode\":\"001\",\"errMsg\":\"系统错误\"}"

return shim.Success([]byte(jsonResp + err.Error()))

}

jsonResp := "{\"errCode\":\"0\",\"errMsg\":\"机构注册成功\"}"

fmt.Printf("orgReg Response:%s\n", jsonResp)

return shim.Success([]byte(jsonResp))

}

/*

机构查询

*/

func OrgQry(stub shim.ChaincodeStubInterface, args []string) pb.Response {

var orgId string

var orgPk string

var err error

if len(args) != 1 {

return shim.Error("Incorrect number of arguments. Expecting name of the person to query")

}

orgId = args[0]

orgPk = "org_" + orgId

Avalbytes, err := stub.GetState(orgPk)

if err != nil {

jsonResp := "{\"errCode\":\"org001\",\"errMsg\":\"Failed to get state for " + orgId + "\"}"

return shim.Success([]byte(jsonResp))

}

if Avalbytes == nil {

jsonResp := "{\"errCode\":\"org002\",\"errMsg\":\"机构ID不存在 " + orgId + "\"}"

return shim.Success([]byte(jsonResp))

}

jsonResp := "{\"errCode\":\"0\",\"errMsg\":\"\",\"list\":" + string(Avalbytes) + "}"

fmt.Printf("orgQry Response:%s\n", jsonResp)

fmt.Println(time.Now().Format("2006-01-02 15:04:05:006") + "-----")

return shim.Success([]byte(jsonResp))

}

4)目录结构如下:

       $GOPATH
  -- mytest.com
     -- testmain.go
     -- orgbase
        -- orgmagage.go

5) 部署智能合约

     使用  peer chaincode install -n mycc -v 1.0 -p mytest.com  >&log.txt

      可以将mytest.com目录下的所有go文件发布成一个chaincode

6)实例化智能合约

        使用 peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mycc -v 1.0 -c '{"Args":["init"]}' -P "OR('Org1MSP.member','Org2MSP.member')" >&log.txt

          实例化刚才部署的 mycc 智能合约,查看log.txt可以查询部署和实例化是否成功。

 


你可能感兴趣的:(fabric)