Fabric1.4 编写链码

Posted 杰西啊杰西

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Fabric1.4 编写链码相关的知识,希望对你有一定的参考价值。

参考博客 https://zhayujie.com/chaincode-test.html

一、说在前面

1、链码使用go语言编写,然后安装在peer节点上即可
2、要调用链码对链上数据进行操作时,可以使用fabric-sdk-py或者fabric-sdk-go等sdk对链码进行操作,使用哪种sdk完全取决于你对哪种语言操作比较熟悉。
3、当然,如果不需要其他额外的服务,只想练习链码的编写,那么就可以使用命令cli进行直接调用

二、编写链码

1、在根路径下新建链码文件夹chaincode
2、在chaincode文件夹下新建文件夹basic-info,新建链码文件basicInfoCC.go如下

package main

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

type BasicInfo struct{
	//个人id
	Pid string `json:"pid"`
	//身份证
	IdNum string `json:"IdNum"`
	//姓名
	Name string `json:"Name"`
	//性别
	Gender string `json:"Gender"`
	//民族
	Nation string `json:"Nation"`
	//籍贯
	Native string `json:"Native"`
	//生日
	Birthday string `json:"Birthday"`
	//手机
	Phone string `json:"Phone"`
	//邮箱
	Email string `json:"Email"`
	//政治面貌
	Status string `json:"Status"`
	//家庭住址
	Address string `json:"Address"`
	//插入该数据的时间
	Time string `json:"Time"`
}

type BasicInfoChaincode struct{ //合约即链码
}

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

//提供函数入口
func (b *BasicInfoChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
	function, args := stub.GetFunctionAndParameters()
	if function == "initBasicLedger" { //根据id进行查找人的基本信息 
		return b.initBasicLedger(stub, args)
	}else if function == "queryBasicByIdNum" { //初始化个人基本信息表账本
		return b.queryBasicByIdNum(stub,args)
	}
	return shim.Error("Invalid BasicInfo Chaincode Smart Contract function name.")
}


//初始化个人基本信息账本
/*
	**args:
		[0]:个人基本信息id
		[1]:身份证
		[2]:姓名
		[3]:性别
		[4]:民族
		[5]:籍贯
		[6]:生日
		[7]:手机
		[8]:邮箱
		[9]:政治面貌
		[10]:家庭住址
		[11]:插入该数据的时间
*/
func (b *BasicInfoChaincode) initBasicLedger(stub shim.ChaincodeStubInterface, args []string) peer.Response {

	basicInfo := []BasicInfo{
		{
			//个人基本信息id
			Pid:args[0],
			//身份证
			IdNum:args[1],
			//姓名
			Name:args[2],
			//性别
			Gender:args[3],
			//民族
			Nation:args[4],
			//籍贯
			Native:args[5],
			//生日
			Birthday:args[6],
			//手机
			Phone:args[7],
			//邮箱
			Email:args[8],
			//政治面貌
			Status:args[9],
			//家庭住址
			Address:args[10],
			//插入该数据的时间
			Time:args[11], //time.Now().Format("2006-01-02 15:04:05")
		},
	}
	i := 0
	for i < len(basicInfo) {
		fmt.Println("i is ", i)
		basicInfoAsBytes, _ := json.Marshal(basicInfo[i])
		stub.PutState(basicInfo[i].Pid, basicInfoAsBytes)
		fmt.Println("Added", basicInfo[i])
		i = i + 1
	}
	return shim.Success([]byte("初始化基本个人信息账本成功"))
}


//根据id进行查找人的基本信息(链码函数)
func (b *BasicInfoChaincode) queryBasicByIdNum(stub shim.ChaincodeStubInterface, args []string) peer.Response { //args传入函数多个参数,这里如果只传入身份证号也可以不使用args []string 只用id_num string
	if len(args) < 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}
	basic_info, _ := stub.GetState(args[0])
	return shim.Success(basic_info)
}


func main(){
	err := shim.Start(new(BasicInfoChaincode))
	if err != nil{
		fmt.Printf("启动BasicInfoChaincode时发生错误: %s", err)
	}
}

三、使用官方样例fabric-samples中的chaincode-docker-devmode网络进行测试链码

1、进入chaincode-docker-demode文件夹下
在这里插入图片描述
启动网络

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

2、在fabric-samples下的chaincode文件夹中新建文件夹basic-info,将你要测试的链码文件复制到这个文件夹下
在这里插入图片描述
3、进入chaincode容器,进行测试

docker exec -it chaincode bash

4、编译链码文件,成功执行后单当前目录下会出现生成的可执行文件。

go build basicInfoCC.go

在这里插入图片描述
5、启动这个可执行文件

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

在这里插入图片描述
等一下可以在这个终端看到操作输出结果
6、另外开一个终端,进入cli容器

docker exec -it cli bash

7、安装链码

# -n是给链码取名字  -C 是给通道取名字
peer chaincode instantiate -n mycc -v 0  -C myc

8、实例化链码

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

9、进行测试
(1)initBasicLedger() 添加信息[名字没取好orz,应该叫做addBasicInfo()]

peer chaincode invoke -n mycc -c '{"Args":["initBasicLedger","1","500103333336363636","jessy","0","han","chongqing","2000-07-19","15777788886","1202020203@qq.com","tuanyuan","chongqing","2021-07-19-00:10:00"]}' -C myc

这个终端信息太多了,回到我们之前那个终端可以看到添加信息Added…
在这里插入图片描述
(2)queryBasicByIdNum()根据id查询信息

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

在这个终端中可以看到
在这里插入图片描述

四、在开发者环境中加入couchdb

1、关闭网络

docker-compose -f docker-compose-simple.yaml down

2、编辑docker-compose-simple.yaml
首先在文件中添加couchdb段的配置:

couchdb:
    container_name: couchdb
    image: hyperledger/fabric-couchdb
    environment:
      - COUCHDB_USER=
      - COUCHDB_PASSWORD=
    ports:
      - 5984:5984
    networks:
      - default

在peer的environment部分添加:

environment:
    - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
    - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984
    - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
    - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=

在peer的depends_on部分添加:

depends_on:
    - couchdb

3、访问页面
在这里插入图片描述

小插曲:发现退出之后再启动无法进入cli,配置couchdb之后再也没办法进入cli,等我解决
在这里插入图片描述

以上是关于Fabric1.4 编写链码的主要内容,如果未能解决你的问题,请参考以下文章

Fabric1.4 编写链码

Fabric1.4:链码管理与测试

Fabric1.4源码中链码容器启动过程解析

Fabric1.4.1视频教程即将推出

菜鸟学习Fabric源码学习 — 背书节点和链码容器交互

Fabric1.4 Fabric-SDK-go及web应用