Fabric实战(10)链码(chaincode)开发-shim包API

本文章所有操作基于的操作系统版本是:ubuntu16.04 64位
本文章基于的Fabric网络环境是《Fabric实战(2)运行一个简单的fabric网络(容器外)》

1 golang版本的chaincode的代码

1.1 chaincode源代码结构

下面看一最简单的chaincode代码以及相关的解释:

//包名
//一个chaincode通常是一个golang源码文件,这个包名必须是main
package main

//导入包
//chaincode需要引入一些Fabric提供的系统包,这些系统包提供了chaincode和Fabirc进行通信的接口。
import (
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
)

//定义chaincode主结构体
//每个chaincode都需要定义个结构体,结构体的名字可以是任意符合golang命名规范的字符串。chaincode的住结构体必须实现Chaincode接口
//   type Chaincode interface {
   
//	        Init(stub ChaincodeStubInterface) pb.Response
//	        Invoke(stub ChaincodeStubInterface) pb.Response
//   }
type SimpleChaincode struct {
   
}

//Init方法
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()
	if function == "invoke" {
   
		return t.invoke(stub, args)
	}

	return shim.Error("Invalid invoke function name. Expecting \"invoke\"")
}

func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   
	return shim.Success(nil)
}

//main函数
//调用shim包的Start方法,启动chaincode,如果启动成功,这个函数会一直阻塞在这个地方,不会退出。
func main() {
   
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
   
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

1.1.1 Init方法

Init方法是chaincode的初始化方法,当执行peer chaincode instantiate实例化chaincode的时候会调用该方法,同时-c 参数后面内容会作为参数传入Init方法中,以下面的实例化命令为例:

peer chaincode instantiate -o orderer.simple-network.com:7050 -C testchannel -n r_test_cc6 -v 1.0    -c '{"Args":["init", "a", "100", "b", "200"]}'  -P "OR ('Org1MSP.member', 'Org2MSP.member')"

上面的命令给chaincode传入4个参数"a", “100”, “b” ,“200”。注意命令中Args后面一共有五个参数,其中第一个参数init是固定值,后面才是参数。在Init函数中可以通过下面的方法获取参数:

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
   
    //获取客户端传入的参数,args是一个字符串切片,存储传入的字符串参数
    _, args := stub.GetFunctionAndParameters()
	return shim.Success(nil)
}

1.1.2 Invoke方法

Invoke方法的主要作用是写入数据。在执行命令peer chaincode invoke的时候会调用这个方法,同时会把命令中-c后面的参数传入Invoke方法中。以下面的invoke命令为例:

peer chaincode invoke -o orderer.simple-network.com:7050 -C testchannel -n r_test_cc6 -v 1.0    -c '{"Args":["invoke", "a", "b", "1"]}'

上面的命令调用chaincode的Invoke方法并传入三个参数, 注意Args后面数组中的第一个值"invoke"是默认的固定参数。

1.2 shim包的方法

shim包常用方法

Success                     #向客户端返回正确消息
Error                       #向客户端返回错误消息
Start                       #启动chaincode
LogLevel                    #将字符串类型转化成LoggingLevel类型
SetLoggingLevel             #设置链码shim包运行日志等级
IsEnabledForLogLevel        #检查合约的是否使能制定的等级

1.2.1 Success方法

Success方法负责将正确的消息返回给调用chaincode的客户端。

//定义
func Success(payload []byte) pb.Response 

//示例
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
   
    return shim.Success([]byte("sucess invoke"))
}

1.2.2 Error方法

Error方法负责将错误的信息返回给调用Chaincode的客户端。

// 定义
func Error(msg string) pb.Response 

//示例
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
   
    return shim.Error([]byte("fail invoke"))
}

1.2.3 SetLoggingLevel方法

设置合约的shim包运行日志等级

// 定义
func SetLoggingLevel(level LoggingLevel) 

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

    //将"debug"字符串转换成LoggingLevel类型
    logleve, _ := shim.LogLevel("DEBUG")
    
    //设置日志等级为debug
	shim.SetLoggingLevel(logleve)
	
    return shim.Success([]byte("sucess invoke"))
}

日志等级如下:

"CRITICAL"      0
"ERROR"         1
"WARNING"       2
"NOTICE"        3
"INFO"          4
"DEBUG"         5

1.2.4 IsEnabledForLogLevel方法

检查合约是否使能了日志等级

//定义
func IsEnabledForLogLevel(logLevel string) bool 

//示例
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
   
    enabled := shim.IsEnabledForLogLevel("DEBUG")
	if enabled{
   
		fmt.Println("Contract enabled debug level")
	}
	 return shim.Success([]byte("sucess invoke"))
}

注意:只要IsEnabledForLogLevel的参数小于当前的等级,都是返回true。比如当前的等级是DEBUG,IsEnabledForLogLevel传入的参数是ERROR,返回值也是true

1.3 shim包ChaincodeStubInterface接口

Shim包中有一个接口ChaincodeStubInterface,在Invoke方法和Query方法方法中该接口作为参数传入方法中。ChaincodeStubInterface接口提供了一组方法,通过该组方法可以非常方便的操作账本数据。ChaincodeStubInterface接口的核心方法大概可以分为四大类:

  • 系统管理
  • 存储管理
  • 交易管理
  • 调用外部chaincode

方法名列表:

GetFunctionAndParameters        #获取调用者传入的参数
GetArgs                         #获取调用者传入参数,返回二维字节切片
GetStringArgs                   #获取调用者传入参数,返回一维字符串切片
GetArgsSlice                    #获取调用者传入参数,返回字节切片
PutState                        #存储数据到账本
GetState                        #从账本中获取指定的数据  
DelState                        #删除账本中的数据
GetStateByRange                 #查询指定key指定范围的数据
CreateCompositeKey              #创建复合键   
GetStatePyPartialCompositeKey   #通过复合键取值
SplitCompositeKey               
  • 12
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值