前言

本篇主要参考官方技术文档,介绍了如何测试网络的准备工作、使用脚本搭建测试网络的细节。


一、准备测试网络

1.1. 概述

Fabric官方提供了一个基础示例项目fabric-samples,项目仓库为hyperledger/fabric-samples。该项目可以部署一个测试网络,专用于引导用户学习Fabric区块链网络的基本特性和操作。

部署这个测试网络需要预先准备三个组件:

  • 示例,即fabric-samples仓库。

注1:包括示例链码等,正常开发不需要这部分内容。

  • 平台特定的Hyperledger Fabric CLI工具二进制可执行文件和配置文件(platform-specific Hyperledger Fabric CLI tool binaries and config files)。

注2:所谓二进制可执行文件,可以理解成一个工具。

  • Fabric Docker镜像。

注3:Fabric的节点可以以Docker容器的形式运行。而镜像(Image)和容器(Container)的关系就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。因此需要先获取所需的镜像。

官方提供了两个脚本bootstrap.sh和install-fabric.sh用于获取上述内容。两个脚本的源代码都位于GitHub上的hyperledger/fabric项目的scripts文件夹中,使用方法和运行效果也相同,但是install-fabric.sh脚本的语法较bootstrap.sh脚本有所改进。具体来讲,脚本的作用如下:

  1. 从GitHub克隆hyperledger/fabric-samples项目仓库到脚本所在目录。
  2. 从GitHub下载指定版本且平台特定的Hyperledger Fabric CLI工具二进制可执行文件和配置文件分别放到本地fabric-samples仓库的根目录下的/bin和/config目录中。
  3. 从Docker Hub上下载指定版本的Hyperledger Fabric Docker镜像文件到本地Docker注册表中,并将下载的镜像文件标记为"latest"。

1.2. 完成准备工作

为了方便后期管理,在当前登录用户的HOME目录下创建一个空目录并进入该目录:

mkdir hyfa && cd hyfa

1.2.1. 方法一:运行install-fabric.sh脚本

从Gitee克隆fabric项目仓库:

git clone https://gitee.com/hyperledger/fabric.git

将install-fabric.sh脚本文件拷贝到当前目录下:

cp ./fabric/scripts/install-fabric.sh ./

执行install-fabric.sh:

./install-fabric.sh

注1:不建议在执行该脚本时使用root权限,即,不要执行sudo ./install-fabric.sh

注2:下载可能需要几分钟,也可能需要十几分钟,取决于当前的网络环境。如果下载太慢,可以换其它方法。

注3:如果需要安装特定版本或者特定组件,可以输入./install-fabric.sh -h命令查看脚本可用的参数。

如果执行install-fabric.sh脚本时使用了root权限,脚本运行后,在GUI中会发现fabric-samples文件夹是带锁的,无法移动文件到该文件夹。同时fabric-samples文件夹以及其中的全部文件的属主都是root,当前用户在运行文件夹中的脚本时会因为权限不够而报错。

如果使用chmod指令解锁文件夹,虽然可以去锁,但是会使里面的全部文件夹带锁;如果递归解锁,则文件在终端中都会绿色高亮(因为所有用户都有读/写/执行的权限,Linux系统默认认为这些文件是高风险文件),如此一来不美观。另外这也没有解决运行脚本时可能的权限不足问题。

最好的解决方法是把fabric-samples文件夹的属主更改为当前用户:

sudo chown -R $USER fabric-samples

默认情况下,运行install-fabric.sh的结果如下:

  1. 克隆hyperledger/fabric-samples到当前目录。

在这里插入图片描述

  1. 拉取Hyperledger Fabric二进制文件:实际上是下载了hyperledger-fabric-linux-amd64-x.x.x.tar.gz和hyperledger-fabric-ca-linux-amd64-x.x.x.tar.gz这两个压缩文件,然后解压到指定目录,然后删除压缩文件。

在这里插入图片描述

  1. 拉取Hyperledger Fabric Docker镜像文件:具体来讲是拉取fabric-peer、fabric-orderer、fabric-ccenv、fabric-baseos和fabric-ca这5个镜像文件。

在这里插入图片描述

1.2.2. 方法二:手动安装

参考install-fabric.sh脚本的源代码,也可以手动实现脚本完成的工作。

  1. 克隆fabric-samples仓库:
git clone https://gitee.com/hyperledger/fabric-samples.git && cd fabric-samples
  1. 下载压缩文件并解压:

分别从https://github.com/hyperledger/fabric/releases以及https://github.com/hyperledger/fabric-ca/releases下载对应版本的发行版压缩文件。如果下载速度太慢,在浏览器中搜索“Github文件加速”,使用任意加速网站(例如:https://github.akams.cn/)加速下载。

将压缩文件复制到虚机的fabric-samples文件夹下,使用tar解压:

tar -zxvf hyperledger-fabric-linux-amd64-2.5.10.tar.gz
tar -zxvf hyperledger-fabric-ca-linux-amd64-1.5.12.tar.gz

赋予全部二进制文件可执行权限:

chmod +x ./bin/*
  1. 使用docker pull命令从Docker Hub拉取指定的Docker镜像文件并将已下载的镜像标记为最新:
docker pull hyperledger/fabric-peer:2.5.10 && docker tag hyperledger/fabric-peer:2.5.10 hyperledger/fabric-peer
docker pull hyperledger/fabric-orderer:2.5.10 && && docker tag hyperledger/fabric-orderer:2.5.10 hyperledger/fabric-orderer
docker pull hyperledger/fabric-ccenv:2.5.10 && docker tag hyperledger/fabric-ccenv:2.5.10 hyperledger/fabric-ccenv
docker pull hyperledger/fabric-baseos:2.5.10 && docker tag hyperledger/fabric-baseos:2.5.10 hyperledger/fabric-baseos
docker pull hyperledger/fabric-ca:1.5.12 && docker tag hyperledger/fabric-ca:1.5.12 hyperledger/fabric-ca

注1:替换国内镜像源后,可能出现较新版本的Fabric镜像获取不到的情况,可以试着拉取旧版本的镜像,以确认是镜像源自身的问题还是网络问题。
注2:如果已经设置了国内镜像源,但是docker pull时仍然出现错误,且替换其它常见国内镜像源同样无法解决。可以搜索关键词“Docker镜像源”,替换可访问的镜像源,或者翻墙。

1.2.3. 方法三:本地编译

完成准备工作最容易遇到的困难是获取二进制可执行文件和镜像文件时的网络问题,最后的解决方案是通过本地编译的方式使用Make工具编译Fabric和Fabric-CA源码以生成二进制可执行文件和镜像文件。

  1. 克隆fabric、fabric-ca和fabric-samples仓库:
git clone https://gitee.com/hyperledger/fabric.git
git clone https://gitee.com/hyperledger/fabric-ca.git
git clone https://gitee.com/hyperledger/fabric-samples.git
  1. 编译Fabric的二进制可执行文件:

可以从Fabric源码编译的二进制可执行文件有8个:configtxgen、configtxlator、cryptogen、discover、ledgerutil、orderer、osnadmin、peer。

在源码根目录编译全部二进制可执行文件:

make all

除discover工具外,其它7个二进制可执行文件都可以单独进行编译,详见Makefile的帮助说明。

  1. 编译Fabric的镜像文件:

可以从Fabric源码编译的镜像有5个:baseos、ccenv、orderer、peer、tools,它们的Dockerfile在images目录下对应的子目录中。

在源码根目录编译全部镜像文件:

make docker

编译镜像文件peer时提示如下错误:go: github.com/onsi/gomega@v1.17.0: Get https://proxy.golang.org/github.com/onsi/gomega/@v/v1.17.0.mod: dial tcp 142.251.211.241:443: connect: connection refused
在这里插入图片描述
原因是依赖项gomega无法下载下来。该依赖项的需求在文件/ccaas_builder/go.mod中。尽管设置了go代理,下载时仍然会访问国外的IP(142.251.211.241),在ccaas_builder文件夹下运行go mod tidy命令提前下载好该依赖项也无效。解决方案是在Dockerfile的RUN make指令前手动添加代理:
sudo vim ./images/peer/Dockerfile
ARG GOPROXY=https://goproxy.cn
ENV GOPROXY=$GOPROXY

编译镜像文件tools时提示如下错误:gzip: stdin: unexpected end of file
原因是文件末尾存在零字节,解决方案是在解压缩时使用–ignore-zeros选项来忽略文件末尾的零字节。
打开tools的Dockerfile:
sudo vim ./images/tools/Dockerfile
将“ tar zxvf - -C /usr/local”改为“tar zxvf - -C /usr/local --ignore-zeros”。

  1. 编译Fabric CA的二进制可执行文件和镜像文件:

可以从Fabric CA源码编译的二进制可执行文件有2个:fabric-ca-server、fabric-ca-client;镜像有1个:fabric-ca。编译方法同Fabric源码。

  1. 复制二进制可执行文件到指定目录下

最后还应当与前述方法保持一致,在fabric-samples下新建的bin文件夹和config文件夹,将全部二进制可执行文件复制到bin文件夹中,并补齐config文件夹下所需的配置文件。

1.3. 添加环境变量(可选)

后续使用fabric-samples/bin文件夹中的二进制文件时,需要将其所在目录添加到PATH环境变量中,这样做的意义是为在系统中任何路径下使用Fabric相关命令时都可以让系统找到该命令并且顺利执行。但是,对于虚拟机,每次重启时都需要重新添加一次环境变量,因此可以将其写入.bashrc文件中。

打开当前登录用户的.bashrc文件:

vim ~/.bashrc

在.bashrc文件的最后添加如下内容:

export PATH=$PATH:$HOME/hyfa/fabric-samples/bin

使用source命令使之生效:

source ~/.bashrc

此外,也可以直接将这些二进制文件复制到 /usr/local/bin/ 中做为全局命令。

1.4. 二进制文件说明

1.2.1节中,拉取二进制文件其实是下载并解压了两个.tar.gz格式的压缩文件。

.tar.gz是一种文件格式,它由两部分组成:

  • .tar(Tape Archive):tar是一个用于打包文件的程序,它可以将多个文件和目录合并成一个单一的文件,通常称为归档文件。这样做的目的是为了便于文件的传输和存储。
  • .gz(Gzip):gzip 是一个压缩文件的程序。.gz 扩展名表示文件已经被gzip 程序压缩。

.tar.gz文件格式表示这是一个先被tar程序打包,然后被gzip程序压缩的文件。这种格式可以有效地减少文件大小,同时保持文件的组织结构。

该格式的压缩文件在Windows系统中用压缩软件打开,可以看到都有哪些内容。

hyperledger-fabric-ca-linux-amd64-x.x.x.tar.gz解压后是bin文件夹下的fabric-ca-client和fabric-ca-server这两个二进制文件。

hyperledger-fabric-linux-amd64-x.x.x.tar.gz解压后则是config文件夹下的配置文件、bin文件夹下的peer等8个二进制文件以及builders文件夹下的其它文件。

在这里插入图片描述

查看GitHub上的fabric-samples仓库,可以发现没有这两个目录及其中的内容,证明这是额外实现的。


二、使用测试网络

2.1. 概述

Fabric官方提供了提供了一个脚本network.sh用于启动测试网络。进入测试网络的目录,可以找到该脚本:

cd ~/hyfa/fabric-samples/test-network

2.2. 基本用法

2.2.1. 启动网络

启动一个默认名称为“fabric_test”的网络:

./network.sh up

启动网络后使用docker ps -a命令查看容器。

2.2.2. 创建通道

创建一个默认名称为“mychannel”的通道:

./network.sh createChannel

2.2.3. 在通道部署链码

部署Go版本的asset-transfer-basic链码:

./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

链码部署后可以再次查看容器,将会看到多出了两个实例。

可选的,asset-transfer-basic链码也支持Java、JavaScript和TypeScript版本。
部署Java版本的asset-transfer-basic链码:
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-java -ccl java

部署JS版本的asset-transfer-basic链码:
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-javascript/ -ccl javascript

部署TS版本的asset-transfer-basic链码:
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-typescript/ -ccl typescript

2.2.4. 关停网络

./network.sh down

该命令将停止并删除节点和链码容器,删除组织加密材料,并从Docker Registry移除链码镜像。该命令还删除之前运行的通道项目和docker卷。

注:如果未正常关停网络,下次启动测试网络时,应先执行该命令。

2.3. 报错

2.3.1. 跟文件权限相关的报错

错误描述:mkdir organizations/peerOrganizations: permission denied

在这里插入图片描述

报错原因:当前用户对fabric-samples文件夹的权限不够。

解决方法:更改fabric-samples文件夹的权限(见1.2.2节);或者在运行脚本前先获得root shell权限(sudo bash)。

2.3.2. 跟Docker相关的报错

错误1

错误描述:Got permission denied while trying to connect to the Docker daemon socket

在这里插入图片描述

报错原因:docker守护进程启动的时候,会默认赋予名字为docker的用户组读写Unix socket的权限,如果在安装docker时没有将当前用户添加到docker组,则会出现上述问题。

解决方法:创建docker用户组,并将当前用户加入到docker用户组中,那么当前用户就有权限访问Unix socket,进而也就可以执行docker相关命令。

sudo groupadd docker
sudo gpasswd -a $USER docker
newgrp docker
错误2

错误描述:Version in “./compose/compose-test-net.yaml” is unsupported

在这里插入图片描述

报错原因:docker-compose在使用.yaml文件时,文件里的版本号与docker和docker-compose的版本有要求,则需要更新的版本。

解决方法:更新docker和docker-compose,或者修改.yaml文件里的版本号。

错误3

错误描述:UnixHTTPConnectionPool(host=‘localhost’, port=None): Read timed out. (read timeout=60)

在这里插入图片描述

报错原因:docker-compose启动容器花费的时间超过默认设定的60S,见于性能特别差劲的系统。

解决方法:修改超时默认设置。

vim /etc/profile
export DOCKER_CLIENT_TIMEOUT=500
export COMPOSE_HTTP_TIMEOUT=500
source /etc/profile

2.3.3. 创建通道时的报错

错误描述:cannot create ledger from genesis block: ledger [mychannel] already exists with state [ACTIVE]

在这里插入图片描述

报错原因:Docker网络“fabric_test”中任然有活跃的容器节点。

解决方法:停止并删除全部容器后再执行一次关停网络的命令。

docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
./network down

2.3.4. 部署Go链码时的报错

错误1

错误描述:go: 未找到命令

在这里插入图片描述

报错原因:没有正确配置配置Golang环境。

解决方法:正确配置Golang。

错误2

错误描述:Error: failed to normalize chaincode path: ‘go list‘ failed …

在这里插入图片描述

报错原因:下载依赖的连接被拒绝。

解决方法:更换Golang代理。

错误4

错误描述:Error: chaincode install failed with status: 500 - error in simulation: failed to execute transaction …: error sending: timeout expired while executing transaction

在这里插入图片描述

进一步查看Peer节点容器的日志,没有报错,但是可以看到grpc.call_duration较大。

在这里插入图片描述

报错原因:单纯的链码执行超时。如下图所示,一次正常的go链码部署,grpc.call_duration在几十秒左右。

在这里插入图片描述

解决方法:重新部署,如果仍超时,考虑增加虚拟机的内存大小和核数。

2.3.5. 部署Java链码时的报错

错误1

错误描述:Downloading from https:// services.gradle.org/distributions/gradle-x.x.x-bin.zip failed: timeout

在这里插入图片描述

报错原因:首次编译Java版本的basic链码时需要下载链码项目指定的gradle压缩包。通常是网络问题导致超时。

解决方案1:多次运行直到成功即可。

解决方案2:打开项目的gradle-wrapper.properties文件,修改distributionUrl字段,将下载地址从https://services.gradle.org/distributions/改为https://mirrors.cloud.tencent.com/gradle/。

错误2

错误描述:Faild to pull hyperledger-javaenv

在这里插入图片描述

报错原因:测试网络的Peer节点首次安装Java版本的basic链码时需要用到名为fabric-javaenv的镜像文件,该镜像在安装测试环境时默认不会安装,因此在第一次部署任何Java版本的链码时会下载该镜像。通常是网络问题导致超时。

解决方案:多次运行直到成功即可。

错误3

错误描述:Could not set file mode 755 on ‘…/fabric-samples/asset-transfer-basic/chaincode-java/build/install/basic/lib’.

在这里插入图片描述

报错原因:前一次部署Java版本的链码时,使用了root权限,导致build文件夹的属主为root。本次使用Java版本的链码时,没有先删除build文件夹且没有使用root权限,因而导致报错。

解决方法:删除build文件夹再运行。

错误4

错误描述:extension (5) should not be presented in certificate-request

链码部署成功,但是链码容器随即退出,查看容器日志如下。

在这里插入图片描述

报错原因:JDK11特定版本的TLS BUG。在Ubuntu18中安装的OpenJDK11遇到有该问题,而在Ubuntu20中安装的OpenJDK11不会。

解决方法:升级JDK11的版本(换句话说,将Ubuntu18系统升级为Ubuntu20,再使用apt命令安装一遍OpenJDK11)。

2.3.6. 部署JS/TS链码时的报错

错误描述:error sending: timeout expired while executing transaction

在这里插入图片描述

报错原因:首次运行JS/TS版本的basic链码时需要从镜像源下载链码项目指定的依赖包。通常是网络问题导致超时。

解决方案:切换镜像源,同时将链码项目中的node_modules文件夹以及package-lock.json文件删除,重新部署。

2.4. 脚本使用语法

network.sh脚本的语法是:network.sh <mode> [flag]

其中,<…>代表必选项,[…]代表可选项。

对于V2.5版本,mode有7种,说明如下。

  • prereq:安装二进制文件和镜像。
  • up:启动Fabric网络,但是不创建通道。
  • createChannel:在网络启动后创建一个通道。
  • up createChannel:启动Fabric网络并创建通道。
  • deployCC:部署链码到通道。
  • cc:链码功能。
  • down:关闭Fabric网络。

flag根据mode的选择有不同,并且可以多选。

2.4.1. prereq方法

当mode为prereq时,flags的说明如下。

  • i:Fabric版本。
  • cai:Fabric CA版本。

2.4.2. up或createChannel方法

当mode为up或createChannel时,flags的说明如下。

  • -ca:使用CA生成网络加密材料。
  • -cfssl:使用CFSSL生成网络加密材料。
  • -bft:为排序服务使用BFT类型的共识(V2.5之前的版本不支持)。
  • -c:定义要创建的通道的名称(默认为“mychannel”)。
  • -s:选择Peer节点的状态数据库的类型,LevelDB(默认)或CouchDB。
  • -r:客户端最大重试请求次数(默认为5次)。
  • -d:客户端最大请求时延(默认为3秒)。
  • -verbose:Verbose模式,用于输出详细的日志信息。

注:在Verbose模式下,脚本会在特定的地方使用env命令和grep命令在终端中列出相关的环境变量及其赋值,可以参见test-netork/scripts目录下的envVar.sh脚本。

常见示例:

./network.sh up createChannel
./network.sh up createChannel -s couchdb

2.4.3. deployCC方法

当mode为deployCC时,flags的部分说明如下。

  • -c:部署链码的通道名。
  • -ccn:链码名。
  • -ccp:链码的文件路径。
  • -ccl:链码的编程语言。
  • -cci:(可选)链码初始化函数的名称。
  • -ccep:(可选)使用签名策略语法的链码背书策略。
  • -cccg:(可选)私有数据集合定义文件的路径。

注1:在部署链码时使用-cci标志主要是为了在新的链码生命周期中支持一些遗留(legacy)的链码。传入参数必须是InitLedger,且只有在链码包含初始化函数InitLedger()时可用(对于V2.5版本的示例,只有basic链码实现了该函数)。
在部署链码时使用该标志,实际上是在下述命令中额外使用了–init-required参数:
peer lifecycle chaincode approveformyorg
peer lifecycle chaincode checkcommitreadiness
peer lifecycle chaincode commit
并在链码部署后立即通过带–isInit参数的peer chaincode invoke命令调用InitLedger()函数。
默认情况下,部署链码后可以任意调用链码中包含的函数,但是如果在链码生命周期中使用了–init-required参数,则必须先调用InitLedger()函数初始化账本,才能调用其它函数。

注2:在部署链码时使用-ccep标志,可以指定新的背书策略,使链码能够覆盖原本会从测试网络的通道配置中继承的默认背书策略。详见入门笔记(七)第一章。

注3:在部署链码时使用-cceg标志,用于实现Fabric的私有数据特性。详见入门笔记(七)第二章。

常见示例:

./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go -cci InitLedger
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go -ccep "OR('Org1MSP.peer','Org2MSP.peer')"

2.4.4. cc方法

当mode为cc时,又有多个子mode,说明如下。

  • list:列出安装到对等体并提交到通道的链码。
  • package:打包链码。
  • invoke:执行invoke操作。
  • query:执行query操作。

子mode的flags部分说明如下。

  • -orgs:执行命令的组织数量。
  • -c:部署链码的通道名。
  • -ccn:链码名。
  • -ccp:链码的文件路径。
  • -ccl:链码的编程语言。

2.5. network.sh脚本代码详解

2.5.1. 脚本启动网络详解

2.5.1.1. 总体说明

如果使用up子命令,network.sh脚本会运行networkUp()函数。

在这里插入图片描述

该函数的作用如下:

  1. 调用checkPrereqs()函数。该函数会进行一些检查,包括二进制文件和配置文件是否存在、二进制文件跟镜像的版本是否匹配,等等。

  2. 调用createOrgs()函数。该函数为Peer节点和排序服务创建所有部署和操作网络所需要的加密材料并调用organisations文件夹中的ccp-generate.sh脚本为Org1和Org2生成CCP文件。

  3. 使用docker-compose启动节点的容器。

2.5.1.2. 加密材料生成方式的可选项
Option 1:使用cryptogen工具

默认情况下,createOrgs()函数使用bin文件夹中的cryptogen工具的generate命令分别为Org1、Org2和Orderer Org创建证书和密钥,所需的配置文件在organizations/cryptogen文件夹中。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Option 2:使用Fabric CA组件

如果在启动网络时使用-ca参数,createOrgs()函数使用docker-compose和配置文件compose/compose-ca.yaml及compose/docker/docker-compose-ca.yaml来启动三个Fabric CA服务器的容器。所需的配置文件则位于organizations/fabric-ca文件夹中。

这些容器使用的镜像为fabric-ca,在启动时会执行命令fabric-ca-server start -b admin:adminpw -d,使用各自的配置文件生成CA证书、秘钥和数据库等内容,并和配置文件存放在一起。

在这里插入图片描述

createOrgs()函数继续调用位于organizations/fabric-ca文件夹的registerEnroll.sh脚本中的函数,使用Fabric CA客户端和刚刚生成的内容为Org1、Org2和Orderer Org创建证书和密钥。

Option 3:使用CFSSL组件

如果在启动网络时使用-cfssl参数,createOrgs()函数调用位于organizations/cfssl文件夹的registerEnroll.sh脚本中的peer_cert()函数和orderer_cert()函数,为Org1、Org2和Orderer Org创建证书和密钥。

在这里插入图片描述

2.5.1.3. 排序服务的可选项
Option 1:使用Raft

默认情况下,docker-compose使用配置文件compose/compose-test-net.yaml以及compose/docker/docker-compose-test-net.yaml启动容器peer0.org1.example.com、peer0.org2.example.com、orderer.example.com及cli。其中,peer0.org1.example.com和peer0.org2.example.com分别是Org1和Org2的peer节点,orderer.example.com是排序节点,cli是测试网络的维护节点。

Option 2:使用BFT

如果在启动网络时使用-bft参数,docker-compose改为使用配置文件compose/compose-bft-test-net.yaml以及compose/docker/docker-compose-bft-test-net.yaml启动容器peer0.org1.example.com、peer0.org2.example.com、orderer.example.com、orderer2.example.com、orderer3.example.com、orderer4.example.com及cli。其中,peer0.org1.example.com和peer0.org2.example.com分别是Org1和Org2的peer节点,orderer.example.com、orderer2.example.com、orderer3.example.com和orderer4.example.com是排序节点,cli是测试网络的维护节点。

2.5.1.4. 数据库的可选项
Option 1:使用LevelDB

默认情况下,LevelDB数据库内嵌在容器peer0.org1.example.com和peer0.org2.example.com。

Option 2:使用CouchDB

如果在启动网络时使用-s couchdb参数,docker-compose还会使用配置文件compose/compose-couch.yaml以及compose/docker/docker-compose-couch.yaml启动容器couchdb0和couchdb1分别作为Org1和Org2的的peer节点的数据库。

2.5.2. 脚本创建通道详解

如果使用createChannel子命令,network.sh脚本会运行createChannel()函数。

该函数的作用如下:

  1. 检查网络是否已成功启动;如果没有,则调用networkUp()函数启动网络。
  2. 调用scripts/createChannel.sh脚本,用于完成创建通道创世区块、创建通道(将排序节点加入通道)、将Peer节点加入通道和为通道中的每个组织设置锚节点的一系列工作。

createChannel.sh脚本首先根据传入的参数选择合适的配置文件并运行creatChannelGenesisBlock()函数,使用configtxgen工具基于配置文件中的配置创建通道创世区块。对于Raft共识,使用配置文件configtx/configtx.yaml;对于BFT共识,使用配置文件bft-config/configtx.yaml。

在这里插入图片描述
在这里插入图片描述

createChannel.sh脚本然后运行createChannel()函数,使用osnadmin工具创建通道。

在这里插入图片描述
在这里插入图片描述

createChannel.sh脚本接着运行joinChannel()函数,使用Peer工具将Peer节点peer0.org1.example.com和peer0.org2.example.com连接到通道。

在这里插入图片描述

createChannel.sh脚本最后运行setAnchorPeer()函数,该函数直接调用scripts文件夹中的setAnchorPeer.sh脚本使这两个Peer节点设为锚节点。

在这里插入图片描述

2.5.3. 脚本部署链码详解

如果使用deployCC子命令,network.sh脚本会运行deployCC()函数。

在这里插入图片描述

该函数直接调用Scripts文件夹下的deployCC.sh脚本部署链码。

deployCC.sh脚本首先会安装链码依赖:

在这里插入图片描述

然后调用packageChaincode()方法,该方法使用peer lifecycle chaincode package命令创建链码包:

在这里插入图片描述

接着调用installChaincode()方法分别在组织1和组织2的peer节点上安装链码包,调用queryInstalled()方法查询安装结果。

接着调用approveForMyOrg()方法为组织1批准链码定义,并调用checkCommitReadiness()方法检查链码定义是否可以提交,期望结果是组织1已经批准而组织2还没有;再一次调用approveForMyOrg()方法为组织2批准链码定义,此时再调用checkCommitReadiness()方法检查链码定义是否可以提交,期望结果变为组织1和组织2都已经批准。

最后调用commitChaincodeDefinition()方法提交链码定义到通道,并调用querCommitted()方法查询提交是否成功。

可选的,可以额外调用chaincodeInvokeInit()方法初始化账本,但这要求链码中实现了InitLedger()方法。

上述这些方法的定义见Scripts文件夹下的ccutils.sh脚本。

在这里插入图片描述

2.6. 脚本运行结果说明

2.6.1. 加密材料

无论使用哪种方式为Peer节点和排序节点创建加密材料均会在organisations文件夹内创建如下两个子文件夹:

ordererOrganizations:保存负责管理排序节点的组织的相关资源。

peerOrganizations:保存负责管理Peer节点的组织的相关资源。

两个子文件夹下会以组织的域名创建文件夹,保存该组织的资源。管理排序节点的组织的域名下包含如下文件夹:

  • ca:保存负责管理排序节点的CA证书和私钥。
  • tlsca:保存排序节点通信时用到的证书和私钥。
  • user:保存排序节点管理员用户的证书和私钥。
  • msp:保存上面各种类型的所有证书和私钥,因为在一些配置文件中存在直接引用MSP文件夹的情况。
  • orderers:保存各个排序节点的CA证书和私钥。

管理Peer节点的组织的域名下类似。

2.6.2. CCP文件

createOrgs()函数还会调用ccp-generate.sh脚本,该脚本使用同目录下的两个模板文件ccp-template.json和ccp-template.yaml,分别为Org1和Org2生成CCP文件,即organisations/peerOrganisations/org1.example.com下的connection-org1.json和connection-org1.yaml,以及organisations/peerOrganisations/org2.example.com下的connection-org2.json和connection-org2.yaml。

注1:这些CCP文件供APP使用,使得APP能够连接到测试网络中的Peer节点。注释掉这一部分内容不会对测试网络的启动、创建通道和部署链码产生影响。

举例来说,可以在项目fabric-samples/asset-transfer-basic/application-java的App.java文件中找到对connection-org1.yaml的使用。

在这里插入图片描述

注2:所有使用Fabric Gateway client API开发的APP(例如fabric-samples/asset-transfer-basic/application-gateway-java项目)都无需这些CCP文件,详见Hyperledger Fabric 入门笔记(九)Fabric V2.4 测试网络基础补充 - 与网络交互


Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐