Fabric2.0的测试网络
1.使用fabric测试网络
这个测试网络一方面可以用来学习Fabric,另一方面也可以让一些更有经验的开发者来测试他们的智能合约和应用,但是不建议用于生产环境,在2.0版本后,这个测试网络也取代了原来的"first-network"。
注:如果你执行了 部署 Hyperledger Fabric2.0 就先关闭 first-network
进入first-network 目录执行以下命令
关闭
./network.sh down
1.1.启动测试网络
执行如下命令进入测试网络所在文件夹
cd fabric-samples/test-network
在这里可以看到一个network.sh文件,执行./network.sh -h可以看到它的使用说明
然后执行如下的命令,会创建一个Fabric网络。
sudo ./network.sh up
这个网络由两个peer节点,一个order节点组成,当使用这个命令的时候,不会有channel被建立,如果成功的话可以看到如下的输出。
可以通过如下命令查看当前运行的三个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共识算法在网络中来达成交易的一致。
1.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两个参数。
1.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参数指明即可
在fabcar chaincode的定义提交到channel之后,这个脚本会调用init函数来初始化这个chaincode,然后调用这个chaincode来防止初始化的车辆列表到账本中,然后会使用查询chaincode的方式来确认数据已经被添加了,这些数据将会用于之后的测试。
1.4.与网络交互
当测试网络成功启动之后,可以利用命令行的peer命令与网络交互,它允许用户调用部署好的智能合约,更新channel或者安装和部署新的智能合约。
首先确保自己位于test-network目录下,执行如下的方式来临时配置。
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_FILE
和CORE_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"]}'
可以看到车辆已经被转移给了Dave,即刚才的更新成功了。
1.5.关闭网络
当使用完测试网络的时候,可以用如下命令来关闭测试网络。
./network.sh down
这条命令会停止并移走节点和chaincode的容器,删除加密所用的信息,并且移走channel和docker卷等之前运行产生的东西,不过如果需要的话,之后可以利用up参数再次让网络运行。
1.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中。