前言
这一周主要是在把之前看过的文章温习一遍。因为前两个星期,一味地为了赶学习的进度,对很多的知识都知识囫囵吞枣的过了一遍。自己仿佛成了知识的搬运工。痛定思痛之后,这一周主要的学习计划,是将前两周写的 Fabric 的文章好好的温习一下,在这个过程中,再进行整理和思考,于是有了这篇文章。
这篇文章,总的来说,应该是前两周学习的一个总结。主要是在理解了 msp 的基础之上,回过头来看,手把手如何搭建一个 Fabric 网络。在这个过程中,发现了很多的之前忽略的细节。所以说,这篇文章,可以说是《手动搭建一个 Fabric 网络-基于 Docker 容器的方式》 的姊妹篇了,是从新的知识高度,来理解 Fabric 网络的搭建工程。全文将按照如下架构来展开:
一、手动搭建 Fabric 网络的两种方式
在手动搭建 Fabric 网络的过程中,一般有两种方式,一种是基于容器的方式,另一种是在服务器上手动部署。
- 基于容器的方式
在《手动搭建一个 Fabric 网络-基于 Docker 容器的方式》一文中,我们采用的是基于容器的方式。在这种方式中,我们把节点和 Orderer 节点所需要的配置信息,写在配置文件 docker-compose-cli.yaml 中,然后通过 docker-compose 工具,一下子可以初始化我们的 Fabric 网络。这种方式搭建网络比较快速方便,如果已经熟悉了 fabric 的搭建过程,用这种方式是很方便的。
- 手动部署
在服务器上手动部署来初始化 Fabric 网络,对理解 Fabric 网络的底层,特别是对理解 MSP 配置和 Peer 节点等的配置文件来说,是必不可少的一场实践。手动部署 Fabric 网络,除了要生成组织关系和身份证书、生成 Ordering 服务启动初始区块、生成新建应用通道的配置交易、生成锚节点配置更新文件等准备工作之外,我们需要根据 Fabric 源码,手动编译生成 Peer,Orderer 等这些组件。在启动这些组件之前,我们还需要首先检查启动所有 Peer 节点的所有配置是否就绪。关于节点的环境变量的设置,有多种方式进行。直接 Terminal 中设置环境变量,或者将这些配置写入到配置文件中。关于采用源码编译启动 Fabric 网络,将会在后续文章中来介绍。
这种方式虽然比较麻烦,但是对理解 Fabric 的配置管理十分有帮助。
比如:
手动启动 Peer 节点之前,首先要检查启动所有 Peer 节点需要检查如下工作是否准备就绪:
– 在/etc/hyperledger/fabric 路径下放置有对应编写好的 core.yaml – 在/etc/hyperledger/fabric 路径下放置生成的对应 msp 文件目录、tls 文件目录。Peer 节点的默认配置文件中指定了适合调试的 Peer 节点功能。
使用时根据需求可能要对其中一些关键配置进行指定。
二、基础知识
接下来这一部分的内容,主要是基于《手动搭建一个 Fabric 网络-基于 Docker 容器的方式》 的实践中而来。主要是对这一部分出现的内容,以及一些新的知识点,进行介绍和总结。可以说,上一篇文章的基础知识。
关于基本概念
- 锚节点
锚节点是 Channel 中能被所有对等节点探测、并能与之进行通信的一种对等节点。
Channel 中的每个成员都有一个(或多个,以防单点故障)锚节点,允许属于不同成员身份的节点来发现通道中存在的其它节点。
主要是刚启动时候的初始联络元素或与其它结构的沟通元素。如刚加入一个 channel 的节点,需要通过某个锚点节点来快速获取 channel 内的情况(比如获取其它节点的存在信息)。
- 环境变量
在配置 Peer 节点与 Orderer 节点的过程中,有多种方式。比如在配置文件中配置,或者是在命令行中配置。在这些配置的过程中,设计了大量的环境变量的设置。
当从环境变量中读入配置时,需要以 CORE_ 前缀开头。
例如配置文件中的 peer.id 项,对应到环境变量 CORE_PEER_ID。
读取配置的顺序
按照优先级从高到低的顺序依次从命令行参数、环境变量或配置文件中读取配置信息。
这里将常见的环境变量配置功能与说明整理如下:
(1)Orderer 环境变量配置及其功能
Orderer 节点的配置文件在一般在/etc/hyperledger/fabric 路径下放置有编写好的 orderer.yaml 文件中。该文件中涉及了上述的环境变量。
(2)Peer 环境变量配置及其功能
Peer 节点的配置文件在一般在/etc/hyperledger/fabric 路径下放置有对应编写好的 core.yaml 文件中。该文件涉及了上述的环境变量。
- 链码的生命周期
在这里介绍一下以下关于链码的生命周期:
用户可以通过命令行方式操作链码,支持的链码子命令包括 install、instantiate、invoke、query、upgrade、package、signpackage 等。大部分命令(除了 package、signpackage 外)的处理过程都是类似的,创建签名提案消息,发给 Peer 进行背书,获取 ProposalResponse 消息。这些操作管理了链码的整个生命周期:
三、CLI Command 解析
在手动搭建 fabric 网络一文中,我们启动了1Orderer+4Peer+1CLI之后,接下来要做的就是要创建 Channel,并且把节点加入 Channel。这一部分涉及到了一些 peer 通道的操作命令,接下来逐一研究一番。
关于 CLI 些命令的详细用法,可以进入 cli 容器之后,用 peer channel –help 来查询用法。
关于通道
- peer 通道操作命令
关于 peer 通道操作命令,主要有以下这几种 peer channel 命令:
这些命令的详细用法,可以进入 cli 容器之后,使用 peer channel –help 来查询详细的参数。
下面主要介绍在搭建网络过程中出现的两个命令:
(1) peer channel create 创建通道
这一部分,主要包括以下内容:
- peer channel create 含义解释
在实际操作中,我们通过进入 cli 容器,利用如下命令来创建通道
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile $ORDERER_CA
从上面可以知道,该命令后面有很多的参数,那么,这些参数都代表什么含义呢?
创建通道的命令含义如下:
-
- -o orderer.example.com:7050—>指定了 Orderer 的服务定义,用作排序服务。
- -c mychannel —>要创建通道的名字
- -f ./channel-artifacts/channel.tx 指定由 configtxgen 等工具生成的配置交易文件,用于提交给排序节点
- –tls true 与 Orderer 通信是否启动 TLS
- –cafile $ORDERER_CA 指定 Orderer 节点的 TLS 证书,该证书为 PEM 格式。
- 创建 Channel 主流程
1、client 向 peer 发起 channel create –c channelname 请求,其中参数 channelname 为 channel 的名称。
2、Peer 接收到创建请求后,通过 broadcast 接口向 orderer 发送创建 channel 消息。 Orderer 接收请求并创建名为 channelname 的 channel,并将新生成的 channel 的配置信息生成新的 block。
3、peer 收到 channel 创建成功消息后, 通过 deliver 接口获取 orderer 中第 0 块 block,并将该 block 存入本地生成 channelname.block 文件,作为该 channel 的创始块。
(2)peer channel join 加入通道
在创建通道的过程中,在本地生成了一个 channelname.block 文件的,该文件包含排序节点的第 0 个 block,peer 节点加入该通道的时候,需要用到该文件。这一部分,主要包括两个部分:
- peer channel join 命令含义解释
将某个 peer 将入 channel 的命令为:
peer channel join -b mychannel.block
加入通道的命令含义如下:
-
- -b, –blockpath string Path to file containing genesis block。区块路径,指向包含创世区块的文件路径
- 加入 Channel 流程
1、sdk 或 CLI 发起 join channel 请求,收到消息的 peer 执行系统级智能合约(cscc)invoke 方法。
2、根据发起请求自带的 block 参数,创建相应的 chain 信息,包括 chain 对应的 ledger,并将该 block 数据提交到该 ledger 中。
3、peer 将创建好的 chain 信息同步到相同组织其它的 peer 中。
4、peer 将创建好的 chain 信息与 orderer 通信,并建立与 orderer 之间在该 channerl 上的数据传输通道。
5、创建 chain 创建成果通知消息,发送给监听此事件的 peer。
关于链码操作命令
围绕链码的生命周期,主要有如下几种链码操作命令。
其中,链码操作支持的常用命令参数如下表所示:
在手动搭建 fabric 网络中,主要涉及了 peer ChainCode install 与 peerChainCode instance。所以,接下来主要介绍这两个命令。
(1) peer chaincode install 安装链码
安装链码,主要从这两个方面来介绍:
- 命令含义解释
使用 peer chaincode install 命令可以安装指定的 ChainCode 并对其命名。命令如下:
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
安装 ChainCode 的含义如下:
-
- -n mycc 安装的链码的名称
- -v 1.0 指定链码的版本为 1.0
- -p ……/examples/chaincode/go/ –path 的缩写,表示链码的本地路径。
install 命令将链码的源码和环境等内容封装为一个
链码安装打包文件(Chaincode Install Package,CIP),并传输到背书节点。背书节点解析后一般会保存在$CORE_PEER_FILESYSTEMPATH/chaincodes/目录下。
安装链码只需要与 Peer 打交道。
打包文件以 name.version 命名,主要包括如下内容:
ChaincodeDeploymentSpec:链码的源码和一些关联环境,如名称和版本;
链码实例化策略,默认是任意通道上的 MSP 管理员身份均可;
拥有这个链码的实体的证书和签名;
安装时,本地 MSP 管理员的签名。
- 链码安装过程
1、首先构造签名提案消息(SignedProposal)。
2、通过 EndorserClient 经由 gRPC 通道发送给 Peer 的 ProcessProposal 接口。
3、Peer 模拟运行生命周期链码的调用交易进行处理,检查格式、签名和权限等,通过则保存到本地文件系统。
(2) Instantiate ChainCode 实例化链上代码
实例化代码,也将从以下两个方面来介绍:
- 命令含义解释
使用如下命令,对链码进行实例化:
peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
命令的含义如下:
-
- -o orderer.example.com:7050—>指定 Orderer 服务器的地址
- –tls true 启用 TLS 通信
- –cafile $ORDERER_CA Orderj 节点的 TLS 证书,当启动 TLS 通信是有效。
- -C mychannel 所面向的通道为 mychannel
- -v 1.0 实例化的版本为 1.0
- -c ‘{“Args”:[“init”,”a”,”100″,”b”,”200″]}’,–ctor,链码的具体执行参数,Json 格式。表示调用函数 init 且 a 账户初始化为 100,b 账户初始化为 200。
- -P –policy,指定链码所关联的背书策略。
- 链码实例化过程
instantiate 命令通过 构造 生命周期管理系统链码(Lifecycle System Chaincode,LSCC)的交易,将安装过的链码在指定通道上进行实例化调用,在节点上创建容器启动,并执行初始化操作。实例化链码需要同时跟 Peer 和 Orderer 打交道。
1、首先,创建一个 SignedProposal 消息。
2、调用 EndorserClient,发送 gRPC 消息,将签名后的 Proposal 发给指定的 Peer 节点(Endorser),调用 ProcessProposal 方法,进行背书处理。节点会模拟运行 LSCC(生命周期系统链码)的调用交易,启动链码容器。实例化成功后会返回 ProposalResponse 消息(其中包括背书签名)。
3、根据 Peer 返回的 ProposalResponse 消息,创建一个 SignedTX(Envelop 结构的交易,带有签名)。
4、使用 BroadcastClient 将交易消息通过 gRPC 通道发给 Orderer,Orderer 会进行全网排序,并广播给 Peer 进行确认提交。
四、总结
这篇文章,是在学习了 MSP 相关知识之后,重新实践手动搭建 Fabric 的总结。
通过这次实践,体会到了 MSP 在 Fabric 出现的方式,是通过环境变量的配置来起作用的。其次,也了解一些 CLI 命令背后发生的故事。
参考链接&书籍:
- Hyperledger fabric 代码解析 之 channel create & join
- Command-line Interface (CLI)
- 《区块链原理,设计与应用》杨保华-9.4 启动 Fabric 网络
- 《区块链原理,设计与应用》杨保华-9.5 链码的概念与使用