Fabric学习(三)之搭建第一个Fabric网络详解

时间:2019.12.26.22.20
本篇文章为构建第一个Fabric网络的详解
参考来源:官方地址

密钥生成器

使用 cryptogen 工具为我们的网络实体生成各种加密材料( x509 证书和签名秘钥)。这些证书是身份的代表,在实体之间通信和交易的时候,它们允许对身份验证进行签名和验证

如何工作

Cryptogen 通过一个包含网络拓扑的文件 crypto-config.yaml,为所有组织和属于这些组织的组件生成一组证书和秘钥。每一个组织被分配一个唯一的根证书(ca-cert),它绑定该组织的特定组件(Peer 节点和排序节点)。通过为每个组织分配一个唯一的 CA 证书,我们模拟了一个典型的网络,网络中的成员可以使用它自己的证书授权中心。Fabric 中的事务和通信由一个实体的私钥(keystore)签名,然后通过公钥(signcerts)验证。

crypto-config.yaml 文件gtihub地址

通过文件中 count 变量指定每个组织的 Peer 节点数量。案例里每个组织有两个 Peer 节点
运行 cryptogen 工具之后,生成的证书和密钥将保存到一个名为 crypto-config 的文件夹中。注意, crypto-config.yaml 文件在排序组织中设置了五个排序节点。cryptogen 会为这五个排序节点生成证书、创建系统通道和 mychannel。使用 Raft 或者 Kafka 排序服务会用五个节点进行排序,而使用Solo 排序服务只会使用一个排序节点

配置交易生成器

configtxgen 工具用来创建四个配置构件:
1、排序节点的创世区块
2、通道配置交易
3、两个锚节点交易,分贝对应一个Peer组织

排序区块是排序服务的创世区块,通道配置交易在通道创建的时候广播给排序服务。锚节点交易,指定了每个组织在此通道上的锚节点

如何工作

Configtxgen 使用一个文件——configtx.yaml,这个文件包含了一个示例网络的定义。它拥有三个成员:一个排序组织(OrdererOrg)和两个 Peer 组织(Org1 & Org2),这两个 Peer 组织每个都管理和维护两个 Peer 节点。这个文件还定义了一个联盟——SampleConsortium,包含了我们的两个 Peer 组织

参数作用
TwoOrgsOrdererGenesis以Solo 排序服务生成创世区块
SampleMultiNodeEtcdRaft以Raft 排序服务生成创世区块。只有将 -o 参数指定为 etcdraft 是才可用
SampleDevModeKafka以Kafka 排序服务生成创世区块。只有将 -o 参数指定为 kafka 是才可用。
TwoOrgsChannel为通道 mychannel 生成创世区块

configtx.yaml 文件的github地址

该文件还包含两个值得注意的附加规范。
第一,为每个组织指定了锚节点(peer0.org1.example.com & peer0.org2.example.com)。
第二,为每个成员指定 MSP 文件位置,进而我们可以在排序节点的创世区块中存储每个组织的根证书。这是一个关键概念。现在每个和排序服务通信的网络实体都可以验证它们的数字签名。

运行工具

configtxgen 和 cryptogen 命令来手动生成证书/密钥和各种配置。或者,你可以尝试使用 byfn.sh 脚本来完成你的目标

手动生成构件

你可以参考 byfn.sn 脚本中的 generateCerts 函数,这个函数包含了生成 crypto-config.yaml 中所定义的证书的必要命令,这些证书将被作为你的网络配置。然而,为了方便起见,我们在这里也提供一个参考。
进入 fabric-samples 文件运行 cryptogen 工具。
执行以下命令会下载必要的二进制文件,在当前目录生成 bin 文件夹存放下载的二进制文件。

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

终端输出

org1.example.com
org2.example.com

证书和秘钥(例如 MSP 材料)将会保存在 first-network 目录的 crypto-config 文件夹中。
接下来,我们需要告诉 configtxgen 工具去哪儿寻找它需要的 configtx.yaml 文件。告诉它在当前工作目录:

$ export FABRIC_CFG_PATH=$PWD

调用 configtxgen 工具创建排序节点的创世区块(默认为Solo 排序服务–>TwoOrgsOrdererGenesis )

../bin/configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block

调用 configtxgen 工具创建 Raft 排序服务的创世区块

../bin/configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block

调用 configtxgen 工具创建Kafka 排序服务的创世区块

../bin/configtxgen -profile SampleDevModeKafka -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block

其中采用 solo 排序模式的类似输出

2017-10-26 19:21:56.301 EDT [common/tools/configtxgen] main -> INFO 001 Loading configuration
2017-10-26 19:21:56.309 EDT [common/tools/configtxgen] doOutputBlock -> INFO 002 Generating genesis block
2017-10-26 19:21:56.309 EDT [common/tools/configtxgen] doOutputBlock -> INFO 003 Writing genesis block

排序通道创世区块和其他生成的构件都保存在当前项目根目录中的 channel-artifacts 文件夹。上边命令中的 channelID 是系统通道的名字

创建通道配置交易

接下来,我们需要去创建通道的交易构件。请确保替换 $CHANNEL_NAME 或者 将 CHANNEL_NAME 设置为整个说明中可以使用的环境变量

# The channel.tx artifact contains the definitions for our sample channel
$ export CHANNEL_NAME=mychannel  
$ ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

注意,如果你使用 Raft 或者 Kafka 排序服务,你也不需要为通道指定特殊命令。TwoOrgsChannel 选项会使用你指定的排序服务配置为网络创建创世区块。
终端类似输出

2017-10-26 19:24:05.324 EDT [common/tools/configtxgen] main -> INFO 001 Loading configuration
2017-10-26 19:24:05.329 EDT [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx
2017-10-26 19:24:05.329 EDT [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 003 Writing new channel tx

为通道上的组织 Org1 定义锚节点

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

为通道上的组织 Org2定义锚节点

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

启动网络

启动网络之前确保已经将之前的网络关闭掉
使用一个脚本启动我们的网络。docker-compose 文件关联了我们之前下载的镜像,然后通过我们之前生成的创世区块 genesis.block 引导排序节点
启动网络

$ docker-compose -f docker-compose-cli.yaml up -d

如果你想要实时查看你的网络日志,请不要加 -d 标识。如果你想要查看日志流,你需要打开第二个终端来执行 CLI 调用

创建和加入通道

回想一下,我们在 创建通道配置交易章节中使用 configtxgen 工具创建通道配置交易。你可以使用相同的方式创建额外的通道配置交易,使用 configtx.yaml 中相同或者不同的选项传给 configtxgen 工具。然后你可以重复在本章节中的过程在你的网络中创建其他通道。

进入容器

$ docker exec -it cli bash
// 类似输出
root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#

要想在容器中运行 peer 命令,必须先设置环境变量,调用每个节点时都必须重新设置

# 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.tx作为创建通道请求的一部分传递给排序节点。
使用 -c 标志指定通道的名称,-f 标志指定通道配置交易,在这个例子中它是 channel.tx,当然你也可以使用不同的名称挂载你自己的交易配置。我们将再次在 CLI 容器中设置 CHANNEL_NAME 环境变量,这样我们就不用显式的传递这个参数。通道的名称必须全部是消息字母,小于 250 个字符,并且匹配正则表达式 [a-z][a-z0-9.-]*

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 export or replace the $CHANNEL_NAME variable appropriately

peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

注意 --cafile 会作为命令的一部分。这是排序节点的根证书的本地路径,允许我们去验证 TLS 握手
peer0.org1.example.com 加入通道。

# By default, this joins ``peer0.org1.example.com`` only
# the <CHANNEL_NAME.block> was returned by the previous command
# if you have not modified the channel name, you will join with mychannel.block
# if you have created a different channel name, then pass in the appropriately named block

 peer channel join -b mychannel.block

修改环境变量,将四个节点都加入通道

peer1.org1.example.com 加入通道

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=peer1.org1.example.com:8051 
CORE_PEER_LOCALMSPID="Org1MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt 
peer channel join -b mychannel.block

peer0.org2.example.com 加入通道

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 
CORE_PEER_ADDRESS=peer0.org2.example.com:9051 
CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 
peer channel join -b mychannel.block

peer1.org2.example.com 加入通道

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 
CORE_PEER_ADDRESS=peer1.org2.example.com:10051 
CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt 
peer channel join -b mychannel.block

更新锚节点

更新通道定义,将 Org1 的锚节点定义为 peer0.org1.example.com 。

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  // 说明现在节点端口分别为 7050/8050/9050/10050
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

peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

将 Org2 的锚节点定义为 peer0.org2.example.com (与执行 Org2 节点的 peer channel join 命令相同,我们需要为这个命令配置合适的环境变量。)

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:9051 
CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 

peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

安装和实例化链码

只示范java的(安装之前先设置环境变量-这里不再一一设置,默认已设置好对应的环境变量)

# make note of the -l flag to indicate "java" chaincode
# for java chaincode -p takes the absolute path to the java chaincode
peer chaincode install -n mycc -v 1.0 -l java -p /opt/gopath/src/github.com/chaincode/chaincode_example02/java/

当我们在通道上实例化链码之后,背书策略被设定为需要 Org1Org2 的节点都背书。所以,我们需要在 Org2 的节点上也安装链码(最好是四个节点都安上好的链码之后在实例化)

接下来,在通道上实例化链码。这会在通道上初始化链码,为链码指定背书策略,然后为目标节点启动链码容器。注意 -P 这个参数。这是我们的策略,我们在此策略中指定针对要验证的此链码的交易所需的背书级别。

在下面的命令里你将会注意到我们指定 -P "AND ('Org1MSP.peer','Org2MSP.peer')" 作为策略。这表明我们需要属于 Org1 和 Org2 的节点“背书” (就是说要两个背书)。如果我们把语法改成 OR ,那我们将只需要一个背书。

peer chaincode instantiate -o orderer.example.com:7050 --tls --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 -l java -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"

查询
# be sure to set the -C and -n flags appropriately

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

//输出为100
调用

调用之后再用上面语句查询,显示结果为90

# be sure to set the -C and -n flags appropriately

peer chaincode invoke -o orderer.example.com:7050 --tls true --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 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'

关于第一个网络的详解到此结束

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值