在万字解析——区块链hyperledger fabric2.2部署实战教程中,我对fabric2.2官方文档的一个示例和两个实战项目进行了操作展示,现在我准备开发一个水产品溯源交易平台,在写下这句话前,我没有开发过任何一个实战的区块链项目,如果写的有不好和不对的地方,欢迎各位大佬指正!
我在上一篇文章配环境为ubuntu20.04,这次我用另一台虚拟机ubuntu18.04重头配置一次开发环境,如果你的Ubuntu没有优化过,请查看本篇尾的虚拟机优化章节:
1.安装git
# 安装
sudo apt-get install git
# 若过程中遇到
#E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源暂时不可用)
#E: 无法获取 dpkg 前端锁 (/var/lib/dpkg/lock-frontend),是否有其他进程正占用它?
# 请执行以下命令后,再安装
sudo rm /var/lib/dpkg/lock-frontend
2.安装curl
sudo apt-get install curl
3.安装docker
# 安装并检查版本
sudo apt-get -y install docker-compose
docker --version
docker-compose --version
# 提示,以后只要碰到docker有关的错误,先执行2.3.1步骤
#1.重启docker
sudo systemctl start docker
#设置系统启动时docker启动,可选
sudo systemctl enable docker
#2.将用户添加到docker组,确保在用户命令下可以执行
sudo gpasswd -a $USER docker
#3.更新用户组
newgrp docker
# docker信息
docker info
# 测试docker,若报错详见文末附加问题1
docker run hello-world
4.安装go
安装并解压
mkdir ~/download
cd ~/download
下载
建议下载1.13版的go,在进行测试前把go.mod改成 1.13 如图,这样三个示例,都能成功(ps:在版本上我至少折腾了有好几十个小时,血的教训!)
#wget https://studygolang.com/dl/golang/go1.14.linux-amd64.tar.gz
# 测试商业票据的时候要换成1.13版本,不知道为什么
wget https://studygolang.com/dl/golang/go1.13.linux-amd64.tar.gz
# 有解释是这个:您系统的 go 版本只需与 fabric-samples/asset-transfer-basic/chaincode-go/go.mod 中指定的版本匹配
解压
sudo tar -C /usr/local -xzf go1.13.linux-amd64.tar.gz
# sudo tar -C /usr/local -xzf go1.14.linux-amd64.tar.gz
创建go目录并配置环境:
mkdir $HOME/go
#用vi打开~./bashrc,配置环境变量
vi ~/.bashrc
# 在最下方插入
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
#使配置的环境变量生效
source ~/.bashrc
#检查是否配置正确
go version
# 配置goproxy环境变量加速国内下载
go env -w GOPROXY=https://goproxy.io
安装示例、二进制和 Docker 镜像
克隆 hyperledger/fabric-samples 仓库
mkdir -p $GOPATH/src/github.com/hyperledger
cd $GOPATH/src/github.com/hyperledger
# 获取fabric-samples源码
git clone https://github.com/hyperledger/fabric-samples.git
#选择适当的版本标签,进入目录,切换分支
cd fabric-samples
# 可自行选择版本
git checkout release-2.2
#查看版本
git branch
3.将指定版本的 Hyperledger Fabric 平台特定二进制文件和配置文件安装到 fabric-samples 下的 /bin和 /config 目录中,下载指定版本的 Hyperledger Fabric docker 镜像
先配置镜像源:
sudo vi /etc/docker/daemon.json
#把以下代码加进去
{
"registry-mirrors":["https://registry.docker-cn.com"]
}
#如果你想要最新的生产发布版本,忽略所有的版本标识符。
# curl -sSL https://bit.ly/2ysbOFE | bash -s
# curl -sSL https://bit.ly/2ysbOFE | bash -s --
# 若报错详见文末附加问题2
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.0 1.4.7 0.4.18
# 若不行试试下面这个,查看问题2
curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh | bash -s 2.2.0 1.4.7 0.4.18
如果二进制文件拉取不到就去官网下载
fabric
fabric-ca
放到fabric-samples下解压
我们可以看到全部下载完毕了
cd chaincode-go
sudo vi go.mod
# 进入文件发现是1.14 自己把改成1.13 ,要与你下载的go版本匹配
环境变量设置
vi ~/.bashrc
# 添加下面的变量
export PATH=$PATH:$GOPATH/src/github.com/hyperledger/fabric-samples/bin
# 使之生效
source ~/.bashrc
# 检验成功否
fabric-ca-client version
现在开始测试网络
cd test-network
./network.sh up
# 报错
#ERROR: The Compose file './docker/docker-compose-test-net.yaml' is invalid because:
#networks.test value Additional properties are not allowed ('name' was unexpected)
# 请更新docker-compose
sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
#配置执行权限:
sudo chmod +x /usr/local/bin/docker-compose
# 检查更新
docker-compose -v
./network.sh down
先谈谈我的最终设计,有4方:养殖场,经销商,消费者,监管局。结构设计如图:
旨在比较以下两者查询效率高低:
1.全部原始数据上传至区块链,再通过couchdb查询。
2.存储原始数据到数据库,再把原始数据通过hash加密上链,与最终查询数据库数据hash比较,若hash值相同则数据真实。
1.1《汽车生产》
首先,看到这个我先想到以范例——《汽车生产》为模板,我们找到汽车生产,我使用的是javascript开发智能合约,懂go或者java的朋友也可以查看这两种语言的版本
现在来分析汽车生产区块链形成的流程:
在fabcar目录下以javascript语言开启脚本./startFabric.sh javascript
,我们来看看这个脚本里做了哪些事情:
# 1. clean out any old identites in the wallets 如果你启动过先清除之前旧创建的文件
rm -rf ...
# 2. launch network; create channel and join peer to channel 启动网络; 创建通道并连接对等通道
pushd ../test-network # 推到这个目录
# 关闭网络,networkDown方法执行stop org3 if exist、clearContainers、removeUnwantedImages、删除订单块和其他通道配置事务和证书等等
./network.sh down
# 开启网络
# up=》networkUp 方法执行 checkPrereqs、 createOrgs 、 createConsortium
# createChannel=》createChannel 方法执行 运行scripts/createChannel.sh脚本
# 参数-ca=>CRYPTO="Certificate Authorities" 采用ca加密
# 参数-s couchdb=>DATABASE="$2" 默认是leveldb,这里使用couchdb
[有关于network.sh脚本详解请看](https://blog.csdn.net/ling1998/article/details/121311568),篇幅问题我就不介绍了。
./network.sh up createChannel -ca -s couchdb
# 开启链码部署到通道,-ccn链码名称,版本,....
./network.sh deployCC -ccn fabcar -ccv 1 -cci initLedger -ccl ${CC_SRC_LANGUAGE} -ccp ${CC_SRC_PATH}
# 3. 当你实例化链码后,我们可以执行以下操作
JavaScript:
#首先切换到"javascript"目录:
Start by changing into the "javascript" directory:
cd javascript
#接下来,执行npm install 安装所有需要的软件包,完毕会发现多了一个node_moudle文件夹,里面安装了所有你需要的依赖包:
Next, install all required packages:
npm install
#然后运行以下应用程序来注册admin用户,并注册一个新用户称为appUser,其他应用程序将使用它与已部署的应用程序进行交互
Then run the following applications to enroll the admin user, and register a new user
called appUser which will be used by the other applications to interact with the deployed
FabCar contract:
node enrollAdmin
# 找到 enrollAdmin.js,看看他做了什么事情:
# 1.加载网络配置 2.创建一个新的CA客户端来与CA交互
# 3.创建一个新的基于文件系统的钱包来管理身份 4.注册管理员用户,并将新身份导入到钱包中)
node registerUser
# 找到 registerUser.js,看看他做了什么事情:
# 1.加载网络配置 2.创建一个新的CA客户端来与CA交互
# 3.创建一个新的基于文件系统的钱包来管理身份 4.构建一个普通用户对象,用于通过CA进行身份验证
# 5.注册普通用户,并将新身份导入到钱包中
#您可以按照如下方式运行调用应用程序。 默认情况下,调用应用程序将创建一辆新车,但您可以更新应用程序以提交其他事务:
You can run the invoke application as follows. By default, the invoke application will
create a new car, but you can update the application to submit other transactions:
node invoke
# 找到 invoke.js,看看他做了什么事情:
# 1.加载网络配置 2.创建一个新的基于文件系统的钱包来管理身份
# 3.创建一个新的网关来连接到我们的对等节点 4.获取我们的合约所部署的网络(频道)
# 5.从网络获取合约:network.getContract('fabcar')待会我们看看合约 6.提交指定事务contract.submitTransaction()\
# 7.断开网络连接
#您可以按照如下方式运行查询应用程序。 默认情况下,查询应用程序将 返回所有车辆,但您可以更新应用程序来评估其他事务:
You can run the query application as follows. By default, the query application will
return all cars, but you can update the application to evaluate other transactions:
node query
# 找到 query.js,看看他做了什么事情:
# 1.加载网络配置 2.创建一个新的基于文件系统的钱包来管理身份
# 3.创建一个新的网关来连接到我们的对等节点 4.获取我们的合约所部署的网络(频道)
# 5.从网络获取合约:network.getContract('fabcar')待会我们看看合约 6.查看指定事务contract.evaluateTransaction()\
# 7.断开网络连接
# 接下来我们看看fabcar智能合约的定义,cd fabric-samples/chaincode/fabcar/javascript/lib/fabcar.js
# 有下面这些函数方法
# 1.初始化账本(async initLedger(ctx))里面定义了许多车辆信息打印输出const cars = [color:'blue',make:'Toyota'...]
# 2.查询编号为carNumber的车辆信息(queryCar(ctx, carNumber))
# 3.创建车辆信息(async createCar(ctx, carNumber, make, model, color, owner))
# 4.查询所有车辆信息(async queryAllCars(ctx))
# 5.改变车辆的拥有者(async changeCarOwner(ctx, carNumber, newOwner))
看到这里我似乎有了一点思路,如果我想这个平台,那就把一条鱼或一批鱼看成车,改变车的拥有者就是产品流通在不同的身份中(养殖场=》经销商=》消费者),但是还有一些问题不是很理解,先实现再说吧,于是
先修改智能合约,fabcar的智能合约在fabric-samples/chaincode
下:
左侧很多文件都要修改,画红线框的部分,我是把fabcar修改成fish,修改也是一个学习的过程。
然后智能合约部分,因为我用的是JavaScript,所以我把fabric-samples/chaincode
和fabric-samples/fabcar
下都复制了一个fabcar修改为fish,再操作,如图:
弄好之后,我们就可以启动链码了:
现在,我们进入文件夹cd javascript
分别进行创建管理员身份=》创建用户=》查询数据=》创建新数据=》查询数据操作:
可以看到把合约初始化的数据查出来了
接下来我们添加交易node invoke.js
,再查询,node query.js
,可以看到添加交易信息也被插入:
至此,我根据模板修改了一下代码,虽然没得到自己想要的功能,但对于fabric运行有了一定的理解,下一篇我主要讲讲自己学习的过程,仿照另外一篇,做出水产品溯源交易平台!
1.配置sudo不要密码
sudo vi /etc/sudoers
# 把%admin....一行改为以下( 是你的用户名):
ALL=(ALL:ALL) NOPASSWD: ALL
2.更换软件更新源
# 1.先切换到目录:
cd /etc/apt
# 2.备份源
sudo cp sources.list sources.list.old
# 3.编辑源
sudo vi sources.list
# 4.删除所有内容,进入https://mirrors.ustc.edu.cn/repogen/ 按照自己系统的版本并添加阿里云源
# 如果你是ubuntu18,请继续看下去,不要使用如下源。
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
# 6. 注意:ubuntu18有问题,这里我用的是如下清华源:
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
3.github换源,否则clone不了
# 打开:
https://ipaddress.com
# 搜索raw.githubusercontent.com
# 修改hosts配置
sudo gedit /etc/hosts
# 添加
185.199.108.133 raw.githubusercontent.com
# 重启网络
sudo /etc/init.d/network-manager restart
# 安装sshd服务
sudo apt-get install openssh-server
# 查看服务状态
systemctl status sshd
# 打开服务
systemctl start sshd
# 关闭服务
systemctl stop sshd
# 重起服务
systemctl restart sshd
# 设定开机启动
systemctl enable sshd