搭建账本Fabric-sample first-network(二)

作者:ethanlu([email protected])

创建于:2018/7/18

最后修改:2018/7/18

1、安装预置环境

检查一下在开发区块链应用程序或者Hyperledger Fabric的平台上是否已经安装了预置环境。

1、下载并安装Hyperledger的Fabric-samplesfabric-samples文件夹中包含了许多示例:

需要git branch 切换到v1.0.2(git checkout v.1.0.2)否则报错。

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

2、我们将使用first-network这个例子。现在让我们打开这个子目录。 

cd first-network

注意:本文档中提供的命令必须运行在fabric-sample的子目录first-network中。如果你选择从其他位置运行命令,提供的一些列脚本将无法找到对应的二进制工具。

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

./byfn.sh -h

以下是该byfn.sh脚本的帮助文档:

如果你选择不提供channel名称,则脚本将使用默认名称mychannel。CLI超时参数(用-t标志指定)是一个可选值;如果你选择不设置它,那么CLI容器将会在脚本执行完之后退出。

4、执行该脚本:

./byfn.sh -m generate

接下来,可以使用以下命令来启动整个网络。再试提示是否继续。回答y:

生成工具后会出现如下界面:

第一步生成我们各种网络实体的所有证书和密钥,genesis block用于引导排序服务,以及配置Channel所需要的一组交易配置集合。

5、接下来,使用以下命令来启动整个网络:

 ./byfn.sh -m up

日志将继续。然后启动所有容器,驱动一个端到端的应用场景。成功以后,在终端窗口中会报告以下内容: 

 跑通之后会出现如下界面:

6、最后,让我们把它全部停下来,这样我们可以一步一步地探索网络设置。以下操作将关闭你的容器,移除加密材料和4个配置信息,并且从Docker仓库删除chaincode镜像。你将再一次被提示是否继续,回答y:

./byfn.sh -m down

 

测试用例说明:

1、加密生成器

Cryptogen消费一个包含网络拓扑的crypto-config.yaml,并允许我们为组织和属于这些组织的组件生成一组证书和密钥。每个组织都配置了唯一的根证书(ca-cert),它将特定组件(peers和orders)绑定到该组织。通过为每一个组织分配唯一的CA证书,我们正在模仿一个经典的网络,这个网络中的成员将使用自己的证书颁发机构。Hyperledger Fabric中的交易和通信是通过存储在keystore中的实体的私钥签名,然后通过公钥手段进行验证(signcerts)。

你将注意到在这个文件里有一个count变量。我们将使用它来指定每个组织中peer的数量;在我们的例子中,每个组织有两个peer。我们现在不会深入研究x.509证书和公钥基础设施的细节。如果你有兴趣,你可以在自己的时间细读这些主题。

在运行该工具之前,让我们快速浏览一下这段代码crypto-config.yaml。特别注意在OrdererOrgs头下的NameDomainSpecs参数:

OrdererOrgs:
#---------------------------------------------------------
# Orderer
# --------------------------------------------------------
- Name: Orderer
  Domain: example.com
  # ------------------------------------------------------
  # "Specs" - See PeerOrgs below for complete description
# -----------------------------------------------------
  Specs:
    - Hostname: orderer
# -------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ------------------------------------------------------
PeerOrgs:
# -----------------------------------------------------
# Org1
# ----------------------------------------------------
- Name: Org1
  Domain: org1.example.com

网络实体的命名约定如下:”{{.Hostname}}.{{.Domain}}”。所以使用我们的排序节点作为参考点,它与Order的MSP ID相关联。该文件包含了有关定义和语法的大量文档。

我们运行cryptogen工具,生成的证书和密钥将被保存到名为crypto-config的文件夹中。

2、配置交易生成器

configtxgen tool用于创建4个配置工作: order的genesis blockchannel的channel configuration transaction, * 以及两个anchor peer transactions一个对应一个Peer组织。

order block是一个ordering service的传世区块,channel transaction文件在Channel创建的时侯广播给order。anchor peer transactions,正如名称所示,指定了每个组织在此channel上的Anchor peer。

Configtxgen使用一个包含示例网络的configtx.yaml文件。有3个成员-一个排序服务组织OrdererOrg以及两个节点组织(Org1&Org2),每个组织管理和持有2个peer节点。该文件还指定了一个SampleConsortium的联盟,由上述2个节点组织构成。 请特别注意此文件顶部的”Profiles”部分。你会注意到我们有两个独特的标题。一个是orderer的创世区块-TwoOrgsOrdererGenesis-另一个是针对管道的TwoOrgsChannel

此文件还包含两个值得注意的附加规格。首先,我们为每个组织指定了锚点节点(peer0.org1.example.compeer0.org2.example.com)。其次,我们为每个成员指定MSP文件夹,用来存储每个组织在orderer genesis block中指定的根证书。这是一个关键的概念。现在任意和ordering service通信的网络实体都可以对其数字签名进行验证。

3、运行工具

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

必要的话,你可以参考byfn.sh脚本中的generateCerts函数去生成相关定义在crypto-config.yaml文件中用于你的网络配置的相关证书。然而,为了方便起见,我们也将在此提供参考。

首先,我们来运行cryptogen这个工具。我们的二进制文件在bin目录中,所以我们需要提供工具所在的相对路径。

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

接下来,我们需要告诉configtxgen工具需要提取的configtx.yaml所在的位置。我们会告诉它在我们当前所在工作目录:

首先,我们需要设置一个环境变量来告诉configtxgen哪里去寻找configtx.yaml。然后,我们将调用configtxgen工具去创建orderer genesis block

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

你可以忽略有关中间证书,证书撤销列表(crls)和MSP配置的日志警告。我们没有在示例网络中使用其中的任何一个。

接下来,我们需要创建channel transaction配置。请确保替换$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

接下来,我们将在正在构建的通道上定义Org1anchor peer。请再次确认$CHANNEL_NAME已被替换或者为以下命令设置了环境变量:

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

现在,我们将在同一个通道定义Org2anchor peer

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

4、启动网络

利用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

启动网络,channel__name默认为mychannel:

CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=<pick_a_value> docker-compose -f docker-compose-cli.yaml up -d

5、 环境变量设置

为了使针对peer0.org1.example.com的CLI命令起作用,我们需要使用下面给出四个环境变量来介绍我们的命令。为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/[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

6、创建/加入channel

使用docker exec命令进入CLI容器:

docker exec -it cli bash

如果成功将看到下列信息:

root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#

使用configtxgen工具生成信道配置-channel.tx。将这个配置作为请求的一部分传递给order。

使用-c标志指定channel的名字,-f标志指定配置交易。在这个例子中它是channel.tx,当然也可以使用不同的名称,挂载自己的交易配置。

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

此命令返回一个创世区块-<channel-ID.block>-我们将使用它加入信道。它包含了channel.tx中的配置信息。

加入peer0.org1.example.com信道。

# 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>

7、安装和实例化链码:

首先,在将示例代码安装到4个peer节点中的其中一个。这个命令将源代码放到peer节点的文件系统中。

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个背书者。

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

8、操作:

查询:查询一下a的值,以确保链码被正确实例化,state DB被填充。查询的语法如下:

# be sure to set the -C and -n flags appropriately
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

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

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

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

# 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

后台分析:

  • 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。

 

遇到的问题: 

1、cryptogen tool not found. exiting

ethanlu@ubuntu:~/go/src/github.com/hyperledger/fabric-samples/first-network$ ./byfn.sh -m generate
Generating certs and genesis block for with channel 'mychannel' and CLI timeout of '10000'
Continue (y/n)? t
invalid response
Continue (y/n)? y
proceeding ...
cryptogen tool not found. exiting

解决方法:

1、下载二进制工具:

curl -sSL https://goo.gl/Gci9ZX | bash

会出现新的问题:

curl: (7) Failed to connect to goo.gl port 443: Connection timed out

 这个问题google了也未必能解决,网上的说法一大堆,有的说是ipv6导致,有的说是防火墙导致

2、在浏览器中打开命令curl -sSL https://goo.gl/Gci9ZX | bash中的这个链接https://goo.gl/Gci9ZX(需要翻墙),然后你可以看到这其实就是一个shell脚本,脚本也就主要做了两件事:下载平台相关可执行文件和下载fabric docker镜像。内容如下:

#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

export VERSION=1.0.2
export ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}')
#Set MARCH variable i.e ppc64le,s390x,x86_64,i386
MARCH=`uname -m`

dockerFabricPull() {
  local FABRIC_TAG=$1
  for IMAGES in peer orderer couchdb ccenv javaenv kafka zookeeper tools; do
      echo "==> FABRIC IMAGE: $IMAGES"
      echo
      docker pull hyperledger/fabric-$IMAGES:$FABRIC_TAG
      docker tag hyperledger/fabric-$IMAGES:$FABRIC_TAG hyperledger/fabric-$IMAGES
  done
}

dockerCaPull() {
      local CA_TAG=$1
      echo "==> FABRIC CA IMAGE"
      echo
      docker pull hyperledger/fabric-ca:$CA_TAG
      docker tag hyperledger/fabric-ca:$CA_TAG hyperledger/fabric-ca
}

: ${CA_TAG:="$MARCH-$VERSION"}
: ${FABRIC_TAG:="$MARCH-$VERSION"}

echo "===> Downloading platform binaries"
curl https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/${ARCH}-${VERSION}/hyperledger-fabric-${ARCH}-${VERSION}.tar.gz | tar xz

echo "===> Pulling fabric Images"
dockerFabricPull ${FABRIC_TAG}

echo "===> Pulling fabric ca Image"
dockerCaPull ${CA_TAG}
echo
echo "===> List out hyperledger docker images"
docker images | grep hyperledger*

3、在你的fabric-sample下新建download.sh,将以上内容复制到文件里,然后保存退出执行以下命令: 

chmod a+x download.sh

 4、进入目录,然后执行命令:

./download.sh

这个时候bin文件夹下就会出现一堆二进制工具。

参考链接:https://www.jianshu.com/p/7d720393fea3

猜你喜欢

转载自blog.csdn.net/weixin_34960892/article/details/81094375
今日推荐