本文参考:http://hyperledger-fabric.readthedocs.io/en/latest/build_network.htmlhtml
这里咱们学习创建第一个Hyperledger Fabric network,包括两个organization(每一个包括2个peer节点),以及一个“solo”的ordering service。node
前提条件:安装docker、docker compose、go环境、npm、node.js,下载并安装好了Hyberledger Fabric Samples。git
安装Hyberledger Fabric Samples简介:github
mkdir hyberledger-fabric
cd hyberledger-fabric
git clone https://github.com/hyperledger/fabric-samples.git
curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap-1.0.0-rc1.sh | bash
上述命令会下载自动化部署脚本,同时也会下载平台特定使用的二进制文件cryptogen,configtxgen,configtxlator, 以及peer,把他们放到上述仓库的bin目录下docker
接下来把bin目录加入到PATH环境变量中npm
vi /etc/profile
打开profile而后把下面语句添加进去便可bootstrap
export PATH=/home/parallels/hyberledger-fabric/bin:$PATHbash
1.尝试run first-network网络
cd fabric-samples/first-network
这里提供了一个脚本,byfn.sh,咱们能够查看其的使用方法app
若是你没有指定channel的名称,则该脚本则会使用默认的channel名称(mychannel)
CLI的超时参数(-t flag)能够选择,若是不选择,那么CLI容器将在脚本结束后退出。
2.生成network artifacts
执行以下命令:
./byfn.sh -m generate
遇到须要选择的地方选择y,会看到以下日志
这一步生成了network entity所须要的certificates以及keys,genesis block用于获取用于配置channel的ordering service以及transaction配置的集合。
3.启动network
接下来输入如下命令启动network,回复y
./byfn.sh -m up
能够看到以下输出结果
./byfn.sh -m up Starting with channel 'mychannel' and CLI timeout of '10000' Continue (y/n)?y proceeding ... Creating network "net_byfn" with the default driver Creating peer0.org1.example.com Creating peer1.org1.example.com Creating peer0.org2.example.com Creating orderer.example.com Creating peer1.org2.example.com Creating cli ____ _____ _ ____ _____ / ___| |_ _| / \ | _ \ |_ _| \___ \ | | / _ \ | |_) | | | ___) | | | / ___ \ | _ < | | |____/ |_| /_/ \_\ |_| \_\ |_| Channel name : mychannel Creating channel...
日志从这里开始,这将启动全部的容器,造成这个完整的P2P的应用场景。
启动成功后会打印以下日志:
2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP 2017-05-16 17:08:01.366 UTC [msp] GetDefaultSigningIdentity -> DEBU 005 Obtaining default signing identity 2017-05-16 17:08:01.366 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AB1070A6708031A0C08F1E3ECC80510...6D7963631A0A0A0571756572790A0161 2017-05-16 17:08:01.367 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: E61DB37F4E8B0D32C9FE10E3936BA9B8CD278FAA1F3320B08712164248285C54 Query Result: 90 2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting..... ===================== Query on PEER3 on channel 'mychannel' is successful ===================== ===================== All GOOD, BYFN execution completed ===================== _____ _ _ ____ | ____| | \ | | | _ \ | _| | \| | | | | | | |___ | |\ | | |_| | |_____| |_| \_| |____/
经过上述日志可以看到不一样的transaction。
4.关闭network
输入以下命令
./byfn.sh -m down
可以看到输出日志以下:
./byfn.sh -m down Stopping with channel 'mychannel' and CLI timeout of '10000' Continue (y/n)?y proceeding ... WARNING: The CHANNEL_NAME variable is not set. Defaulting to a blank string. WARNING: The TIMEOUT variable is not set. Defaulting to a blank string. Removing network net_byfn 468aaa6201ed ... Untagged: dev-peer1.org2.example.com-mycc-1.0:latest Deleted: sha256:ed3230614e64e1c83e510c0c282e982d2b06d148b1c498bbdcc429e2b2531e91 ...
若是您想了解有关底层工具和引导机制的更多信息,请继续阅读。 在接下来的章节中,咱们将介绍构建功能齐全的Hyperledger Fabric网络的各类步骤和要求。
5.Crypto生成器
咱们使用crytogen工具给咱们不一样的network entity生成加密证书(X509 certs)。这些证书表明了身份,当咱们的entity在进行通讯以及transact的时候进行签名与验证身份。
Cryptogen有一个配置文件crypto-config.yaml,包括了网络拓扑,同时容许咱们给organization以及component(隶属于organization)生成一个证书与私钥的集合。每个organization被分配一个惟一的根证书(绑定了隶属于Org的具体的component,包括peers与orderers)。经过给每一个organization分配一个惟一的CA证书,咱们正在模仿一个典型的网络,参与的成员将使用本身的证书颁发机构颁发的证书。Hyperledger Fabric的transaction与通讯均被entity的私钥(keystore)进行签名,截止被公钥进行验证(signcerts)。
这个配置文件中有一个计数(count)的变量,咱们使用其定义organization中peer的数量,在本例中咱们定义每个Org有两个peer。这里不会深刻讨论X.509证书以及公钥框架。
在run这个工具以前,咱们回顾一下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
network entity的命名规则约定以下:“{{.Hostname}}.{{.Domain}}”。所以,使用咱们的ordering node做为参考,咱们能看到一个名称为 - orderer.example.com的ordering node,该node与Orderer的MSP ID关联。 您还能够参考会员 Membership Service Providers (MSP)文档,以便更深刻地了解MSP。
咱们运行cryptogen工具以后,生成的证书与秘钥将会保存到crypto-config文件夹中。
6.配置transaction生成器
configtxgen tool用于建立以下配置项:
genesis block:是一个配置block用于初始化blockchain网络以及channel的,一样能够做为链上的第一个block
genesis block
,channel configuration transaction
如何使用该工具请查看, Channel Configuration (configtxgen)
orderer block是ordering service的genesis block,channel transaction file在channel建立时广播给orderer。anchor peer transactions在channel定义了一个Org Anchor Peer。
Configtxgen有一个配置文件configtx.yaml,包括了sample network的定义。现有3个成员:一个Orderer Org以及两个Peer Orgs(Org1 Org2,每一个包括2个peer节点)。这个文件定义了一个联合consortium,包括两个Peer Org。注意该文件的顶部profile section。你会发现有两个惟一的headers。一个用做orderer Genesis block - TwoOrgsOrdererGenesis
-,一个用做channel - TwoOrgsChannel。
后续咱们在来看这些headers。
注意:sampleConsortium被定义在system-level profile中,接下来被channel-level profile引用。Channels存在在consortium的范围内,全部的consortium都在network的范围内。
这个配置文件包括了两个附加的定义。一个就是每一个Peer Org(peer0.org1.example.com
& peer0.org2.example.com
)的anchor节点,另一个就是指向每一个成员的MSP目录的位置,基于此,咱们能够将每一个Org的根证书存放在orderer Genesis block中,这是一个很重要的概念。如今任意network entity与ordering service通讯时就能对起数字签名进行验证。
7.运行tool
能够经过configtxgen
and cryptogen手动生成证书/密钥以及各项配置文件。一样,能够参考byfn.sh脚本实现。
接下来咱们尝试手动生成。
能够参考byfn.sh脚本中的generateCerts函数用来生成证书(这些证书被定义在crypto-config.yaml中的网络配置所使用)所须要的命令。为了方便起见,咱们提供一个参考以下。
首先,先跑起来cryptogen工具,咱们的二进制文件都在bin目录下,所以咱们须要cd到tool所在的目录下.
../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
接着,咱们建立channel transaction artifact(channel.tx)。而后,确保替换$CHANNEL_NAME(这里我用zeychannel替换的)或设置环境变量,语句以下:
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上定义Org1的anchor节点。而后,确保替换$CHANNEL_NAME(这里我用zeychannel替换的)或设置环境变量,语句以下:
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
而后,咱们在相同的channel上定义Org2的anchor节点。
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
8.启动network
咱们利用docker-compose脚原本启动咱们的network。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
若是没有注释掉上面的命令的话,在network启动的时候,其将执行全部的CLI命令,具体请见 What’s happening behind the scenes?节。咱们须要分析每一步的功能及句法,所以咱们一步步执行命令。
timeout的变量适合使用较高的数值,默认是60s。
启动network,注意$CHANNEL_NAME,<pick_a_value>本身设定
CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=<pick_a_value> docker-compose -f docker-compose-cli.yaml up -d
若是想看到实时日志,则不要加-d标示。若是须要日志流,则须要打开第二个终端进行操做。
9.环境变量
对于如下针对peer0.org1.example.com的CLI命令,咱们须要使用如下给出的四个环境变量来介绍咱们的命令。这些peer0.org1.example.com变量都被包含在CLI容器里,所以咱们能够不用传递的操做它们。然而!,若是你想发送calls到其余peers或者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
10.建立并进入Channel
接下来进入到刚建立的CLI容器里面,
docker exec -it cli bash
若是成功则能看到以下信息
请回忆下咱们使用configtxgen工具生成channel配置artifact-channel.tx。咱们将把artifact做为建立channel的请求的一部分发送给orderer。
注意到在接下来的命令中咱们发送了-- cafile做为命令的一部分。这个是orderer证书的本地路径,使得咱们能够验证TLS握手。
咱们使用-c flag 标注出咱们的channel名称,用-f flag标注出咱们的channel 配置transaction。在本例中是channel.tx,然而你可使用不一样的名称用于挂载配置transaction。使用下面建立channel的语句的时候注意channel-name。
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>
-咱们能够经过这个id进入到channel。它包含channel.tx中指定的配置信息,建立成功后有以下输出:
接下来的操做都须要在CLI容器中进行,在操做peer0.org1.example.com以外的peer时,须要记得相关环境变量的命令。
接下来咱们把peer0.org1.example.com加入到channel中去,channel-ID.block是以前生成的,这里个人是zeychannel.block。
# 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>
如下是成功的显示
你可把其余的peer加入到该channel上,可是须要设置上述的四个环境变量。
11.安装并实例化chaincode
咱们这里只是使用已经存在的chaincode。
application经过chaincode与blockchain ledger进行交互。咱们把chaincode安装到execute与endorse咱们transaction的peer上,接下来在channel上初始化chaincode。
首先,安装sample go代码到4个peer之一的peer上。如下命令把chaincode的源代码放到了peer节点的文件系统上。
peer chaincode install -n zeychaincode -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
安装成功打印以下日志
接下来,在channel上实例化chaincode。这将在channel上初始化chaincode,同时设置chaincode的endorsement的策略,而后在目标peer上启动chaincode容器。请注意-P参数,咱们经过设置这个参数,来指定transaction的endorsement的需求level,用于验证chaincode。
在下面的命令,咱们定义了endorsement策略为-P "OR ('Org0MSP.member','Org1MSP.member')"。这表示咱们须要隶属于Org1或者Org2的peer进行“endorsement”(也就是说,只有一个endorsement)。若是把or改成and则说明咱们须要两个endorsement。
# 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 zeychannel -n zeychaincode -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
请在 endorsement policies中查看更详细的策略说明。
12.查询
首先查询a的值,确保chaincode已经正常的实例化,同时确保state DB已经被填充
# be sure to set the -C and -n flags appropriately peer chaincode query -C zeychannel -n zeychaincode -c '{"Args":["query","a"]}'
13.调用
让咱们从a帐户转移10个到b帐户,这个命令将会建立新的block同时更新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 zeychannel -n zeychaincode -c '{"Args":["invoke","a","b","10"]}'
而后查询
# be sure to set the -C and -n flags appropriately peer chaincode query -C zeychannel -n zeychaincode -c '{"Args":["query","a"]}'
14.上述调用过程解析
TwoOrgsChannel
profile.里面。peer0.org1.example.com
与 peer1.org1.example.com
隶属于 Org1; peer0.org2.example.com 以及
peer1.org2.example.com
隶属于 Org2。这些关系在crypto-config.yaml中定义,同时在咱们的docker compose中指定了MSP的路径。peer0.org1.example.com
) 以及 Org2MSP (peer0.org2.example.com
)的anchor节点接下来被更新了。咱们基于创建的channel把Org1MSPanchors.tx
与 Org2MSPanchors.tx
的artifacts,发送给orderering service,以实现上述的更新。peer0.org1.example.com
与 peer0.org2.example.com