1.实验目标
通过一台主机完成Fabric测试网络搭建,链码开发,调试,部署和调用的过程。本实验项目为一个学生信息管理系统(部分),要求链码提供学生信息的管理功能:包括新增学生信息,修改学生信息,查询学生信息等。
限定操作要求:
1.使用fabric-samples包下的test-network示例搭建本地测试链码
2.使用bin文件夹下的二进制工具与链码交互
2.实验前提条件
1.本地已经安装Docker且已经成功拉取Fabric相关镜像
2.二进制工具已经配置到系统变量中,可通过命令行直接使用
3.成功用git克隆fabric-samples到本地GOPATH对应目录下
4.已经完成“启动Fabric测试网络”相关系统变量的配置(用于表示当前操作者身份)
3.创建工作目录
在GOPATH目录下创建相关文件夹,用来存放本次实验必要的资料
本人这里创建的目录路径是:$GOPATH/src/chaincode/student-go
接着将fabric-sample包下的test-network,config,bin文件夹复制到student-go目录下(用于测试网络)
最后在student-go文件夹下创建chaincode文件夹,用来存放链码
4.编写链码
1.创建链码文件:在chiancode目录下创建student.go文件,本次实验的所有链码都在这个文件中编写;因为链码部署需要模块化,所以要对chaincode目录进行模块化初始化(当chaincode源码目录下生成了go.mod,说明模块化初始化已经完成,当引用完第三方库就会出现go.sum文件)
2.第三方库的拉取可能会因为网速或者没有设置GO111MODULE="auto"等原因导致拉取失败,可以多次尝试
go get github.com/hyperledger/fabric-chaincode-go
go get github.com/hyperledger/fabric-protos-go
3.智能合约设计思路
因为这是一个学生信息管理系统,其中必要的数据是学生信息,所以可以用一个结构体定义,此外还有就该结构体提供增删改查等操作。注意:Fabric智能合约需要一个结构体继承相关对象才能拥有在Fabric网络中执行能力
4.开始编码
(1) 当前包的定义以及第三方包的引用
(2)定义结构体:本项目要定义两个结构体,第一个是继承Fabric智能合约对象的接口的结构体,另外一个是学生信息结构体
(3)定义检查学生ID是否重复:从逻辑上理解,ID重复的学生信息是不允许再次录入的,所以我们需要先定义该工具方法以供使用。注意:该方法是绑定在智能合约对象中的(StudentContract结构体), 因为要提供智能合约允许被外部调用,而StudentContract结构体是继承了超级账本智能合约接口的对象,拥有被外部调用的能力)
(3)定义新增学生信息方法:新增学生信息方法也是绑定在智能合约对象中,而且在新增信息前还需要检查学生ID是否重复
(4)定义读取学生信息方法:根据学生ID读取学生信息,若信息不存在需要给出相应的提醒
(5)定义更新学生信息的方法:该方法实际上是一个全覆盖方法,即每次更新都要传输学生的所有字段
(6)定义获取所有学生信息的方法
(7) 定义main方法:main方法在这里可以启动链码(部署到fabric网络上后可以自动执行,等待调用)
5.部署链码
1.部署链码前需要启动测试网络,所有要先在终端进入test-network目录
2.启动测试网络
通过network.sh脚本启动测试网络(关闭测试并清除相关数据: ./network.sh down):
./network.sh up
3.创建Channal
这里创建的channel主要作用是让两个组织节点之间能进行通信,这里创建通道名字为默认名字:mychannel
./network.sh creatChannel
4.部署链码
同样通过network.sh脚本进行链码的部署:
ccn 链码名称 ccp 链码目录 ccl 链码语言类型
./network.sh deployCC -ccn student -ccp ../chaincode -ccl go
6.链码调用
这里需要通过peer工具对已经部署好的链码调用。因此需要确保在当前终端路径下(test-network),能够直接通过命令使用peer工具
1.调用查询方法
在本项目中,查询方法共有两个,分别是读取学生信息和获取所有学生信息。
通过peer工具调用链码方法模式:
当空参数的方法时,args里面放方法名(如查询所有学生信息);
当需要传递参数时,方法名放function中,而传递的参数则放在args中(如查询某个学生信息)
查询所有学生信息(一开始没有添加信息时输出信息会是空的):
peer chaincode query -C mychannel -n student -c '{"args":["All"]}'
查询某个学生信息:
peer chaincode query -C mychannel -n student -c '{"function":"Get","args":["007"]}'
2.调用执行方法
在本项目中,只要涉及数据变更的,都需要通过执行调用。如:新增学生信息,修改学生信息等。执行方法需要表明自己身份,因此调用过程中需要指定相关证书:
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n student --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"Create","Args":["001","chenchen","123456789"]}'