作者:ethanlu([email protected])
创建于:2018年7月18日
最后修改:2019年7月11日
【重点:如果之前跑过e2e的sample,在跑这个之前一定要把镜像删掉,官网有这一步操作。】
# 在e2e_cli目录下
docker rm -f $(docker ps -aq)
如果不成功依次删除各个镜像
docker rmi hyperledger-zookeeper
最后清理全部images
docker rmi $(docker images -q)
检查一下在开发区块链应用程序或者Hyperledger Fabric的平台上是否已经安装了预置环境。
1、下载并安装Hyperledger的Fabric-samples
。fabric-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
。如果你选择从其他位置运行命令,提供的一些脚本将无法找到对应的二进制工具(如bin目录下的crypto)。
3、我们提供一个完全注释的脚本byfn.sh,利用这些docker镜像可以快速引导一个由4个代表2个不同的组织对等以及节点排序一个服务节点的Hyperledger fabric
网络。它还将启动一个容器来运行一个对等节点加入通道,部署实例化链码以及驱动已经部署的链码执行交易的脚本。
./byfn.sh -h
以下是byfn.sh
脚本的帮助文档:
如果你选择不提供信道名称,则脚本将使用默认名称mychannel
.CLI超时参数(用-t标志指定)是一个可选值;如果你选择不设置它,那么CLI容器将会在脚本执行完之后退出。
如图4所示,执行该脚本(会报错,文章的最后问题解答有解决办法):
./byfn.sh -m generate
接下来,可以使用以下命令来启动整个网络再试提示是否继续:
生成工具后会出现如下界面:
第一步生成我们各种网络实体的所有证书和密钥,genesis block
用于引导排序服务,配置以及Channel
所需要的一组交易配置集合。
5,接下来,使用以下命令来启动整个网络:
./byfn.sh -m up
日志将继续然后启动所有容器,驱动一个端到端的应用场景成功以后,在终端窗口中会报告以下内容:
跑通之后会出现如下界面:
6,最后,让我们把它全部停下来,这样我们可以一步一步地探索网络设置。以下操作将关闭你的容器,移除加密材料和4个配置信息,并且从docker库删除chaincode镜像。你将再一次被提示是否继续,回答Y:
./byfn.sh -m down
如图1所示,加密生成器
Cryptogen
消费一个包含网络拓扑的crypto-config.yaml
,并允许我们为组织和属于这些组织的组件生成一组证书和密钥。每个组织都配置了ca-cert
唯一的根证书(),它将特定组件(对等体和订单)绑定到该组织。通过为每一个组织分配唯一的CA证书,我们正在模仿一个经典的网络,这个网络中的成员将使用自己的证书颁发机构.Hyperledger Fabric中的交易和通信是通过存储在keystore
中的实体的私人签名,然后通过公司手段进行验证(signcerts
)。
将你在注意到这个文件里有一个count
变量我们将使用它来指定每个组织中。peer
的数量;在我们的例子中,每个组织有两个对等体我们现在不会深入研究X.509证书基础状语从句:公钥设施。的细节如果你有兴趣,你可以在自己的时间细读这些主题。
在运行该工具之前,让我们浏览快速一下这段代码crypto-config.yaml
注意特别在。OrdererOrgs
头下的Name
,Domain
状语从句:Specs
参数:
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 block
, channel的channel configuration transaction
,*以及两个anchor peer transactions
一个对应一个Peer组织。
order block
是一个订购服务的传世区块,channel transaction
文件在Channel
创建的时侯广播给订单。anchor peer transactions
,正如名称所示,指定了每个组织在此频道上的锚点同伴。
Configtxgen使用一个包含示例网络的configtx.yaml
文件。有3个成员 - 一个排序服务组织OrdererOrg
以及两个节点组织(Org1
&Org2
),每个组织管理和持有2个对等节点。该文件还指定了一个SampleConsortium
的联盟,由上述2个节点组织构成。请特别注意此文件顶部的“个人资料”部分。你会注意到我们有两个独特的标题。一个是orderer的创世区块 - TwoOrgsOrdererGenesis
- 另一个是针对管道的TwoOrgsChannel
。
此文件还包含两个值得注意的附加规格。首先,我们为每个组织指定了锚点节点(peer0.org1.example.com
和peer0.org2.example.com
)。其次,我们为每个成员指定MSP文件夹,存储用来组织每个在orderer genesis block
中指定的根证书。这是一个关键的概念。现在任意和订购服务通信的网络实体都可以对其数字签名进行验证。
3,运行工具
你可以用configtxgen
状语从句:cryptogen
。命令来手动生成证书/密钥和各种配置文件或者,你可以使用尝试脚本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
你可以忽略有关中间证书,证书撤销列表(CRL)的和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
接下来,将我们在正在构建的通定上定义Org1
的anchor peer
请再次确认$ CHANNEL_NAME已被替换或者为以下命令设置了环境变量:
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
现在,将我们同在一个通道定义Org2
的anchor 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= docker-compose -f docker-compose-cli.yaml up -d
5,环境变量设置
使为了针对peer0.org1.example.com
的CLI命令起作用,我们需要使用下面给出四个环境变量来介绍我们的命令。为peer0.org1.example.com
涉及的这些变量将被拷贝产品产品产品到CLI容器中,因此我们不需要复制它们。然而,如果你发送调用到其他的同行节点或者命令者,需要则相应地提供这些值检查。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,创建/加入通道
使用docker exec
命令展示展示展示进入CLI容器:
docker exec -it cli bash
如果成功将看到下列信息:
root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
使用configtxgen工具生成信道配置 - channel.tx
。将这个配置作为请求的一部分传递给订单。
使用-c
标志指定信道的名字,-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.tx
中的配置信息。
加入peer0.org1.example.com信道。
# By default, this joins ``peer0.org1.example.com`` only
# the .block was returned by the previous command
peer channel join -b
如图7所示,安装和实例化链码:
首先,在将示例代码安装到4个对等节点中的其中一个。这个命令将源代码放到对等节点的文件系统中。
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
接下来,在信道上实例化chaincode。这将初始化信道上的链码,设置链码的背书策略,为目标对等节点启动一个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
账户的的的转10
到b
。账户的这个交易将创建³³一个新的区块更新并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
,上在一次调用的时侯转移了10
给b
因此,查询。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.tx文件的createChannel
命令。
createChannel
命令的产出是一个创世区块 -
- 这个创世区块被存储在对象节点的文件系统中同时包含了在channel.tx的信道配置。
joinChannel
命令被4个对等节点执行,作为之前产生的genesis block的输入。这个命令介绍了对象节点加入
以及利用
去创建一条链。
现在我们有了由4个对等节点以及2个组织构成的信道。的英文这我们的TwoOrgsChannel
配置文件。
peer0.org1.example.com
状语从句:peer1.org1.example.com
属于ORG1; peer0.org2.example.com
状语从句:peer1.org2.example.com
属于ORG2
这些关系是通过加密config.yaml定义的,MSP路径在搬运工 - 撰写文件中被指定。
Org1MSP(peer0.org1.example.com
)和Org2MSP(peer0.org2.example.com
)的锚同伴将在后续被更新。我们通过携带通道的名字传递Org1MSPanchors.tx
和Org2MSPanchors.tx
配置到排序服务来实现anchor peer的更新。
一个链码- chaincode_example02
被安装在peer0.org1.example.com
状语从句:peer0.org2.example.com
这个链码在peer0.org2.example.com
被实例化。实例化过程将链码添加到信道上,并启动对等节点对应的容器,并且初始化和链码服务有关的键值对。示例的初始化的值是[”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
转移10
到b
。
然后链码服务被安装到peer1.org2.example.com
一个query
请求被发往peer1.org2.example.com
用于查询a
的值。这将启动第三个链码服务名为dev-peer1.org2.example.com-mycc-1.0
。查看报道a
的值为90,正确地反映了之前的交易,a
的值被转移了10。
1,找不到密码工具退出。
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
这个问题谷歌了也未必能解决,网上的说法一大堆,有的说是IPv6的的导致,有的说是防火墙导致
2,浏览在器中打开命令curl -sSL https://goo.gl/Gci9ZX | bash
中的这个链接https://goo.gl/Gci9ZX
(需要),然后你可以看到这其实就是一个shell脚本,脚本也就主要做了两件事:下载平台相关可执行文件和下载镜像内容如下:
#!/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(vim download.sh)
,
vim download.sh
将以上脚本内容复制到文件里,然后保存退出执行以下命令:
chmod a+x download.sh
进入目录,然后执行脚本:
./download.sh
这个时候文件夹下就会出现一堆二进制工具。
参考链接:https://www.jianshu.com/p/7d720393fea3
2,CRIT 002错误解组为struct:4错误解码:
ethanlu@ubuntu:~/go/src/github.com/hyperledger/fabric-samples/first-network$ ./byfn.sh -m generate
Generating certs and genesis block for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds
Continue? [Y/n] y
proceeding ...
/home/ethanlu/go/src/github.com/hyperledger/fabric-samples/first-network/../bin/cryptogen
##########################################################
##### Generate certificates using cryptogen tool #########
##########################################################
+ cryptogen generate --config=./crypto-config.yaml
org1.example.com
org2.example.com
+ res=0
+ set +x
/home/ethanlu/go/src/github.com/hyperledger/fabric-samples/first-network/../bin/configtxgen
##########################################################
######### Generating Orderer Genesis block ##############
##########################################################
+ configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
2018-08-09 18:52:52.229 PDT [common/configtx/tool] main -> INFO 001 Loading configuration
2018-08-09 18:52:52.235 PDT [common/configtx/tool/localconfig] Load -> CRIT 002 Error unmarshaling config into struct: 4 error(s) decoding:
* '' has invalid keys: capabilities
* 'Profiles[TwoOrgsChannel].Application' has invalid keys: Capabilities
* 'Profiles[TwoOrgsOrdererGenesis]' has invalid keys: Capabilities
* 'Profiles[TwoOrgsOrdererGenesis].Orderer' has invalid keys: Capabilities
+ res=1
+ set +x
Failed to generate orderer genesis block...
此时git版本默认版本1.2 ,。在./byfn .sh -m生成时 要git branch 切换到v1.0.2(git checkout v.1.0.2)
3,无法连接到http + docker:// localhost的Docker守护程序 - 它正在运行吗?
ethanlu@ubuntu:~/go/src/github.com/hyperledger/fabric-samples/first-network$ ./byfn.sh -m up
Starting with channel 'mychannel' and CLI timeout of '10000'
Continue (y/n)? y
proceeding ...
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
ERROR !!!! Unable to start network
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.37/containers/cli/logs?follow=1&stderr=1&stdout=1&tail=all: dial unix /var/run/docker.sock: connect: permission denied
注意一下。很多都是权限问题和版本问题。