在文章的开篇,首先对如下两篇文章的博主表示感谢,感谢他们对学习资源的共享。

https://www.yezhem.com/index.php/archives/52/

https://blog.csdn.net/zgdl1789/article/details/108061503

本文得益于上述两篇文章,同时再结合自己的实际搭建、配置心得,详细的描述将pbft共识算法添加至fabric1.4的步骤,为后来人提供学习参考。

一、前言

众所周知,pbft共识算法的实现仅存在于hyperledger fabric v0.6的版本中。在v0.6之后的版本,如fabric v2.x 采用的是kafka、solo、raft共识算法。从官方文档来看,bft类共识算法的开发仍在进行中,截至到本文的发布日期,fabric还不支持bft类共识算法。

那么是否可以将自行开发的pbft共识算法加入到fabric v1.x的版本中?

答案是肯定的,即使它可能存在着些许不足。

二、PBFT 共识算法在 Fabric v1.4.4中的实现

1、工具包的下载

链接:https://pan.baidu.com/s/1hshTuQXyFlZA0xeiFF-fwQ

提取码:8888

工具包中的文件展示:

2、Go的安装

具体安装过程可参考我之前写的文章:go的安装

(1)go包的解压

本人为了方便,直接将上述压缩包解压至HOME路径下,如下图所示:

找到go包,并将路径切到go包所在的位置(用cd命令即可,在此不再展示):

在go包所在的路径下(我的是:/home/jianyuzhi/fabric1.4.4-pbft/已解压)执行下述安装命令,将go包解压至/usr/local目录下:

$ sudo tar -zxvf go1.15.linux-amd64.tar.gz -C /usr/local

go包解压后的展示:

(2)创建工作目录(可自行选定):

$ mkdir -p /home/jianyuzhi/gopath/src/github.com/hyperledger

(3)环境变量的配置(说明一下,如下展示的环境变量配置方法和我之前文章中用到的环境变量配置方法的作用是一样的)

$ gedit ~/.bashrc 

在文件末端添加如下内容:

export PATH=$PATH:/usr/local/go/binexport GOPATH=$HOME/gopathexport GOROOT=/usr/local/go

更新,使配置的环境变量生效:

$ source ~/.bashrc

(4)安装结果的查看

配置信息展示:

$ go env

输出:

安装版本展示:

$ go version

输出:

(5)赋予权限

$ cd /usr/local$ sudo chmod -R 777 go

(6)go 包的安装

注意:这一部分很重要,后续二进制文件的编译能否成功,很大部分取决于它

文件夹的创建:

$ mkdir -p $GOPATH/src/golang/x

包的下载:

这一步由于国内网络的原因可能会失败,因此先进行代理的修改:

$ go env -w GO111MODULE=on$ go env -w GOPRIVATE=*.corp.example.com$ go env -w GOPROXY=https://goproxy.cn,direct

开始下载:

$ cd $gopath/src/github.com/golang/x$ git clone https://github.com/golang/tools.git

等tools下载完成后,运行如下命令来安装fabric运行可能用到的go工具:

$ go get golang/x/tools/go/packages

如果上述命令运行失败,可尝试把代理关了(至于为啥我也不清楚,关了之后就能正常下了,自己多试试)

$ go env -w GO111MODULE=off$ go get golang/x/tools/go/packages

继续下go get(可能不会全部下载成功,多试试。我当时也没全部下载下来,但后续的话仍能正常运行):

$ export GO111MODULE=on$ go mod init$ go get github.com/golang/sys$ go get golang/x/grpc-go$ go get github.com/golang/zap$ go get net$ go get sync$ go get github.com/golang/atomic$ go get github.com/golang/lint$ go get github.com/golang/text$ go get github.com/golang/genprot$ go get github.com/golang/tools$ go get github.com/golang/multierr$ go get crypto$ go get github.com/golang/pierrec/lz

上述命令完事后,gopath目录下会多出两个文件夹:bin、pkg:

详细的目录结构展示(目前仅关注bin、pkg的子目录):

3、node、npm、npx的安装

在node压缩包所在的路径下,进行解压、链接等操作。参照我之前的文章:node、npm、npx的安装

此处不再赘述

4、docker、docker-compose、containerd.io的安装

(1) 根据工具包中的压缩包进行安装,详细参考我之前的文章即可:docker、docker-compose、containerd.io指定版本的安装

版本的指定如下:

$ sudo apt-get install docker-ce=5:19.03.5~3-0~ubuntu-xenial docker-ce-cli=5:19.03.5~3-0~ubuntu-xenial containerd.io=1.2.5-1

(2)安装完毕后,检查下版本是否和工具包中标注的版本一致。

(3)创建docker组

$ groupadd docker

(4)将当前用户添加到docker组

$ usermod -aG docker jianyuzhi

上述命令的执行,可能会输出,当前用户已存在(大概是这么个意思),不用管它即可,继续接下来的操作

(5)添加国内都docker镜像

$ sudo mkdir -p /etc/docker$ gedit /etc/docker/daemon.json

将下述内容添加至daemon.json文件中

{“registry-mirrors”: [“https://obou6wyb.mirror.aliyuncs.com”]}

(6)命令运行

$ systemctl daemon-reload$ systemctl restart docker

(7) 权限的赋予

$ sudo chmod -R 777 /var/run/docker.sock

5、fabric、fabric-samples源码的下载

在$gopath/src/hyperledger路径下进行相关操作:

$ cd $gopath/src/hyperledger

fabric源码的下载:

$ git clone https://github.com/hyperledger/fabric.git

fabric-samples源码的下载:

$ git clone https://github.com/hyperledger/fabric-samples.git

下载完成后,$gopath/src/hyperledger路径下会有fabric和fabric-samples这两个文件夹。分别进入到这两个文件夹下,将源码的版本切换至 v1.4.4版本。如何进行版本的切换,此处不再展示,可参考:https://blog.csdn.net/jianyuzhi/article/details/122276645。

6、pbft共识算法的添加

pbft共识算法包含在工具包里,就不需要再进行下载了,直接将pbft文件夹复制到/fabric/orderer/consensus文件夹下即可

7、二进制文件的制作(注意,制作出的二进制文件还不包含pbft部分,后面需要对一些配置文件进行修改后,再重新制作部分二进制文件)

$ cd fabric$ make release

制作的二进制文件会输出至fabric/release/linux-am64/bin中

8、镜像文件的下载

$ cd fabric/scripts$ sudo ./bootstrap.sh 1.4.4 -b -s

镜像下载完成后的展示:

9、配置文件的获取和文件夹的移动(是否一定要移动文件夹,暂时我还为论证,按照前辈的步骤来的,后续再部署时我会试一下,到时再来更新)

(1)将fabric路径下的sampleconfig中的三个配置文件复制到fabric-samples路径下的/config文件夹中(没有就自己创建)

(2)将fabric/release/linux-am64/bin中制作的二进制文件复制到fabric-samples路径下的/bin文件夹中(没有就自行创建)

(3)将fabric-samples文件夹移动至fabric文件夹下

(4)添加全局变量

$ gedit ~/.bashrc

将以下内容添加进去(或者在原来的基础上改为如下内容):

export PATH=$PATH:/usr/local/go/bin:$HOME/gopath/src/github.com/hyperledger/fabric/fabric-samples/bin

更新配置,使其生效:

$ source ~/.bashrc

10、配置/修改相关文件,以便支持pbft共识算法

(1)修改fabric/common/tools/configtxgen/localconfig/config.go

在config.go文件的第388行添加:

case "pbft":

添加完后的展示:

(2)修改fabric/common/tools/configtxgen/encoder/encoder.go

在encoder.go文件的第38行,添加:

ConsensusTypePbft = "pbft"

添加完后的展示:

在encodr.go文件的第215行,添加:

case ConsensusTypePbft:

添加完后的展示:

(3)修改fabric/orderer/common/server/main.go文件

在main.go文件的头部添加:

“github.com/hyperledger/fabric/orderer/consensus/pbft”

添加完后的展示:

在main.go文件的第650行添加:

consenters["pbft"] = pbft.New()

添加完成后的展示:

到此,文件的配置就差不多了,现在对上述的一些操作做下说明:

文章所述的行数,并不是唯一的(我的和前辈写的就有些偏差,导致我在此浪费了许多时间),大多数情况下是一致的。可以根据展示图进行二次校准,千万别添加错了位置。

11、部分二进制文件的制作

上文已经制作过了二进制文件,但那时的源码并不含有pbft共识算法。因此,在后续的对相关的配置文件进行修改后,要想使其生效,需要重新制作二进制文件。

不难看出,修改的位置仅涉及到:orderer、configtxgen部分,因此仅重新制作这两个二进制文件即可:

在fabric文件夹下执行:

$ make orderer-docker$ make configtxgen

重新制作的二进制文件会输出至:hyperledger/fabric/.build/docker/bin和hyperledger/fabric/.build/bin路径下。然后用重新制作的两个二进制文件替换掉之前制作的:

$ cp $gopath/src/github.com/hyperledger/fabric/.build/docker/bin/orderer $gopath/src/github.com/hyperledger/fabric/fabric-samples/bin

$ cp $gopath/src/github.com/hyperledger/fabric/.build/bin/configtxgen $gopath/src/github.com/hyperledger/fabric/fabric-samples/bin

通过复制,然后覆盖掉之前的二进制文件即可。

或者不通过复制命令,手动删除掉原来的二进制文件,然后添加新的二进制文件。这一步随意操作,效果是一样的。

12、添加pbft-network文件,并修改

(1)pbft-network文件包含在工具包,找到它,将其复制到fabric文件夹下

(2)修改pbft-network/base/peer-base.yaml文件的第4和17行,将 $IMAGETAG 删除。删除后的展示:

(3)修改pbft-network/docker-compose-cli.yaml文件的第59行,删除$IMAGETAG ,删除后的展示:

13、fabric的运行(运行的是pbft共识算法哦)

切入到pbft-network目录下,并创建文件夹:

$ cd fabric/pbft-network$ mkdir channel-artifacts

网络配置文件的生成:

$ cryptogen generate --config ./crypto-config.yaml

channel与创世区块的生成:

$ configtxgen --profile Genesis -outputBlock ./channel-artifacts/genesis.block$ configtxgen --profile Channel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel

运行完上述命令后,文件夹的展示:

运行镜像:

$ docker-compose -f docker-compose-cli.yaml up -d

输出:

运行镜像的查看:

$ docker ps -a

输出:

镜像的停止:

$ docker-compose -f docker-compose-cli.yaml down

输出:

Ok! 竣工

接下来,我将尝试通过caliper对本文所运行的fabric网络进行压测,可关注我的后续文章