超级账本HyperLedger: Fabric Chaincode(智能合约、链码)开发方法

Tags: HyperLedger 

目录

说明

这是“网易云课堂IT技术快速入门学院”使用的素材。操作、配置文件和代码讲解视频在网易云课堂《HyperLeger Fabric进阶实战课》第一章中。

Hyperledger fabric的chaincode可以使用Go、Node.js、Java等语言开发。Chaincode将在Peer节点上以容器的方式运行,实现与背书节点进程之间的隔离。这里讲解一下怎样用Go语言开发Chaincode。

相关笔记

视频演示:

文字介绍:

问题汇总:

Chaincode代码结构

chaincode的代码结构大体如下,直接调用shim.Start()启动chaincode:

package main

import (
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

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

然后需要做的就是为SimpleChaincode实现一些接口,其中InitInvoke是约定好的,必须有的。

实现Init接口

首先增加一个Init方法,这个方法将在chaincode初始化的时候调用,用来初始化chaincode。

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
	fmt.Println("ex02 Init")
	_, args := stub.GetFunctionAndParameters()

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error

	if len(args) != 4 {
		return shim.Error("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return shim.Error("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return shim.Error("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return shim.Error(err.Error())
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return shim.Error(err.Error())
	}

	return shim.Success(nil)
}

实现Invoke接口

通过Invoke接口,调用请求将被转发到Invoke,然后可以在这里将请求转发给不通的函数处理:

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    fmt.Println("ex02 Invoke")
    function, args := stub.GetFunctionAndParameters()
    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)
    }

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

在Init和Invoke方法中,都有一个stub参数,通过这个参数可以做很多操作,例如读取数据、写入数据、查看提案等。

shim.ChaincodeStubInterfac: 可以使用的ChainCode接口

接口在“github.com/hyperledger/fabric/core/chaincode/shim”中的ChaincodeStubInterface中定义。

ChaincodeStubInterface : interface
    [methods]
   +CreateCompositeKey(objectType string, attributes []string) : string, error
   +DelState(key string) : error
   +GetArgs() : [][]byte
   +GetArgsSlice() : []byte, error
   +GetBinding() : []byte, error
   +GetChannelID() : string
   +GetCreator() : []byte, error
   +GetDecorations() : map[string][]byte
   +GetFunctionAndParameters() : string, []string
   +GetHistoryForKey(key string) : HistoryQueryIteratorInterface, error
   +GetQueryResult(query string) : StateQueryIteratorInterface, error
   +GetSignedProposal() : *pb.SignedProposal, error
   +GetState(key string) : []byte, error
   +GetStateByPartialCompositeKey(objectType string, keys []string) : StateQueryIteratorInterface, error
   +GetStateByRange(startKey, endKey string) : StateQueryIteratorInterface, error
   +GetStringArgs() : []string
   +GetTransient() : map[string][]byte, error
   +GetTxID() : string
   +GetTxTimestamp() : *timestamp.Timestamp, error
   +InvokeChaincode(chaincodeName string, args [][]byte, channel string) : pb.Response
   +PutState(key string, value []byte) : error
   +SetEvent(name string, payload []byte) : error
   +SplitCompositeKey(compositeKey string) : string, []string, error

读取传入参数

传入参数通过stub.GetFunctionAndParameters()获取,得到的是一个数组,记录了所有传入参数。

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
	function, args := stub.GetFunctionAndParameters()
	..
	if len(args) != 4 {
		return shim.Error("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	...
	}

写入账本

使用stub.PutState()方法以key-value的方式将数据写入账本:

//A:="a"
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
if err != nil {
	return shim.Error(err.Error())
}

//B:="a"
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
if err != nil {
	return shim.Error(err.Error())
}

查询账本

使用stub.GetState()方法查询区块:

//A:="a"
Avalbytes, err := stub.GetState(A)
if err != nil {
	jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
	return shim.Error(jsonResp)
}

返回值

使用stub.Success()或者stub.Error()将数据返回给调用者:

func Success(payload []byte) pb.Response {
	return pb.Response{
		Status:  OK,
		Payload: payload,
	}
}

func Error(msg string) pb.Response {
	return pb.Response{
		Status:  ERROR,
		Message: msg,
	}
}

接下来…

合约的使用参考:《超级账本HyperLedger:Fabric的Chaincode(智能合约、链码)开发、使用演示》

更多关于超级账本和区块链的文章

参考

  1. chaincode interface
  2. HyperledgerFabric的使用
  3. 《超级账本HyperLedger:Fabric的Chaincode(智能合约、链码)开发、使用演示》
  4. HyperLedger Fabric ChainCode开发——shim.ChaincodeStubInterface用法

HyperLedger

  1. hyperledger fabric 1.3.0 多节点手动部署
  2. 【视频】超级账本HyperLedger: Fabric源码走读(一):项目构建与代码结构
  3. 【视频】超级账本HyperLedger: Fabric Go SDK的使用
  4. 【视频】超级账本HyperLedger: Fabric使用kafka进行区块排序(共识)
  5. 超级账本HyperLedger: Fabric 1.2.0使用时遇到的问题
  6. 超级账本HyperLedger: Fabric的Chaincode开发过程中遇到的问题
  7. 【视频】超级账本HyperLedger: 为Fabric的Peer节点配置CouchDB
  8. 【视频】超级账本HyperLedger: Fabric从1.1.0升级到1.2.0
  9. 【视频】超级账本HyperLedger: Fabric源码走读(零):源代码阅读环境准备
  10. 【视频】超级账本HyperLedger: Fabric的Chaincode(智能合约、链码)开发、使用演示
  11. 超级账本HyperLedger: Fabric Node.js SDK使用时遇到的问题
  12. 超级账本HyperLedger: Fabric Golang SDK使用时遇到的问题
  13. 超级账本HyperLedger: FabricCA的级联使用(InterMediateCA)
  14. 【视频】超级账本HyperLedger: 使用Ansible进行Fabric多节点分布式部署(实战)
  15. 超级账本HyperLedger: Fabric掰开揉碎,一文解惑
  16. 超级账本HyperLedger: Fabric Channel配置的读取转换
  17. 【视频】超级账本HyperLedger: Fabric进阶,在已有的Channel中添加新的组织
  18. 超级账本HyperLedger: 超级账本工作组旗下项目介绍
  19. 超级账本HyperLedger: Fabric Chaincode(智能合约、链码)开发方法
  20. 【视频】超级账本HyperLedger: Fabric-CA的使用演示(两个组织一个Orderer三个Peer)
  21. 超级账本HyperLedger: FabricCA的基本概念与用法讲解
  22. 【视频】超级账本HyperLedger: Fabric的全手动、多服务器部署教程
  23. 超级账本HyperLedger: Explorer安装使用
  24. 【视频】超级账本HyperLedger: Fabric nodejs SDK的使用
  25. 超级账本HyperLedger: Fabric部署过程时遇到的问题汇总
  26. 超级账本HyperLedger: Cello部署和使用
  27. 超级账本HyperLedger: Fabric的基本概念与基础用法

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  系统软件  程序语言  运营经验  水库文集  网络课程  微信网文  发现知识星球