公司最近需要搭建一套区块链项目进行数据存储,于是研究了下HyperLedger Fabric这个IBM开发的重量级区块链框架,这个著名的项目采用了可插拔式的模块,提供联盟链和私链的区块链解决方案
一.安装环境
安装docker和docker-compose
首先安装go语言环境,其次配置GOPATH
环境变量,例如配置到/Users/admin/go
cd $GOPATH
然后创建目录src/github.com/hyperledger/
,注意必须是创建这样的目录
然后从github上clone一下fabric的源码,切换到1.4.6分支
进入scripts目录,运行bootstrap.sh
,拉取所需镜像
这样基本的环境变量就搭好了
进入到fabric目录下,使用make configtxgen
make cryptogen
生成之后可能需要的工具configtxgen
、cryptogen
,会生成到/build/bin
下
二.启动项目
拉取我的https://github.com/maxisvest/fabric-java-sample项目(改造自某个大神的项目),进入`src/main/test/fixture/sdkintegratio`,使用`fabric.sh up`启动所需容器(其实就是官方的java sdk下面的测试环境启动的脚本)
之后运行main方法就可以安装,实例化,操作链码了
src
下的org.example.SimpleAssetChaincode
供编写链码时的实时编译,编写好后将该类下的代码粘贴到src/main/test/fixture/sdkintegration/javacc/sample1/src/main/java/org/example/SimpleAssetChaincode.java
中,以供安装链码需要
首先使用main方法manager.installChainCode()
+ manager.instantiateChainCode()
,安装并实例化链码。
之后链码又做修改,需要提升版本号,然后使用manager.installChainCode()
+ manager.upgradeChaincode()
来升级链码。
本项目是springboot的项目,可以使用Application
启动项目,然后安装链码后可以通过controller查询和写入数据
三.遇到的坑
代码中使用channel.joinPeer()
和channel.addPeer()
有区别,新new出来的某个名字的channel如果join过peer,再次join会报错,只能通过add来加入peer,但是如果没join过peer直接使用add,不知道会怎么样,还没尝试
参考文章
https://www.jianshu.com/p/bfb081a96337 对于channel的一些坑
http://melanx.com/2019/06/20/fabric%E5%90%84%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AE%B2%E8%A7%A3/ Fabric配置文件讲解
https://www.cnblogs.com/aberic/ 这个人的教程很详细,给了我不少启发,包括搭建和代码编写
https://blog.csdn.net/mx1222/article/details/87921286 手动停止并删除链码
关于chaincode的坑install chaincode
会将chaincode的源码传入到peer节点上,此时chaincode不会生效instantiate
会实例化chaincode,首先会启动一个java-env的容器对chaincode打包,其次生成chaincode的容器并启动起来,安装chaincode需要每个peer节点都安装,实例化只需要一次
官方给的chaincode中无法正常打包,因为依赖的guava版本太低了,需要手动定义20.0版本到pom下面才能正常打包
可以参考
https://github.com/hooj0/fabric-chaincode-java
https://github.com/hooj0/fabric-sdk-java-commons
如果出现fabirc error authorizing update: error validating ReadSet: readset expected key [Group] /Channel/App
可以先结束并删除镜像docker rmi -f $(docker ps -aq)
然后清理悬空镜像docker volume prune
可能会用到的命令
一条命令实现停用并删除容器docker stop $(docker ps -q) & docker rm $(docker ps -aq)