hyperledger fabric 实战开发——水产品溯源交易平台(一)
在(一)部分本人主要讲解了区块链部署的示例流程以及简单把水产品作为一项资产进行创建和交易的修改过程。这篇文章(二)主要讲解一下我是如何学习制作一个区块链追溯平台的,包括前后端开发,在这里我按照农产品追溯平台来进行学习制作,这个平台的作者已经开放了学习的微信公众号通道,我为了省钱,自己学点技术,就自学了,过程虽然费力,但是应该会学到不少,就目前我还没有系统学习之前,看平台展示功能还是非常全的,这是他的软件架构,如图,这里面我大概就了解一点mysql和vue(这还是最近学的),本科学的springboot,mybatis已经全忘光了,所以又是重新学习,我在这里篇幅有限,学不了以下图片那么多技术啦,就写一个简单一点的项目,由于我是遍测试遍写的,如果有误欢迎指正。
成果展示:
因为篇幅有限,这里就展示两张。
按照区块链、后端、前端的顺序学习,我会把自认为比较重要掌握的部分写下来区块链这部分还没学过的同学可以看看我这篇文章
万字解析——区块链hyperledger fabric2.2部署实战教程
我认为这张图就把交易流程表达的很清晰了。
1.A首先连接到peer。
2.A调用chaincode发起proposal;与此同时,P1收到后先模拟执行,再产生结果返回给A。
3.A收到各peer返回的结果。
4.A向O1发起交易;与此同时,O1产生区块后会通知peer,而peer会更新其账本。
5.最后通过订阅事件A收到了结果。
引用自:Hyperledger Fabric架构详解
以github上简易项目为例:hyperledger-simple-app,这个是1.1版本的,根据版本的不同,配置文件内容结构会有所变动,但原理是相同的,这里仅作为配置的参考。
详细请查阅:hyperledger fabric配置文件详细分析,hyperledger fabric官方文档。
接下来我们来看这个农产品溯源项目的Hyperledger Fabric部分:
由于改了需求,只需要写大黄鱼,我在这里把结构体重申一下:
1.养殖信息:{大黄鱼ID,养殖过程ID,养殖海域,养殖企业、放苗时间、捕捞时间、饲料种类、备注(养殖过程出现的问题)}
2.处理信息:{大黄鱼ID,操作过程ID,操作人、操作人电话、存贮时间、存贮方式、存贮容器、备注(存储过程有无损坏等问题)}
3.物流信息:{大黄鱼ID,物流过程ID,司机、司机电话、始发地、出发时间、目的地、到达时间、备注(运送方式、是否换乘、中途卸货等)}
4.销售信息:{大黄鱼ID,销售过程ID,销售商名称、销售负责人、销售人电话、备注(销售过程问题)}
在进行测试的时候我大概理解了一些这个农产品追溯的逻辑(很重要),现总结如下:
在这个项目中,包括官方示例项目,分布式账本给的都是键值对的形式存储,其中{“key”:value,“record”:{value…}},key在其中是主键,官方设置的查询功能中是通过查询这个主键,来查询某一条记录的,而我们记录的一个农产品的追溯数据是由多个key,record构成。打比方说,农产品有种植数据,加工数据,贮存数据等,每一条数据上链都是不同的key值,因此我们没办法根据查询key值来访问到整个溯源链,因此需要借助couchdb的富查询来拿到定义的农产品ID的好几条相关信息,再把他们合并到一起,来组成全过程溯源信息。
测试采用简易信息:
第一步:
1.养殖信息:{大黄鱼ID,养殖过程ID,养殖海域}
第二步:
1.养殖信息:{大黄鱼ID,养殖过程ID,养殖海域}
2.处理信息:{大黄鱼ID,操作过程ID,操作人}
1. 以fabcar示例为例,go运行链码,用javascript查询调用,结论是可行,如图
2. 编写bf(自编的big fish大黄鱼)的go链码,调用已有功能,加上富查询
由于我用的版本是2.2,于是到官方文档找到使用方法
这是链码范例marbles_chaincode.go,里面包括如何使用富查询等功能,部分截图如下:
根据上述范例写了三个方法,先用简单数据测试:
我不断地invoke了不同的数据三次:
查询结果如下,这表明我写的查询方法没有把所有ID为101的大黄鱼找出来,而且我这个key唯一的key,因此不能重复上传。
所以应该把养殖过程ID作为key,而大黄鱼ID作为追溯ID,查询关于追溯ID的历史值,就可以查找到所有流程数据。再修改链码
invoke.js和query.js,提交交易,查询交易。
现在我们可以看到把鱼ID为1的两个溯源流程查出来了,只需要到时候按照一个编码规则指导用户进行输入就可以规范化。
现在把计划数据导进来测试:
在上一篇文章中提到降低存储,加密存储,提高查询速度,加强安全性能,设计链上链下存储,现在讲一下测试过程中发现的坑,首先mysql操作如果直接写在链码中是不能背书通过的,大神想实现详情请转fabric调用mysql,于是写在node.js上,node.js实现请见使用nodejs连接mysql数据库实现增删改查,然后在go链码中,由于原始数据量太大,因此把原始数据通过sha256加密得到密文传入区块链存储,最后再从msql取数据就会快很多,如图:
go加密算法:
下面是数据库测试:
// mysql配置
const conn = mysql.createConnection({
host:"192.168.152.136",
port:"3306",
user:"root",
password:"root",
database:"traceability",
});
//创建连接
await conn.connect((err)=>{
if(err) throw err;
console.log('connect success!')
})
// 出入语句
await conn.query("insert into aquaInfo values ('101', '1', '桃花岛海域','桂福坤团队','2021-3-11','2022-2-30','冰鲜鱼','养殖期间未发现病害')");
// 提交事务给区块链
await contract.submitTransaction('createAquaInfo', '101', '1', '桃花岛海域','桂福坤团队','2021-3-11','2022-2-30','冰鲜鱼','养殖期间未发现病害');
可以看到,数据库传进来了,事务也提交成功,加密后的密文也存在区块链上了。
我们的区块链网络测试就到这里,下面我就自己按自己所学技术编写web了