Ubuntu20.04搭建Hyperledger Fabric 2.2.2
基本工具
vim,curl,wget
go语言环境 版本1.16.3
由于apt-get命令安装golang在国内网络环境受限制,推荐手动安装(增加动手能力)。
前往go语言中文网https://studygolang.com/dl
下载
go1.16.3.linux-amd64.tar.gz
进入下载的压缩包文件所在目录
将压缩包解压至/usr/local/ 目录下
$ sudo tar zxvf go1.16.3.linux-amd64.tar.gz -C /usr/local/
进入/usr/local/ 目录,新建workspace文件夹作为Golang的工作目录,也可以取别的名字,后面相关的命令和代码替换workspace就行
$ sudo mkdir workspace
$ sudo chmod -R 777 workspace
修改环境变量
$ sudo vim ~/.bashrc
弹出一个记事本,按a进入插入模式,复制后右键粘贴以下内容至记事本内容最上方
export GOROOT=/usr/local/go #GOROOT是系统上安装Go软件包的位置。
export GOPATH=/home/hadoop/GOPATH #GOPATH是工作目录的位置。
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
然后按enter换行,让内容有序一点,按esc,输入:wq即可保存并退出
使用以下命令应用环境变量的更改命令
$ source ~/.bashrc
查看环境变量是否正确
$ export
输出有以下内容
declare -x GOROOT="/usr/local/go"
declare -x GOPATH="/usr/local/workspace"
验证go是否安装成功
$ go version
输出为
go version go1.16.3 linux/amd64
设置GOPROXY代理
$ go env -w GOPROXY=https://goproxy.cn,direct
设置GOPRIVATE来跳过私有库,比如常用的Gitlab或Gitee,中间使用逗号分隔
$ go env -w GOPRIVATE=.gitlab.com,.gitee.com
设置 GOSUMDB=“sum.golang.google.cn”, 这个是专门为国内提供的sum 验证服务
$ go env -w GOSUMDB="sum.golang.google.cn"
至此Go语言已经安装完成
后续过程中如果出现以下内容不用在意
warning: GOPATH set to GOROOT (/usr/local/go) has no effect
安装docker 版本20.10.6
卸载旧版本docker
docker,docker.io,docker-engine都是docker以往的名字
在安装Docker前先将其他任何已有Docker删除,如果你之前系统中没有装过Docker可以跳过这一步
$ sudo apt-get remove docker docker-engine docker.io containerd runc
apt-get报告没有这些packages属于正常现象
/var/lib/docker/目录下的内容包含镜像(images),容器(containers),volumes,以及networks,
如果你装过docker并且不想保存以往的数据,可以前往
https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine
更新apt
$ sudo apt-get update
允许apt使用基于https的repository
$ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release
添加docker的官方GPG密钥
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
安装stable库
$ echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
安装docker
$ sudo apt-get update
往往最新的docker不一定就能适合你的系统,先查看可以安装的版本
$ apt-cache madison docker-ce
输出几行docker-ce的版本,找到20.10.6的那行,ctrl+shift+v 复制下第二列的内容,也就是版本号,替换下方指令中的<VERSION_STRING>,被替换内容包括两侧尖括号
$ sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
完成后执行hello-world检查否正确安装
$ sudo docker run hello-world
看到hello-world说明ok了
查看docker的版本
$ docker --version
显示v20.10.6
启动docker,这里正常来说已经启动了,确保一下,下面这条指令也很常用
$ sudo systemctl start docker
设置开机启动docker
$ sudo systemctl enable docker
添加自己的账户到docker组,同样自己的用户名替换尖括号部分,以后用docker就不用sudo了
$ sudo usermod -a -G docker <username>
Ubuntu注销,登录打开终端,验证docker是否脱离sudo运行
$ docker run hello-world
此后如果重启虚拟机,可能会出现docker未启用,情况如下
$ docker psCannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?$ systemctl start dockerJob for docker.service failed because the control process exited with error code.See "systemctl status docker.service" and "journalctl -xe" for details.
此时只需执行以下指令
$ cd /etc/docker$ mv daemon.json daemon.conf$ systemctl restart docker$ docker version#验证docker是否开启
安装docker-compose,版本1.27.2
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
更改docker-compose权限
$ sudo chmod +x /usr/local/bin/docker-compose
执行一下docker-compose
$ docker-compose
正常会出使用规则,如果报错则
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
查看docker-compose版本
$ docker-compose --version
显示v1.27.2
建立用于存放fabric-samples的文件夹,递归建立目录
$ mkdir -p ~/go/src/github.com/hyperledger/$ cd ~/go/src/github.com/hyperledger/
拉取Fabric v2.2.2 及 Fabric-ca v1.4.9,可能会中断多试几遍,五秒没反应或者出现2.2.2没法拉取就ctrl+c重来,可以开代理下载,应该稳定一些,不开也行,看网络心情,下载完了记得关闭代理
$ curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.2 1.4.9
下载完成后查看docker镜像
$ docker imageshyperledger/fabric-tools 2.2 212bfff67240 2 months ago 436MBhyperledger/fabric-tools 2.2.2 212bfff67240 2 months ago 436MBhyperledger/fabric-tools latest 212bfff67240 2 months ago 436MBhyperledger/fabric-peer 2.2 0db1edb6ddd8 2 months ago 55MBhyperledger/fabric-peer 2.2.2 0db1edb6ddd8 2 months ago 55MBhyperledger/fabric-peer latest 0db1edb6ddd8 2 months ago 55MBhyperledger/fabric-orderer 2.2 89cac0d3ab9b 2 months ago 38.5MBhyperledger/fabric-orderer 2.2.2 89cac0d3ab9b 2 months ago 38.5MBhyperledger/fabric-orderer latest 89cac0d3ab9b 2 months ago 38.5MBhyperledger/fabric-ccenv 2.2 989d60213726 2 months ago 502MBhyperledger/fabric-ccenv 2.2.2 989d60213726 2 months ago 502MBhyperledger/fabric-ccenv latest 989d60213726 2 months ago 502MBhyperledger/fabric-baseos 2.2 0483f4bff906 2 months ago 6.85MBhyperledger/fabric-baseos 2.2.2 0483f4bff906 2 months ago 6.85MBhyperledger/fabric-baseos latest 0483f4bff906 2 months ago 6.85MBhyperledger/fabric-ca 1.4 dbbc768aec79 6 months ago 158MBhyperledger/fabric-ca 1.4.9 dbbc768aec79 6 months ago 158MBhyperledger/fabric-ca latest dbbc768aec79 6 months ago 158MB
启动测试网络
进入test-network目录
$ cd fabric-samples/test-network
关闭可能在运行的容器
$ ./network.sh down
创建Fabric网络,该网络由两个peer node和一个orderer node组成,但这个指令不会创建channel
$ ./network.sh up
运行成功则输出以下内容
Creating network "net_test" with the default driverCreating volume "net_orderer.example.com" with default driverCreating volume "net_peer0.org1.example.com" with default driverCreating volume "net_peer0.org2.example.com" with default driverCreating peer0.org2.example.com ... doneCreating orderer.example.com ... doneCreating peer0.org1.example.com ... doneCreating cli ... doneCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES1667543b5634 hyperledger/fabric-tools:latest "/bin/bash" 1 second ago Up Less than a second clib6b117c81c7f hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up 1 second 0.0.0.0:7051->7051/tcp peer0.org1.example.com703ead770e05 hyperledger/fabric-orderer:latest "orderer" 2 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp, 0.0.0.0:7053->7053/tcp orderer.example.com718d43f5f312 hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up 1 second 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com
查看容器列表,可以看到之前network建立时的3个node
$ docker ps -a
每个node及user在使用Fabric network时需要从属于一个organizaton以参与网络,test network包含两个peer organization,分别是Org1和Org2,以及一个用于维护网络服务次序的orderer organization
Peers是所有Fabirc network的基本组成,Peers负责保存区块链分类帐并在将交易提交到分类帐之前验证交易
Peers是智能合约的执行者,智能合约包含了管理区块链分类账上资产的业务逻辑
test network中,Org1及Org2分别拥有peer0.org1.example.com和peer0.org2.example.com作为其组织内唯一的Peer
每个Fabric网络还包括Ordering service。 当对等方(Peers)验证交易并将交易块添加到区块链分类账中时,他们并不确定交易的顺序或将其添加至新的块中。 在分布式网络上,Peers可能彼此相距很远,并且对创建事务的时间没有准确的约定。 在交易顺序上达成共识是一个代价高昂的过程,这会给对等方造成开销。
Ordering service允许Peers专注于验证交易并将其提交到分类账。在Ordering node(s)收到客户认可的交易后,他们就交易顺序达成共识,然后将其添加到区块中。 然后将这些块分发到Peers,Peers将这些块添加到区块链分类账中。 个人理解:Ordering service在区块链网络中扮演一个中间人的角色,负责交接手续,确保一手交货一手交钱,保证交易过程稳定安全。
Sample network使用由orderer organization操作的单节点Raft ordering service。 您可以在ordering.example.com上看到正在计算机上运行的订购节点。 尽管test network仅使用单个节点订购服务,但是production network具有多个订购节点,这些订购节点由一个或多个订购者组织操作。 不同的ordering node将使用Raft共识算法来就网络上的事务顺序达成协议。
创建一个通道(Channel)
现在已经有了peer nodes和order nodes,使用脚本network.sh建立一个Fabric channel用于Org1和Org2之间的交易。Channels是在特定网络成员之间的私有层,只能由在channel中的organization使用,对于网络中的其他成员不可见。每个channel有一个独立的区块链分类账,organization被邀请加入channel后,会将自己的peers也代入channel并存储channel分类帐并验证channel上的交易。
$ ./network.sh createChannel
创建通道后,可以开始使用智能合约与通道分类帐进行交互。智能合约包含管理区块链分类账上资产的业务逻辑。网络成员运行的应用程序可以调用智能合约以在分类账上创建、更改和转移资产。应用程序查询智能合约以读取分类账上的数据。 为了确保交易有效,使用智能合约创建的交易通常需要由多个组织签名才能提交到channel分类账。多个签名是Fabric信任模型不可或缺的一部分。交易需要多次认证,可以防止channel上的一个组织篡改其对等账本或使用未经同意的业务逻辑。要签署交易,每个组织都需要在其Peers上调用并执行智能合约,然后再签署交易的输出。如果输出是一致的并且已经有足够的组织签名,则可以将事务提交到分类帐。在通道(channel)上指定需要执行智能合约的设置组织的策略称为认证策略,该策略是为每个chaincode设置的,作为chaincode定义的一部分。 在Fabric中,智能合约以称为chaincode的软件包部署在网络上。 Chaincode安装在organization的peers上,然后部署到channel,这样就能在channel中认可交易并与区块链分类账交互。在将chaincode部署到channel之前,channel成员需要就建立chaincode管理的chaincode定义达成共识。当所需的组织数目达成一致时,可以将chaincode定义提交给渠道,chaincode已完成使用前的准备。
部署chaincode(链码,可理解为智能合约的代码),名称为chaincode-go,语言选择为go
$ ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
成功后关闭测试网络
$ ./network.sh down
安装nvm
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash$ export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"$ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
验证nvm安装情况
$ nvm versionv0.34.0
安装node及npm
$ nvm install 14.16.1
更新npm全局包
$ npm update
安装build-essential,整合了Python v2.7, make, and a C/C++ compiler toolchain such as GCC
$ sudo apt install build-essential
成功后关闭测试网络
$ ./network.sh down
启动测试网络
$ ./network.sh up createChannel -c mychannel -ca
此命令将部署具有两个peers,一个ordering service和三个证书颁发机构(Orderer,Org1,Org2)的Fabric测试网络。 代替使用cryptogen工具,我们使用证书颁发机构(因此代码中含有-ca)来启动测试网络。 此外,启动证书颁发机构时会引导组织管理员用户注册。 在后续步骤中,我们将显示示例应用程序如何完成管理员注册。
部署chaincode,名称为chaincode-javascript,语言选择为javascript
$ ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-javascript/ -ccl javascript
在fabric-samples目录下打开一个新的终端,进入下方目录
$ cd asset-transfer-basic/application-javascript
该目录包含使用Fabric SDK for Node.js开发的示例程序。 运行以下命令以安装应用程序依赖项
$ npm install
此过程将安装在应用程序的package.json中定义的关键应用程序依赖项。 其中最重要的是结构网络Node.js模块。 它使应用程序能够使用身份,钱包和网关来连接到channel,提交交易并等待通知。 本教程还使用fabric-ca-client模块为用户注册各自的证书颁发机构,生成有效的身份,然后由fabric-network模块使用该身份与区块链网络进行交互。 npm install完成后,一切就绪,可以运行该应用程序。 让我们看一下将在本教程中使用的示例 JavaScript 应用程序文件。 运行以下命令以列出此目录中的文件。
$ lsapp.js node_modules package.json package-lock.json
下一节的第一部分涉及与证书颁发机构(Certificate Authority)的通信。 在运行待会儿的程序时,可以打开新的terminal shell并运行
$ docker logs -f ca_org1
显示证书颁发机构日志。
当我们启动Fabric测试网络时,创建了一个管理员用户(名为admin)作为证书颁发机构(CA)的注册者。 我们的第一步是通过让应用程序调用enrollAdmin来生成admin的私钥,公钥和X.509证书。 此过程使用证书签名请求(CSR)-专用密钥和公用密钥首先在本地生成,然后将公用密钥发送到CA,CA返回编码的证书供应用程序使用。 这些凭证然后存储在钱包中,使我们能够充当CA的管理员。 让我们运行该应用程序,然后逐步完成与智能合约功能的每种交互。 在asset-transfer-basic / application-javascript目录中,运行以下命令:
$ node app.js