Hyperledger fabri 部署网络(单机环境)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yang731227/article/details/84029062

title: Hyperledger fabri 部署网络(单机环境)
tags: Hyperledger, fabric ,区块链


安装预置环境

下载项目

        首先我们需要配置好Hyperledger Fabric开发环境,然后下载并安装Hyperledger Fabric Samples。你会注意到fabric-samples文件夹中包含了许多示例。我们将使用first-network这个例子。

        你如果你不知道环境配置和Samlpes的下载安装,可以看我之前的文章:

https://blog.csdn.net/yang731227/article/details/83868333

使用脚本自动部署

         Hyperledger Fabric Samples提供一个完全注释的脚本byfn.sh,利用这些Docker镜像可以快速引导一个由4个代表2个不同组织的peer节点以及一个排序服务节点的Hyperledger fabric网络。它还将启动一个容器来运行一个将peer节点加入channel、部署实例化链码服务以及驱动已经部署的链码执行交易的脚本。

        为了使用byfn.sh 我们先切换到 first-network目录
```cd /home/go/src/fabric-samples/first-network`

1.查看byfn.sh帮助文档

./byfn.sh -h

注意:如果你选择不提供channel名称,则脚本将使用默认名称mychannel

  1. 生成配置

        第一步先生成成我们各种网络实体的所有证书和密钥。

./byfn.sh -m generate -i 1.0.0

只截取了部分信息

注意:1.0.0是镜像标签 ,使用 -i可以指定标签,如果不指定默认标签为latest, 下面命令中的1.0.0类同。

  1. 启动网络
            现在我们开始使用命令启动网络

./byfn.sh -m up -i 1.0.0

  1. 关闭网络
            当然我们也可以关闭网络,使用下面的命令会将关闭你的容器,移除加密材料和4个配置信息,并且从Docker仓库删除chaincode镜像

./byfn.sh -m down -i 1.0.0

使用工具手动部署

了解工具

  • 证书生成器

        fabric使用cryptogen工具,读取描述了网络的拓扑结构crypto-config.yaml的配置文件,来为网络中的实体生成证书(certificates)。这些证书是身份的代表,它们允许在我们的网络实体进行交流和交易时进行签名/验证身份验证。

        通过对每个组织分配唯一的CA证书,每个链成员通过自己的证书获取权限。Hyperledger Fabric中的交易和通信是通过存储在keystore中的实体的私钥签名,然后通过公钥手段进行验证(signcerts)。

        crypto-config.yaml文件里的count参数用来指指定每个组织中peer的数量。

有兴趣的小伙伴可以自己看本机的crypto-config.yaml文件。

  • 配置交易生成器

`configtxgen是Hyperledger Fabric提供的用于通道配置的实用程序,主要生成以下3种文件:

  • order genesis block :排序服务(ordering service)的创世区块。
  • channel configuration transaction : 通道配置交易,会在channel创建时广播给orderer。
  • 以及两个anchor peer transactions :指定通道上两个组织的锚节点(Anchor Peer)。

        Configtxgen使用一个包含简单网络的定义的configtx.yaml文件。该文件还指定了一个SampleConsortium的联盟,2个节点组织构成。

请注意,我们SampleConsortium在系统级配置文件中定义,然后由我们的通道级配置文件引用。渠道存在于一个联盟的范围内,所有联盟必须在整个网络的范围内定义。

手动生成配置文件

        我们可以用configtxgencryptogen命令来手动生成证书/密钥和各种配置文件。

注意:cryptogenconfigtxgen 都是需要我们手动编译生成的,并且存放在$GOPATH/bin/
如何生成,可以查看我之前的文章
https://blog.csdn.net/yang731227/article/details/83868333

  1. 生成证书
            首先我们运行crytyogen工具,我们的二进制文件位于bin 目录中. 我们可以通过修改crypto-config.yaml文件来生成我们需要的证书。

首先进入存放crypto-config.yaml的目录

cd  fabric-samples/first-network

然后执行工具生成证书

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

执行命令返回信息:

org1.example.com
org2.example.com

执行命令后,证书和密钥(也就是MSP material)将输出到crypto-config目录中,里面是各个组织的安全文件。

  1. 生成创世区块

        接下来,我们需要告诉configtxgen去哪找到需要的配置文件configtx.yaml,所以我们先先设置一个环境变量。
必须在fabric-samples/first-network 目录下使用
export FABRIC_CFG_PATH=$PWD

然后,我们将调用configtxgen工具去创建orderer genesis block

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

注意: orderer genesis块和我们即将创建的后续工件将输出到channel-artifacts该项目根目录的目录中。上述命令中的channelID是系统通道的名称。

  1. 创建channel transaction配置(channel.tx)

        接下来,我们需要创建channel transaction配置。执行命令前需要设置$CHANNEL_NAME环境变量。

export CHANNEL_NAME=mychannel`
$GOPATH/bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME`

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

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

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

order genesis block 和 channel transaction artifacts都将输出到channel-artifacts目录下。最终目录包含4个文件:genesis.block,channel.tx,Org1MSPanchors.tx和Org2MSPanchors.tx。

启动网络

注意:如果你之前使用 byfn.sh脚本开启了网络,请确保在继续操作之前已关闭测试网络。

        我们将利用docker-compose脚本来启动我们的区块链网络。docker-compose文件利用我们之前下载的镜像,并用以前生成的genesis.block来引导orderer。

        在运行之前,需要修改docker-compose-cli.yaml文件,使用#注释掉下面的代码:

#command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME} ${DELAY}; sleep $TIMEOUT'

        该行代码会使cli容器运行的时候自动运行脚本script.sh,会进行创建channel,加入节点等等一系列操作,此时如果再进行手动执行,并把CHANNEL_NAME设置为mychannel,就会出现channel名称重复问题,从而报错 Error: got unexpected status: BAD_REQUEST

1.运行docker-compose命令启动网络:

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

CLI容器处于空闲状态时只会会停留1000秒。你可以使用以下命令再次启动它:

docker start cli

2.设置环境变量
        下面是peer0.org1.example.com的环境变量。每当在CLI命令中需要执行节点操作时,都要确认当前处于哪个节点下。

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/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

        CLI容器针对peer0.org1.example.com操作所需要的环境变量已经设置好了,但如果需要对其他peer或者orderer节点进行操作,则需要提供这些变量值。

        例如,要切换至peer1.org1节点,就需要将peer0.org1.example.com在环境变量中进行替换。同理,如果切换到其他节点,需要对应的修改环境变量。

3.创建&加入信道

我们使用configtxgen工具创建channel transaction配置 。你可以重复使用相同或不同的configtx.yaml文件,在你的网络创建其他的信道。

        我首先进入CLI容器中:

docker exec -it cli bash

        如果执行成功,你将看到下列信息:opt/gopath/src/github.com/hyperledger/fabric/peer#

        我们使用-c标志指定channel的名字,-f标志指定channel配置文件。在这个例子中它是channel.tx,当然你也可以使用不同的名称,挂载你自己的channel配置。再一次,我们将在CLI容器里设置了CHANNEL_NAME环境变量,所以不需要明确传递这个参数。

export CHANNEL_NAME=mychannel

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会作为命令的一部分。这是orderer的root cert的本地路径,允许我们去验证TLS握手。

        此命令返回一个创世区块<channel-ID.block>,我们将使用它加入信道。它包含了channel.tx中的配置信息。如果你没有修改过channel.tx文件中默认的通道名称,上面的命令会返回mychannel.block

        现在让我们将peer0.org1.example.com加入channel。

peer channel join -b mychannel.block

        前面我们说过,当需要加入其他节点的时候,需要设置环境变量

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:7051 
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 

我们继续加入peer0.org2.example.com

peer channel join -b mychannel.block

你可以修改环境变量来让别的节点加入信道,这里我就不演示了。

  1. 更新锚节点(anchor peers)

        我最后添加到节点是peer1.org2.example.com,所以执行完成后我们的命令行现在处于peer1.org2下。而现在我们需要为Org1设置锚节点peer0.org1,所以命令行需要先切回到peer0.org1

设置当前操作节点为peer0.org1

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/[email protected]/msp 
CORE_PEER_ADDRESS=peer0.org1.example.com:7051

然后更新Org1锚节点为peer0.org1

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

设置当前操作节点为peer0.org2:

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 
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp 
CORE_PEER_ADDRESS=peer0.org2.example.com:7051

然后更新Org2锚节点为peer0.org2

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

安装和实例化链码

        我们将利用一个现有的简单链码,应用程序和区块链账本会相互影响通过chaincode。因此,我们需要在每个会执行以及背书我们交易的peer节点安装chaincode,然后在信道上实例化chaincode

chaincode 支持很多语言,如Gland ,Node.js ,Java 。

安装

在这里我们使用Golang版本的,现在我们来安装下

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

        接下来,在信道上实例化chaincode。这将初始化信道上的链码,设置链码的背书策略,为目标peer节点启动一个chaincode容器注意-P参数。这是我们需要指定的当这个chaincode的交易需要被验证的时侯的背书策略。

        在下面的命令中,你会注意到我们指定-P "OR ('Org0MSP.member','Org1MSP.member')"作为背书策略。这意味着我们需要Org1或者Org2组织中的其中一个的节点的背书即可(即只有一个背书)。如果我们改变语法为AND那么我们就需要2个背书者。

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')"

实例化

现在我们来进行实战

1.查询(Query)
让我们查询一下a的值,以确保链码被正确实例化,state DB被填充。查询的语法如下:

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

2.调用(Invoke)
现在让我们从a账户转10到b账户。这个交易将创建一个新的区块并更新state DB。调用语法如:

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"]}'

3.我们再次查询

让我们确认下我们之前的调用被正确地执行了。我们初始化了a的值为100,在上一次调用的时侯转移了10给b。因此,查询a应该展示90。查询的语法如下:

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

运行过程分析

以下是通过./byfn.sh -m up启动网络时,运行script.sh脚本所进行步骤

  • script.sh脚本被拷贝到CLI容器中。这个脚本驱动了使用提供的channel name以及信道配置的channel.tx文件的 createChannel命令。

  • createChannel命令的产出是一个创世区块- <your_channel_name>.block-这个创世区块被存储在peer节点的文件系统中同时包含了在channel.tx的信道配置。

  • joinChannel命令被4个peer节点执行,作为之前产生的genesis block的输入。这个命令介绍了peer节点加入 <your_channel_name>以及利用 <your_channel_name>.block去创建一条链。

  • 现在我们有了由4个peer节点以及2个组织构成的信道。这是我们的 TwoOrgsChannel配置文件。

  • peer0.org1.example.compeer1.org1.example.com属于Org1; peer0.org2.example.compeer1.org2.example.com属于Org2

  • 这些关系是通过crypto-config.yaml定义的,MSP路径在docker-compose文件中被指定。

  • Org1MSP( peer0.org1.example.com)和Org2MSP( peer0.org2.example.com)的anchor peers将在后续被更新。我们通过携带channel的名字传递 Org1MSPanchors.txOrg2MSPanchors.tx配置到排序服务来实现anchor peer的更新。

  • 一个链码- chaincode_example02被安装在 peer0.org1.example.compeer0.org2.example.com

  • 这个链码在 peer0.org2.example.com被实例化。实例化过程将链码添加到信道上,并启动peer节点对应的容器,并且初始化和链码服务有关的键值对。示例的初始化的值是 [”a“,”100“,”b“,”200“]。实例化的结果是一个名为 dev-peer0.org2.example.com-mycc-1.0的容器启动了。

  • 实例化过程同样为背书策略传递相关参数。策略被定义为 -P "OR ('Org1MSP.member','Org2MSP.member')",意思是任何交易必须被Org1或者Org2背书。

  • 一个针对 a的查询发往 peer0.org1.example.com。链码服务已经被安装在了 peer0.org1.example.com,因此这次查询将启动一个名为 dev-peer0.org1.example.com-mycc-1.0的容器。查询的结果也将被返回。没有写操作出现,因此查询的结果的值将为 100

  • 一次 invoke被发往 peer0.org1.example.com,从 a转移 10b

  • 然后链码服务被安装到 peer1.org2.example.com

  • 一个 query请求被发往 peer1.org2.example.com用于查询 a的值。这将启动第三个链码服务名为 dev-peer1.org2.example.com-mycc-1.0。返回 a的值为90,正确地反映了之前的交易, a的值被转移了10。

猜你喜欢

转载自blog.csdn.net/yang731227/article/details/84029062