1. 阿里云解决方案网首页
  2. ERP文章

HYPERLEDGER FABRIC 建立一个简单网络

Building you first network

网络结构:

2Orgnizations(每个Org包含2peer节点)+1solo ordering service

打开fabric-sample下的示例first-network

HYPERLEDGER FABRIC 建立一个简单网络

其中byfn.sh为启动这个网络的启动脚本,启动脚本中除建立一个包含4个节点和1Order service的网络外,还会启动一个容器用来执行脚本在channel中加入节点,部署和初始化chaincode,以及在部署的chaincode上执行交易。

启动脚本

第一步,生成必要文件,执行命令:

HYPERLEDGER FABRIC 建立一个简单网络

HYPERLEDGER FABRIC 建立一个简单网络

 

HYPERLEDGER FABRIC 建立一个简单网络

 

 

 

 

 

默认channel名称为mychannel

上述是否继续选择y,脚本程序会给网络实例生成数字证书和密钥;生成genesis block用来启动ordering service;一些用来配置channel的配置交易

1、生成数字证书和密钥

HYPERLEDGER FABRIC 建立一个简单网络

2、生成genesis block

HYPERLEDGER FABRIC 建立一个简单网络

3、生成channel配置交易

HYPERLEDGER FABRIC 建立一个简单网络

4、生成anchor peer update for Org1MSP

HYPERLEDGER FABRIC 建立一个简单网络

5、生成anchor peer update for Org2MSP

HYPERLEDGER FABRIC 建立一个简单网络

执行上述命令后,查看证书目录:

HYPERLEDGER FABRIC 建立一个简单网络

2、第二步,启动网络,执行命令./byfn.sh -m up

HYPERLEDGER FABRIC 建立一个简单网络

上图显示在一个节点上安装chaincode所配置的环境变量,其中配置了节点所拥有的证书信息。

执行结束后,终端显示如下:

HYPERLEDGER FABRIC 建立一个简单网络

上述命令会启动所有的containers

HYPERLEDGER FABRIC 建立一个简单网络

上面通过脚本./byfn.sh生成了一个fabric网络,接下来详细说明脚本中所执行的命令信息:

1Crypto Generator

cryptogen工具会对网络节点生成证书信息,证书信息可以代表每一个实例节点,用于节点间通信和交易。

cryptogen使用的配置文件为crypto-config.yaml。配置文件中描述了网络的拓扑结构同时会为OrgnizationsOrgnizations下的节点生成一系列的证书。每个Orgnization会有一个根证书ca-cert用来绑定特定节点(peer或者order)到该Orgnization。通过对每个Orgnization颁发一个唯一的数字证书,我们可以模仿典型的区块链网络,每个加入链的成员使用自己的数字证书进行获取授权。交易和通信使用节点的私鈅,验证使用节点的公钥(数字证书)。配置文件里的count参数用来指定每个Orgnization的节点数量,本例子中一个Orgnization下面包含两个节点,所以count的值在本例中设定为2

在运行这个命令之前,我们快速的看一下crypto-config.yaml里的配置信息。特别关注OrderOrgs header下的Name,DomainSpecs几个参数。

使用命令:

sed ‘s/^[ ]*#.*$//g’ crypto-config.yaml > crypt.yaml

sed -i ‘/^$/d’ crypt.yaml

去掉配置文件中的注释部分如下:

HYPERLEDGER FABRIC 建立一个简单网络

网络节点的命名规则为{Hostname}.{Domain}。以上述配置文件中order节点为例,order节点的命名为orderer.example.com,对应的MSP IdOrderer

运行cryptogen命令后,生成的数字证书和密钥信息保存在crypto-config文件夹中。

Configuration Transaction Generation

配置交易生成工具:configtxgen 用来生成4个配置信息

orderer genesis block

fabric channel configuration transaction

2anchor peer transaction (每个Peer Org生成一个)

orderer blockordering service的起始blockchannel配置交易文件在channel创建时广播到ordereranchor peer交易用来指定channel上每个OrgAnchor Peer

configxgen的配置文件为configtx.yaml,其中包含对我们所创建的示例网络的定义。配置文件包含3个角色,一个Orderer OrgOrderOrg)和两个Peer OrgsOrg1Org2)。配置文件也指定了一个组合SampleConsortium,包含2Peer Org。打开配置文件,配置文件顶部Profiles部分有两个唯一的headers。其中TwoOrgsOrderedGenesis用来配置orderer genesis blockTwoOrgChannel用来配置我们的channel

HYPERLEDGER FABRIC 建立一个简单网络

HYPERLEDGER FABRIC 建立一个简单网络

HYPERLEDGER FABRIC 建立一个简单网络上述配置文件中还包含两个没有特别意义的指定信息。第一个,我们为每一个Peer Org指定了Anchor Peerpeer0.org1.example.compeer0.org2.example.com)。第二点,我们指定了每个角色的MSP路径,从而允许我们把每个Org的根证书存储在orderer genesis block中。这是一个重要的概念。现在每个节点和ordering service通信都需要验证通过他们的数字证书。

运行cryptogenconfigtxgen命令

可以手动运行上述两个命令生成数字证书/密钥或者生成配置交易。也可以通过修改脚本byfn.sh脚本实现上述目标。

手动生成证书和配置交易

可以参考byfn.sh脚本中的generateCerts函数理解生成网络配置中数字证书的命令。为了便利,这里我们也提供了一种参考方法。

首先运行cryptogen工具。cryptogen命令在first network子目录的bin目录下,下面运行命令使用了该命令所在位置的相对路径。

../bin/cryptogen
generate --config=./crypto-config.yaml

也许你会遇到提示如下警告,直接忽略就可以

[bccsp]
GetDefault -> WARN 001 Before using BCCSP, please call
InitFactories(). Falling back to bootBCCSP.
接下来,我们需要告诉configtxgen工具引用哪里的配置文件configtx.yaml。这里我们通过设置环境变量来设定配置文件的路径。
export
FABRIC_CFG_PATH=$PWD
../bin/configtxgen
-profile TwoOrgsOrdererGenesis -outputBlock
./channel-artifacts/genesis.block

你可以忽略掉关于intermediate certificates, certificate revocation lists (crls) and MSP configurations的警告信息,在本例中的网络中,我们不会用到上述信息。

接下来,我们创建channel交易。确保替换$CHANNEL_NAME的值或者设置CHANNEL_NAME作为一个环境变量。创建命令如下:

export
CHANNEL_NAME=mychannel

#
this file contains the definitions for our sample channel
../bin/configtxgen
-profile TwoOrgsChannel -outputCreateChannelTx
./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

接下来,在我们创建的channel上定义Org1Anchor Peer节点。执行命令为:

../bin/configtxgen
-profile TwoOrgsChannel -outputAnchorPeersUpdate
./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg
Org1MSP

channel上定义Org2Anchor Peer节点:

../bin/configtxgen
-profile TwoOrgsChannel -outputAnchorPeersUpdate
./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg
Org2MSP

启动网络

我们引用一个docker-compose脚本启动网络,docker-compose文件引用了我们之前下载的镜像文件同时根据之前生成的genesis.block引导orderer

working_dir:
/opt/gopath/src/github.com/hyperledger/fabric/peer
#
command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep
$TIMEOUT'
volumes
如果去掉注释部分,网络启动时脚本会执行所有的CLI命令。这里我们手动的执行每一条命令,以便于我们了解命令的语法和功能。
TIMEOUT参数传递一个相对较大的值(单位为秒);否则CLI容器默认会在60s后退出。
启动网络:
CHANNEL_NAME=$CHANNEL_NAME

TIMEOUT=<pick_a_value>

docker-compose
-f docker-compose-cli.yaml up -d
如果你想实时查看执行上述命令的日志信息,那么去掉上面的-d选项(后台运行)。如果打开了上述日志流,那么你需要另外再打开一个终端用来执行CLI命令。
环境变量
为了在peer0.org1.example.com上执行下面的CLI命令,需要先配置下面4个环境变量。peer0.org1.example.com的这些变量我们已经在CLI容器中配置了,因此我们可以不用传递这些环境变量的值了。但是,如果你想发送命令到其他peer或者orderer,你需要提供这些变量相应的值。检查docker-compose-base.yaml查看那指定的路径。
#
Environment variables for PEER0

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
创建和加入channel
执行docker
exec命令进入CLI容器
docker
exec -it cli bash
成功执行后,出现如下提示:
root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
之前,我们使用configtxgen工具生成了配置交易channel.tx。我们将会传递这个交易到orderer作为创建channel请求的一部分。
注意:--cafile选项是orderer的根证书存放在本地的路径,该信息可以用来验证TLS握手过程。
我们使用-c选项指定channel的名字,使用-f选项指定配置交易。在本例中为channel.tx,你也可以mount配置交易为一个不同的名字。(配置交易通过本地路径mount到容器中)
export
CHANNEL_NAME=mychannel

#
the channel.tx file is mounted in the channel-artifacts directory
within your CLI container
#
as a result, we pass the full path for the file
#
we also pass the path for the orderer ca-cert in order to verify the
TLS handshake
#
be sure to replace the $CHANNEL_NAME variable appropriately

peer
channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f
./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
这条命令返回一个genesis
block
<channel-ID.block>。该block可以用来加入channel时使用,block中包含了channel.tx中指定的配置信息。
你需要留在CLI容器中执行剩余的手动命令。如果发送命令的目标不是peer0.org1.example.com,那么要重新设置相应的环境变量。现在我们加入peer0.org1.example.comchannel
#
By default, this joins ``peer0.org1.example.com`` only
#
the <channel-ID>.block was returned by the previous command

 peer
channel join -b <channel-ID.block>
你可以修改上边4个环境变量的值为其他peer节点信息配置加入其他节点到channel中。
安装和实例化chaincode
我们利用一个简单的已写好的chaincode。应用通过chaincode和区块链的账本进行交互,因此我们需要首先在每个peer节点上安装chaincode用来执行交易和背书交易,然后在channel上实例化chaincode
首先安装例子go代码到4peer节点中的一个。这个命令会把go源码放在peer节点的文件系统中。
peer
chaincode install -n mycc -v 1.0 -p
github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
接下来,在channel上实例化chaincode。这将会在channel上初始化chaincode,为chaincode设置背书策略,为目标peer启动一个chaincode容器。注意-P参数,这个参数指定了在该chaincode上一个交易被认可需要的背书级别。
接下来的命令中,我们设置-P参数为
-P
"OR ('Org0MSP.member','Org1MSP.member')"
。这表示我们需要Org1或者Org2中一个peer节点的背书。如果改变语法为AND,那么就需要两个背书。# be sure to replace the $CHANNEL_NAME environment variable
#
if you did not install your chaincode with a name of mycc, then
modify that argument as well

peer
chaincode instantiate -o orderer.example.com:7050 --tls
$CORE_PEER_TLS_ENABLED --cafile
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
-C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a",
"100", "b","200"]}' -P "OR
('Org1MSP.member','Org2MSP.member')"
上述命令中的mycc为上文中peer上安装的chaincode的名称。
下面查询a的值,确认chaincode被正确的实例化,stateDB正常的运行。查询的语法如下:
#
be sure to set the -C and -n flags appropriately

peer
chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
现在从a转移10b。这个交易会产生一个新的区块并更新stateDB。调用的语法是:
#
be sure to set the -C and -n flags appropriately

peer
chaincode invoke -o orderer.example.com:7050  --tls
$CORE_PEER_TLS_ENABLED --cafile
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
 -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'
现在再次查询,查看上述转移10的命令是否已经成功执行,执行的命令是:
#
be sure to set the -C and -n flags appropriately

peer
chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
正常执行,会输出如下提示:
Query
Result: 90
下面描述docker-compose-cli.yaml文件中没有注释script.sh时的执行情况。去掉包含script.sh脚本执行的注释,然后使用docker-compose命令再次启动网络。
1Script.sh脚本在CLI容器里已经备份过,脚本执行createChannel命令根据设定的channel名字,使用channel.tx文件作为channel配置交易。
2createChannel执行的输出是一个genesis
block-<your channel
name>.block。输出存储在peer节点的文件系统上包含了channel.tx所指定的channel配置信息。
3joinChannel命令被执行(4peer节点),joinChannel命令使用上文生成的genesis
block作为参数,该命令引导peer节点加入到<your
channel name>并且建立一个以<your
channel name>.block为起始的链。
4、目前我们建立了一个包含4个节点的channel,channel包含两个orgnizations。类似TwoOrgsChannel文件的配置。
5peer0.org1.example.compeer1.org1.example.com属于Org1peer0.org2.example.compeer1.org2.example.com属于Org2
6、这些关系在crypto-config.yaml里定义,MSP的路径在docker
compose中指定
7Org1MSPAnchor
Peer(peer0.org1.example.com)Org2MSPAnchor
peerpeer0.org2.example.com)被更新。我们通过传递Org1MSPanchor.txOrg2MSPanchor.tx以及channel的名字到ordering
service来实现这一步。
8、将编写好的chaincode_example02安装在peer0.org1.example.compeer0.org2.example.com上(这里并没有安装在所有peer上,而是仅安装在anchor
peer节点上,anchor
peer节点之前每个Org设置了一个)
9chaincodepeer0.org2.example.com上实例化。实例化过程添加chaincodechannel中,为目标peer启动容器,同时初始化与chaincode相关的key-value键值对。本例中初始化的值为[“a”,”100”
“b”,”200”]。实例化后会启动一个容器dev-peer0.org2.example.com-mycc-1.0。(实例化过程发送至peer0.org2.example.com上执行
10、实例化过程也传递了一个背书策略的参数。背书策略类似形式:-P
"OR   
('Org1MSP.member','Org2MSP.member')",代表任何交易必须被Org1Org2的一个peer背书。
11、在peer0.org1.example.com上执行查询a的值。chaincode之前已经安装在peer0.org1.example.com上了,因此查询操作会为Org1peer0节点启动一个容器dev-peer0.org1.example.com-mycc-1.0。查询结果也会返回回来,这个过程中没有任何写操作发生,所以a的值还是100
12、发送一个转移账户金额的调用到peer0.org1.example.com,从a账户转移10单位至b账户
13chaincode然后安装在peer1.org2.example.com
14、发送查询a账户操作至peer1.org2.example.com。这将启动第三个chaincode容器dev-peer1.org2.example.com-mycc-1.0。返回金额90,说明之前帐号金额的转移操作成功执行。
这说明了什么
为了在账本上成功的执行读写操作,chaincode必须安装在peer上。另外,chaincode容器直到实例化或者传统交易-读写执行的时候(例:查询a账户的值),chaincode容器才会启动。channel中的每个节点都维护了账本的完全复制,存储了不可改变的、序列化的记录区块以及state
database用于保存当前的fabric状态。即便是那些没有安装chaincode的节点(例如peer1.org1.example.com)也会同步账本。最终chaincode在安装到peer1.org1.example.com后就可以被调用了,因为chaincode已经完成了实例化。
怎样查看交易信息
查看CLI
docker容器的日志信息
docker
logs -f cli
可以看到交易的详细过程
怎样查看chaincode的日志
在每个chaincode
container上可以查看当前container里所执行过的交易。具体查看命令如下:
docker
logs dev-peer0.org2.example.com-mycc-1.0
docker
logs dev-peer0.org1.example.com-mycc-1.0
docker
logs dev-peer1.org2.example.com-mycc-1.0
理解docker-compose拓扑结构
BYFN例子提供了两种docker-compose文件配置,每一种都是由docker-compose-base.yaml(文件存放在base文件夹中)文件拓展而来。第一个配置文件是docker-compose-cli.yaml,该配置文件配置了一个CLI容器,一个orderer4peer节点。使用该配置文件启动可以实现本文中的所有操作指令。第二种配置文件docker-compose-e2e.yaml是配置启动一个使用Node.js
SDK的点对点测试。这个配置文件的主要区别是包含了fabric-ca-servers容器。因此,我们可以使用REST接口实现向CA组织注册和登记用户。
如果你想使用docker-compose-e2e.yaml并且不先运行byfn.sh脚本,那么我们需要做4个微改动。我们需要设定Organization
CA的私鈅。你可以设定这些值为你的crypto-config文件夹。例如设置Org1的私鈅路径为:crypto-config/peerOrganizations/org1.example.com/ca/。私鈅文件是一个长hash值加上_sk组成。设定Org2的私鈅为crypto-config/peerOrganizations/org2.example.com/ca/
另外2出改动是修改docker-compose-e2e.yamlca0ca1配置中的FABRIC_CA_SERVER_TLS_KEYFILE变量对应的值。需要指定tls证书所在的路径。
按照一个简单区块链网络的生成过程,制作执行过程如下:
执行步骤 执行命令和前置条件
生成必要信息 1、网路节点的证书文件

../bin/cryptogen
			generate --config=./crypto-config.yaml

2、生成gensis block

export
			FABRIC_CFG_PATH=$PWD
../bin/configtxgen
			-profile TwoOrgsOrdererGenesis -outputBlock
			./channel-artifacts/genesis.block

3、生成channel.tx

../bin/configtxgen
			-profile TwoOrgsChannel -outputCreateChannelTx
			./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

4、生成anchor peer

../bin/configtxgen
			-profile TwoOrgsChannel -outputAnchorPeersUpdate
			./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME
			-asOrg Org1MSP
创建channel peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx

创建channel的命令由peer节点发起,使用上文生成的channel.tx,上述命令生成<channel_name>.block在当前文件夹中,该block中保存了channel.tx的信息。节点加入channel后,该区块作为节点区块链的第一个区块。

加入peer节点到channelpeer channel join -b $CHANNEL_NAME.block

peer加入channel时使用创建channel时生成的block文件

加入哪个peer节点到channel中,需要通过在CLI容器中设置如下环境变量指定:

CORE_PEER_LOCALMSPID=”Org1MSP”

CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp

CORE_PEER_ADDRESS=peer0.org1.example.com:7051

设置上述环境变量,加入peer0节点到channel

更新Anchor peerpeer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx

使用configtxgen生成的anchor.tx文件

安装chaincodepeer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

CLI容器中设置环境变量指定在哪个peer节点上安装chaincode

channel上实例化chaincodepeer chaincode instantiate -o orderer.example.com:7050 –tls $CORE_PEER_TLS_ENABLED –cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 1.0 -c ‘{“Args”:[“init”,”a”,”100″,”b”,”200″]}’ -P “OR (‘Org1MSP.member’,’Org2MSP.member’)”

需要设定环境变量指定在哪个peer节点上执行实例化chaincode命令

执行chaincode调用

原创文章,作者:admin,如若转载,请注明出处:https://www.aliyunsolution.com/2112.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注