测试系统 Ubuntu 16.04 64位

本文参考了fabric官方文档,基本上是按照原文来的,并且排了一些安装上的坑,如果文章中有什么理解的问题欢迎指正,原文链接如下。
Using the Fabric test network

1.安装相关软件

1.1.docker安装

直接参考下面这篇文档安装好docker-ce即可

Ubuntu 16.04安装docker详细步骤

按照下面这篇文章的3.2节安装好docker-compose即可

ubuntu16.04 安装docker-ce,docker-compose

安装成功后使用如下命令,如果显示出版本号说明安装成功

docker-compose -v

1.2.clone

从该地址clone需要的项目,如果云服务器clone过慢,建议本地科学上网clone好之后打包scp上传云服务器

https://github.com/hyperledger/fabric-samples.git

1.3.下载专用的bin文件和config文件

首先进入clone下来的fabric samples文件中,然后执行如下命令

curl -sSL https://bit.ly/2ysbOFE | bash -s

如果报了如下错误:

curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused

这里可以参考如下博客查看原因并解决:
curl -sSL https://bit.ly/2ysbOFE | bash -s无法执行问题解决

本质上就是手动从https://github.com/hyperledger/fabric/blob/main/scripts/bootstrap.sh下载这个bootstrap.sh并运行,如果无法访问github,可以在github.com后面加.cnpmjs.org访问其镜像。

下载好之后,在bin目录下有peer等二进制文件,在config目录下有若干yaml文件,如果需要的话,可以使用如下命令将peer等添加到环境变量中:

export PATH=<path to download location>/bin:$PATH

1.4.安装go语言环境

照下面这个网址的教程来安装就行了,这里安装go主要是为了方便之后使用他给的默认的chaincode示例,此外似乎现在很多区块链的项目都会用到go,所以安装一下应该还是有好处的。

ubuntu安装go

为了防止之后使用go时出现time out的问题,可以使用如下命令使用国内代理,(或者用科学上网的方式也可以解决)。

go env -w GOPROXY=https://goproxy.cn,direct

到这里准备工作就做好了

2.使用fabric测试网络

这个测试网络一方面可以用来学习Fabric,另一方面也可以让一些更有经验的开发者来测试他们的智能合约和应用,但是不建议用于生产环境,在2.0版本后,这个测试网络也取代了原来的"first-network"。

2.1.启动测试网络

首先回到clone好项目的目录,执行如下命令进入测试网络所在文件夹

cd fabric-samples/test-network

在这里可以看到一个network.sh文件,执行./network.sh -h可以看到它的使用说明

下面这条命令会移除先前所有运行中的容器

sudo ./network.sh down

然后执行如下的命令,会创建一个Fabric网络。

sudo ./network.sh up

这个网络由两个peer节点,一个order节点组成,当使用这个命令的时候,不会有channel被建立,如果成功的话可以看到如下的输出。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PI6u6POB-1593192296217)(./blog-pic/1.png)]

可以通过如下命令查看当前运行的三个Docker容器,这三个容器就是由刚才的up命令创建的

sudo docker ps -a

每个与Fabric网络交互的节点需要属于一个作为网络成员的组织,这些组织所组成的组被称为consortium(联盟),这个测试网络有两个联盟成员Org1和Org2,还有一个为网络提供排序服务的排序组织。

Peers是Fabric网络的基础组件,它存储区块链的账本,并在交易提交到账本之前验证交易,Peers也运行包含着业务逻辑的智能合约,由此来管理账本上的资产。

网络中的每个Peer都属于联盟的一个成员,在测试网络中peer0.org1.example.com和peer0.org2.example.com各有一个peer。

每个Fabric网络也包含一个排序服务,用于将交易进行排序,这样可以让peer节点专注于验证交易和提交到账本。在order节点收到来自客户端的交易之后,会按照顺序添加到一个块中,然后分发到各个peer中,加入区块链账本。此外order节点还可以操作系统的channel,定义哪些组织是联盟成员。

测试网络中用了一个Raft排序节点来提供排序服务,这个节点所属组织为orderer.example.com,在测试网络中只有一个order节点,但是在真实的网络中,可能会有被多个组织操作的多个排序节点,不同的排序节点会利用Raft共识算法在网络中来达成交易的一致。

2.2.创建一个Channel

Channel是一个用于特定网络成员之间通信的私有层,只有被邀请加入Channel的成员才能够使用它,对网络中其他成员不可见,每个Channel都有一个单独的区块链账本,被邀请加入Channel的peer可以存储Channel的账本然后验证Channel的交易。

运行如下命令可以创建一个名为mychannel的Channel连接Org1和Org2。

./network.sh createChannel

只要最后打印出========= Channel successfully joined ===========就说明创建成功了,也可以利用-c来自定义Channel的名称,通过指定不同的名称可以创建多个Channel。

如果想要在启动测试网络的同时创建Channel,可以同时使用up和createChannel两个参数。

2.3.在管道中使用chaincode(智能合约)

06在创建channel之后,可以使用智能合约来和channel的账本交互,运行在网络成员上的应用可以调用智能合约来改变账本上的资产,也可以查询智能合约来读取账本上的数据。

多重签名用于保证利用智能合约创建的交易的有效性,在提交到账本之前,智能合约会被多个组织签名,这样可以防止一个组织篡改账本,只有交易是连续的,而且被足够多的组织签名之后,才会提交到账本中。指明channel中组织的策略也是chaincode定义的部分。

在Fabric中,只能合约以chaincode的形式部署在网络中,一个智能合约会安装在一个组织的peers中,之后才能部署在Channel中,这样才可以用于和区块链账本交互和交易背书,Channel中的成员需要同意chaincode中的定义,这些定义建立了chaincode的治理,只有足够多的成员同意了定义,才能将这个定义提交到channel中,来进行使用。

这里运行如下命令可以启动一个用于刚刚创建好的channel的chaincode

./network.sh deployCC

这个命令会创建一个名为fabcar的chaincode到两个peer上,然后用在两个peer所属的channel上。看到如下的输出说明已经创建完毕。

这里默认是使用go语言的chaincode,不过事实上fabric也支持Java等语言,用-l参数指明即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2OTmkqxT-1593192296222)(./blog-pic/2.png)]

在fabcar chaincode的定义提交到channel之后,这个脚本会调用init函数来初始化这个chaincode,然后调用这个chaincode来防止初始化的车辆列表到账本中,然后会使用查询chaincode的方式来确认数据已经被添加了,这些数据将会用于之后的测试。

2.4.与网络交互

当测试网络成功启动之后,可以利用命令行的peer命令与网络交互,它允许用户调用部署好的智能合约,更新channel或者安装和部署新的智能合约。

首先确保自己位于test-network目录下,并且已经根据1.3节的内容配置好了peer的环境变量。或者用如下的方式来临时配置。

export PATH=${PWD}/../bin:$PATH

此外还需要配置一下config所在的目录。

export FABRIC_CFG_PATH=$PWD/../config/

这样准备工作就做好了。

设置如下的环境变量,可以使得你作为Org1来操作peer命令。

# Environment variables for Org1

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

CORE_PEER_TLS_ROOTCERT_FILECORE_PEER_MSPCONFIGPATH两行指明了Org1的加密所用的信息。

可以使用如下的命令来查看channel的账本中的汽车列表,这个列表是刚才使用deployCC参数时添加的。

peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'

当然chaincode也可以在网络中的某个成员想要转移或者更新资产的时候调用,利用如下的命令可以调用fabcar chaincode来修改账本中的某一辆车的拥有者。

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 fabcar --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":"changeCarOwner","Args":["CAR9","Dave"]}'

如果出现"Chaincode invoke successful. result: status:200 "的字样,说明更新成功。

由于背书策略要求交易被Org1和Org2都签名,所以chaincode在调用时需要用–peerAddresses参数来指明两个Org,因为TLS在这个网络中被使用到,所以需要使用到tlsRootCertFiles来指明TLS证书。

为了查看调用是否成功,可以使用另一个chaincode的查询,这里我们可以利用Org2来执行peer命令进行查询,首先需要设置如下环境变量。

# Environment variables for Org2

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

然后可以使用如下命令来查看CAR9在账本中的情况。

peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryCar","CAR9"]}'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1nBzWspq-1593192296224)(./blog-pic/3.png)]

可以看到车辆已经被转移给了Dave,即刚才的更新成功了。

2.5.关闭网络

当使用完测试网络的时候,可以用如下命令来关闭测试网络。

./network.sh down

这条命令会停止并移走节点和chaincode的容器,删除加密所用的信息,并且移走channel和docker卷等之前运行产生的东西,不过如果需要的话,之后可以利用up参数再次让网络运行。

2.6.启动过程详解

  • ./network.sh为两个peer节点和一个order节点创建了证书和密钥,默认情况下,脚本会利用在organizations/cryptogen文件夹下的加密工具。
  • 脚本利用configtxgen工具创建了系统的创世块,它使用configtx/configtx.yaml文件来创建创世块,并存储在system-genesis-block文件夹中。
  • 当上述两步完成之后,./network.sh会启动网络,脚本利用在docker文件夹下的docker-compose-test-net.yaml文件创建peer和orderer节点。
  • 如果使用了createChannel子命令,脚本还会运行script文件夹下的createChannel.sh脚本来创建所需要的channel,脚本会用peer命令来创建channel,加入两个组织。
  • 如果运行了deployCC命令,脚本会在所有peers上运行script下的deployCC.sh脚本来安装fabcar chaincode,在chaincode的定义被提交到channel之后,peer命令会调用init函数来初始化chaincode,并将所需的数据放入chaincode中。
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐