五、hyperledger fabric 投票链码开发

实现一个简单的投票链码(go编写),包含两个功能,给用户投票,获取投票信息。

一、编写智能合约代码vote.go

package main

import(
	"fmt"
	"encoding/json"
	"bytes"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	"github.com/hyperledger/fabric/protos/peer"
)

type VoteChaincode struct {
}

type Vote struct {
	Username string `json:"username"`
	Votenum int `json:"votenum"`
}

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

func (t *VoteChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {

	fn , args := stub.GetFunctionAndParameters()

	if fn == "voteUser" {
		return t.voteUser(stub,args)
	} else if fn == "getUserVote" {
		return t.getUserVote(stub,args)
	}

	return shim.Error("Invoke 调用方法有误!")
}

func (t *VoteChaincode) voteUser(stub shim.ChaincodeStubInterface , args []string) peer.Response{
	// 查询当前用户的票数,如果用户不存在则新添一条数据,如果存在则给票数加1
	fmt.Println("start voteUser")
	vote := Vote{}
	username := args[0]
	voteAsBytes, err := stub.GetState(username)

	if err != nil {
		shim.Error("voteUser 获取用户信息失败!")
	}

	if voteAsBytes != nil {
		err = json.Unmarshal(voteAsBytes, &vote)
		if err != nil {
			shim.Error(err.Error())
		}
		vote.Votenum += 1
	}else {
		vote = Vote{ Username: args[0], Votenum: 1} 
	}

	//将 Vote 对象 转为 JSON 对象
	voteJsonAsBytes, err := json.Marshal(vote)
	if err != nil {
		shim.Error(err.Error())
	}

	err = stub.PutState(username,voteJsonAsBytes)
	if err != nil {
		shim.Error("voteUser 写入账本失败!")
	}

	fmt.Println("end voteUser")
	return shim.Success(nil)
}

func (t *VoteChaincode) getUserVote(stub shim.ChaincodeStubInterface, args []string) peer.Response{

	fmt.Println("start getUserVote")
	// 获取所有用户的票数
	resultIterator, err := stub.GetStateByRange("","")
	if err != nil {
		return shim.Error("获取用户票数失败!")
	}
	defer resultIterator.Close()

	var buffer bytes.Buffer
	buffer.WriteString("[")

	isWritten := false

	for resultIterator.HasNext() {
		queryResult , err := resultIterator.Next()
		if err != nil {
			return shim.Error(err.Error())
		}

		if isWritten == true {
			buffer.WriteString(",")
		}

		buffer.WriteString(string(queryResult.Value))
		isWritten = true
	}

	buffer.WriteString("]")

	fmt.Printf("查询结果:\n%s\n",buffer.String())
	fmt.Println("end getUserVote")
	return shim.Success(buffer.Bytes())
}

func main(){
	err := shim.Start(new(VoteChaincode))
	if err != nil {
		fmt.Println("vote chaincode start err")
	}
}

二、将代码文件夹/vote拷贝到fabric-samples下面的chaincode文件夹

三、进入到fabric-samples/chaincode-docker-devmode,启动网络

docker-compose -f docker-compose-simple.yaml up

四、新开一个终端,编译链码,并启动

docker exec -it chaincode bash

cd vote/

go build

CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=mycc:0 ./hello

五、新开一个终端,进入docker容器,操作链码

docker exec -it cli bash

安装链码

peer chaincode install -p chaincodedev/chaincode/vote -n mycc -v 0

实例化链码

peer chaincode instantiate -n mycc -v 0 -c '{"Args":[]}' -C myc

创建投票人信息,初始创建票数加一

peer chaincode invoke -n mycc -c '{"Args":["voteUser", "chenjunfei"]}' -C myc

五、hyperledger fabric 投票链码开发_第1张图片

查询投票人信息

peer chaincode invoke -n mycc -c '{"Args":["getUserVote"]}' -C myc

再次执行投票后票数+1

你可能感兴趣的:(hyperledger,fabric)