【2020秋冬】【区块链】fabric 链码的简单编写

原计划等node-SDK的代码搞完一起写个总结,结果实验环境要在今天被清空了
先把链码的基础编写(增删改查)总结出来

链码一,对{name ; num} 形式数据进行増,删,查操作

安装新链码

peer chaincode install -n mycc -v 2.0 -p github.com/hyperledger/fabric/examples/chaincode/go

实例化新链码

peer chaincode upgrade -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init"]}'

导入包;声明结构体;初始化;

package main

import (
	"fmt"
	"strconv"

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

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

func (t *SimpChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
	fmt.Println("ex02y Init")
	return shim.Success(nil)
}

声明invoke函数,内部定义要编写的函数

func (t *SimpChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
	fmt.Println("ex02y Invoke")
	function, args := stub.GetFunctionAndParameters()
	if function == "add" {
		return t.add(stub, args)
	} else if function == "delete" {
		return t.delete(stub, args)
	} else if function == "query" {
		return t.query(stub, args)
	}

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

add 添加数据

func (t *SimpChaincode) add(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	var name string
	var num int
	var err error
	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}
	name = args[0]
	NumExit, err := stub.GetState(name)
	if err != nil {
		return shim.Error("Failed to get state")
	}
	if NumExit != nil {
		return shim.Error("Name already exit")
	}
	num, err = strconv.Atoi(args[1])
	if err != nil {
		return shim.Error("Invalid transaction amount, expecting a integer value")
	}
	fmt.Printf("name = %s, num = %d\n", name, num)


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

	return shim.Success(nil)
}

cli指令

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["add","aaa","001"]}'

添加成功
query 查询数据

func (t *SimpChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	var name string // Entities
	var err error

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting name of the person to query")
	}

	name = args[0]

	// Get the state from the ledger
	QueryNum, err := stub.GetState(name)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + name + "\"}"
		return shim.Error(jsonResp)
	}

	if QueryNum == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + name + "\"}"
		return shim.Error(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + name + "\",\"Amount\":\"" + string(QueryNum) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return shim.Success(QueryNum)
}

cli指令

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","aaa"]}'

查询到aaa对应的值 1

在这里插入图片描述
delete 删除数据

func (t *SimpChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	name := args[0]
	// Delete the key from the state in ledger
	err := stub.DelState(name)
	if err != nil {
		return shim.Error("Failed to delete state")
	}

	return shim.Success(nil)
}

cli指令

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["delete","aaa"]}'

成功删除aaa数据,后续再次查询结果为空

在这里插入图片描述

链码二,对{num ; {name ; value ; type}} 形式数据进行,増,删,改,查询单个或全部数据

声明结构体和复杂的数据结构体;初始化

type StructChaincode struct {
}

type User struct {
	Name string `json:"name"`
	Value int `json:"value"`
	Type string `json:"type"`
}

func (t *StructChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
	fmt.Println("mvcc 3.0 Init")
	return shim.Success(nil)
}

声明invoke函数

func (t *StructChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
	fmt.Println("mvcc 3.0 Invoke")
	function, args := stub.GetFunctionAndParameters()
	if function == "add" {
		return t.add(stub, args)
	} else if function == "delete" {
		return t.delete(stub, args)
	} else if function == "query" {
		return t.query(stub, args)
	} else if function  == "update" {
		return t.uptade(stub, args)
	} else if function  == "queryall" {
		return t.queryall(stub,args)
	}

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

add 增加数据

func (t *StructChaincode) add(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 4 {
		return shim.Error("Incorrect number of arguments. Expecting 5")
	}
	a, err := strconv.Atoi(args[2])
	if err != nil {
		return shim.Error("Invalid transaction amount, expecting a integer value")
	}
	var per = User{Name:args[1], Value:a, Type:args[3]}

	PerAsByte, _ := json.Marshal(per)
	err = stub.PutState(args[0], PerAsByte)
	if err != nil {
		return shim.Error(err.Error())
	}

	return shim.Success(nil)
}

cli指令

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["add","Peo1","aaa","100","student"]}'

在这里插入图片描述
query 查询数据

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

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting name of the person to query")
	}

	QueryMessage, err := stub.GetState(args[0])
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + args[0] + "\"}"
		return shim.Error(jsonResp)
	}

	//jsonResp := "{\"Name\":\"" + args[0] + "\",\"Amount\":\"" + string(QueryMessage) + "\"}"
	//fmt.Printf("Query Response:%s\n", jsonResp)
	return shim.Success(QueryMessage)
}

cli指令

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","Peo1"]}'

在这里插入图片描述
update 修改name数据

func (t *StructChaincode) uptade(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}

	PeoAsBytes, _:= stub.GetState(args[0])
	peo := User{}

	er :=json.Unmarshal(PeoAsBytes, &peo)
	if er != nil {
		return shim.Error("Failed to unmarshal")
	}
	peo.Name = args[1]

	PeoAsBytes, _= json.Marshal(peo)
	err := stub.PutState(args[0],PeoAsBytes)
	if err != nil {
		return shim.Error("Failed to update state")
	}

	return shim.Success(nil)
}

cli指令

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["uptade","Peo1","abb"]}'

在这里插入图片描述
再次查询,name修改成功(aaa -> abb)
在这里插入图片描述
delete删除数据

func (t *StructChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	err := stub.DelState(args[0])
	if err != nil {
		return shim.Error("Failed to delete state")
	}

	return shim.Success(nil)
}

cli指令

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["delete","Peo3"]}'

在这里插入图片描述
再次查询,Peo3已经删除
在这里插入图片描述
queryall 查询所有数据

使用的是GetStateByRange函数,尾指针无所谓,只会返回存在的数据
GetStateByRange返回的是指针,getListResult函数用来对数据格式进行处理

func getListResult(resultsIterator shim.StateQueryIteratorInterface) ([]byte,error){


	defer resultsIterator.Close()
	// buffer is a JSON array containing QueryRecords
	var buffer bytes.Buffer
	buffer.WriteString("[")


	bArrayMemberAlreadyWritten := false
	for resultsIterator.HasNext() {
		queryResponse, err := resultsIterator.Next()
		if err != nil {
			return nil, err
		}
		if bArrayMemberAlreadyWritten == true {
			buffer.WriteString(",")
		}
		buffer.WriteString("{\"Key\":")
		buffer.WriteString("\"")
		buffer.WriteString(queryResponse.Key)
		buffer.WriteString("\"")


		buffer.WriteString(", \"Record\":")
		// Record is a JSON object, so we write as-is
		buffer.WriteString(string(queryResponse.Value))
		buffer.WriteString("}")
		bArrayMemberAlreadyWritten = true
	}
	buffer.WriteString("]")
	fmt.Printf("queryResult:\n%s\n", buffer.String())
	return buffer.Bytes(), nil
}
func (t *StructChaincode) queryall (stub shim.ChaincodeStubInterface, args []string) pb.Response{
	resultsIterator,err:= stub.GetStateByRange(args[0],args[1])
	if err!=nil{
		return shim.Error("Query by Range failed")
	}
	result,err:=getListResult(resultsIterator)
	if err!=nil{
		return shim.Error("getListResult failed")
	}
	return shim.Success(result)
}

cli指令

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["queryall","Peo1","Peo4"]}'

返回Peo1及Peo2的全部信息
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值