通过上面的一系列操作,我们已经可以在本机环境中搭建fabric的开发环境,并可以编写基本的链码了.接下来,我们回过头来,从一个俯瞰的视角,来看看构建网络是怎么做的. byfn == Build Your First Network. 构建你的第一个网络.
整体结构
先来看byfn.sh 的源码, 直接拉到文件最后, 看最后的10几行代码:
当我们键入 ./byfn.sh -m up时,将会调用networkUp函数. 继续查看 networkUp函数:
函数执行时,一开始会检查环境需求(149行,checkPrereqs),然后判断是否已经生成过 crypto-config( 151 行), 因为我们是第一次运行, 这个目录是不存在的, 所以将会依次调用generateCerts, replacePrivateKey, generateChannelArtifacts (152-154行) 3个函数来生成相关的证书和创世区块等配置信息.
然后,根据是否使用 couchdb来执行不同的docker-compose命令. 默认情况下, couchdb是不启用的(需要使用-s参数指定), 所有将执行如下的命令:
IMAGE_TAG=$IMAGETAG
docker-compose
-f $COMPOSE_FILE up -d
2
>&1
替换掉默认值后,上面的命令相当于:
IMAGE_TAG=latest docker-compose -f docker-compose-cli.yaml up -d 2>&1
实际上是用docker-compose启动了一系列的docker容器.具体内容我们稍后再讲,继续往下看.
如果docker-compose命令运行成功, 将会继续执行一条 docker命令:
docker
exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT
这个命令的作用是在cli容器中执行scripts/script.sh脚本. 打开scirpt/script.sh文件,从上面的注释中可以看到该脚本将对我的网络进行一个端到端的测试(Build your first network (BYFN) end-to-end test).
很容易猜到, cli容器就是d
至此为止, 我们可以理出来byfn.sh执行的几个关键步骤:
1.生成配置及初始化文件 -> 2. 启动docker-compose容器 -> 3.在cli容器中执行测试脚本
1.生成配置及初始化文件
这个过程中,依次调用了generateCerts, replacePrivateKey, generateChannelArtifacts三个函数,相当于byfn.sh指定generate参数时的执行效果,即:byfn.sh -m generate.
generateCerts: 实际上是调用了下面的程序生成一系列的配置文件:
cryptogen
generate –config=./crypto-config.yaml
实例crypto-config.yaml文件中定义了一个排序Org( OrderOrgs)和两个PeerOrg(PeerOrgs),其中每个PeerOrg定义了两个节点(count=2)以及1个一般用户(非Admin).每个Org下面都有ca\msp\tlsca\users四个目录,如果是OrderOrg,则会另外有orderers目录,列出所有order节点信息, 如果是PeerOrg,则会另外有peers目录, 列出所有peer节点信息. ( 各个目录内部配置文件信息后续专题介绍)
replacePrivateKey: 将generateCerts过程中生成的私钥替换到docker-compose-e2e.yaml文件中.
generateChannelArtifacts: 将生成4个文件: orderer 的启动区块 (bootstrap block), 也即创世区块: genesis.block文件;channel配置交易文件 channel.tx; 2个锚节点交易文件 (Org1MSPanchors.tx, Org2MSPanchors.tx).
至此,各种初始化文件已经创建成功了. 在自己搭建BaaS时,将根据不同的输入条件,改变初始的配置.
2.启动docker-compose容器
如上述, 这个过程其实就是执行
IMAGE_TAG=latest docker-compose -f docker-compose-cli.yaml up -d 2>&1
命令了. 我们大概看下docker-compose-cli.yaml文件的内容:
IMAGE_TAG=latest docker-compose -f docker-compose-cli.yaml up -d 2>&1
命令了. 我们大概看下docker-compose-cli.yaml文件的内容:
从顶层结构上看, 这个compose中共定义了6个service, 分别是orderer节点\org1的peer0节点\org1的peer1节点\org2的peer0节点\org2的peer1节点, 以及cli节点.
展开具体定义可以看到, 前面5个service的具体定义是在文件base/docker-compose-base.yaml文件中定义的,cli服务则是在本文件内部定义的.
我们打开base/docker-compose-base.yaml文件,看下orderer服务的定义:
可以看到,这块代码分别定义了容器名称\镜像名称\环境变量\工作目录\启动命令\挂载目录\导出端口 等信息,需要关注两个地方,一是启动命令 command, 二是挂载卷 volumes.
在启动命令command中,定义了值是orderer,翻到下面下面,可以看到peer服务的定义里面,启动命令command的值是peer.可见这两个命令是fabric重要的入口命令,在看fabric的时候,这两个package是定义了main方法的,可以从main方法入手,跟踪分析程序的启动过程(在go语言中,只有定义了main方法的包才可以启动执行.你可以想到,前面提到的cryptogen工具,也是在源码包中定义了main方法的).回头看docker-compose-cli.yaml文件,可以看到cli中的 command指定的是 /bin/bash,因为cli不需要初始执行其他命令,只是提供shell出来,在后续过程中将使用docker exec 进入执行其他的命令.
再来看挂载卷volumes的定义,可以看到每行都定义了一个指定的目录/文件,其中:前面的是宿主机中的目录,:后面的是容器里面的目录.我们前面步骤中创建的配置和初始化文件,都会映射到容器目录中,供容器运行时使用.
总结一下,docker compose执行时,编排启动了6个容器,包括:一个orderer,一个cli,2个org的各自2个peer.各个容器镜像中提供了程序执行需要的环境及程序代码,而程序需要的参数\配置文件\初始化文件等则是上一步在容器之外生成的.
3.在cli容器中执行测试脚本
测试脚本为什么需要中cli容器中执行呢?在宿主机上面执行可不可以呢? 当然可以.但是,前面已经提到,容器镜像的目的就是提供程序执行需要的环境及程序代码,如果我们在自己宿主机中执行的话,需要非常繁琐的环境配置过程,而使用容器的话,则可以跳过这些细节,而且环境的清理也方便.所以,还是使用容器吧.
前面讲过,这一步骤是中cli容器中执行了scirpt/script.sh脚本.我们大概看一下这个脚本的内容.
这里就是执行了一系列的函数来验证网络的完整功能了,包括创建channel / 加入 channel 以及模拟交易等等.我们以创建channel为例,看看它是怎么实现的.
没错,又是对peer的调用.这里调用了peer channel create子命令来完成对通道的创建.而配置参数,当然就是使用之前生成的配置文件了.
总结:
byfn演示了一个基于 solo 排序模式的网络,并测试了创建通道以及执行交易的整个过程.
1.生成配置及初始化文件
2.将1生成的配置及初始化文件映射到容器目录中,启动容器
3.在cli容器中根据peer子命令执行相关交易.
通过对上述过程的了解,我们很容易想到,封装一个BaaS(Blockchain as a Service)的大概方法了:
首先需要自己实现一套UI,在UI中:
1. 根据用户输入条件,调用cryptogen等命令,生成需要的配置及初始化文件
2.在docker环境中,启动一系列容器
3.封装对cli容器中执行 peer命令的一系列方法,对外提供接口,就可以在UI中使用了
这里需要注意的地方就是,docker环境多集群部署方案 ( docker compose, k8s) ,UI管理.好在Hyperledger官方已经提供了两个独立的项目在做这样的事情,它们就是 Hyperledger cello (
https://github.com/hyperledger/cello
) 项目和Hyperledger explore(
https://github.com/hyperledger/blockchain-explorer
)项目.在你自己准备实现之前,建议先参考一些官方的实现.
https://github.com/hyperledger/cello
) 项目和Hyperledger explore(
https://github.com/hyperledger/blockchain-explorer
)项目.在你自己准备实现之前,建议先参考一些官方的实现.
==更多原创内容分享,请扫码关注公众号: 超级账本开发 ==