前言

在基于truffle框架实现以太坊公开拍卖智能合约中我们已经实现了以太坊智能合约的编写及部署,但其工作方式注定其只能应用于有限的业务场景中。相比之下,基于超级账本的Fabric具有高可扩展性和高可定制性,能够应用在更为复杂的商业场景中,但Fabric技术涉及很多新的概念,源代码跟新速度快且各版本间兼容性差,对初学者很不友好。为了使能够快速掌握Fabric,本文基于其目前最新的2.4版本搭建了一套区块链运行环境,并在此之上部署了官方示例chaincode并对其进行交互调试,最终整个环境及示例代码能够正常运行且得出预期结果。

环境搭建

网上几乎所有的Fabric教程都是基于Ubuntu环境而不是Windows,其原因主要是Fabric的运行需要的Docker环境在Windows下表现不佳,此外Fabric许多官方文档也是基于Ubuntu纂写,在windows下运行可能会遇到难以预估的bug。原本为了方便后期部署至公网服务器想在CentOS上搭建环境,但由于CentOS8停止维护,且CentOS Stream使用体验颇差,于是最终选择了Debian系统。
本环境各系统、软件版本如下:

系统、软件 版本
VMware Pro 16.0.0
Debian debian-11.2.0-amd64-DVD-1.iso
git 2.30.2
curl 7.74.0
docker 20.10
golang go1.17.8
jq jq-1.6
fabric 2.4.0
fabric-ca 1.5.2
fabric-samples v2.3.0

本环境各Docker镜像版本如下:

镜像 版本
hyperledger/fabric-tools 2.4
hyperledger/fabric-peer 2.4
hyperledger/fabric-orderer 2.4
hyperledger/fabric-ccenv 2.4
hyperledger/fabric-baseos 2.4
hyperledger/fabric-ca 1.5

警告:建议Fabric所有实验过程皆在root权限下进行,否则在sudo权限切换的过程中会出现很多环境变量的问题。

杂项安装

  1. 安装最新版本Git

    apt install git
    
  2. 安装最新版本cURL
    apt install curl
    
  3. 安装Golang
  4. 安装jq
    apt install jq
    

安装Fabric

官方脚本安装

为了帮助开发者快速搭建Fabric环境,官方创建了一个Fabric环境搭建的批处理工具bootstrap.sh,可以通过该工具直接安装环境:

wget https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh
chmod +x bootstrap.sh
./bootstrap.sh

不出意外的话会看见脚本顺利的环境安装过程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NgTStb2P-1649231335512)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108131408966.png ‘./bootstrap.sh’)]

手动安装

当然,直接使用官方脚本不出意外的话肯定会出意外(网络原因),在此我们可以通过手动安装需要的各项环境。

  1. 安装fabric-samples
    fabric-samplesFabric的官方Demo集合,其内部包含多个示例,每个示例有GolangJavaScripttypescriptJava的链码实现,并且这些链码可以直接部署到对应的Fabric上,对初学者很有帮助。fabric-samples安装非常简单,使用git clone git@github.com:hyperledger/fabric-samples.git将项目源码克隆到本地即可,若一直失败也可以直接在release中下载对应版本的压缩包。
  2. 安装Fabric
    Fabric是联盟链的核心开发工具,包含了我们开发、编译、部署过程中的所有命令。
  3. 下载fabric 2.4.0并解压
wget https://github.com/hyperledger/fabric/releases/download/v2.4.0/hyperledger-fabric-linux-amd64-2.4.0.tar.gz
mkdir /usr/local/fabric
tar -xzvf hyperledger-fabric-linux-amd64-2.3.2.tar.gz -C /usr/local/fabric
  1. 下载fabric-ca 1.5.2并解压
wget https://github.com/hyperledger/fabric-ca/releases/download/v1.5.2/hyperledger-fabric-ca-linux-amd64-1.5.2.tar.gz
tar -xzvf hyperledger-fabric-ca-linux-amd64-1.5.2.tar.gz
mv bin/* /usr/local/fabric/bin
  1. 设置环境变量,在/etc/profile末尾添加
#Fabric
export FABRIC=/usr/local/fabric
export PATH=$PATH:$FABRIC/bin
  1. 更新环境变量source /etc/profile

安装Docker

  1. 如果存在则移除旧的版本
apt remove docker docker-engine docker.io containerd runc
  1. 更新apt索引包并允许其使用HTTPS安装
apt update
apt install \apt-transport-https \ca-certificates \curl \gnupg \lsb-release
  1. 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  1. 添加Docker仓库
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
  1. 安装Docker引擎
apt update
apt install docker-ce docker-ce-cli containerd.io
  1. 安装docker-compose
apt install docker-compose

安装Docker镜像依赖

Fabric相关镜像均可以在DockerHub官方镜像网站进行下载,搜索需要的镜像则可获取安装方法,本试验用到的所有镜像为:

docker pull hyperledger/fabric-tools:2.4
docker pull hyperledger/fabric-peer:2.4
docker pull hyperledger/fabric-orderer:2.4
docker pull hyperledger/fabric-ccenv:2.4
docker pull hyperledger/fabric-baseos:2.4
docker pull hyperledger/fabric-ca:1.5

使用docker images命令查看安装完成后镜像:

hyperledger/fabric-tools     2.4       625237d887db   4 weeks ago    473MB
hyperledger/fabric-peer      2.4       ee643d889779   4 weeks ago    62.3MB
hyperledger/fabric-orderer   2.4       df64446ac2df   4 weeks ago    37.3MB
hyperledger/fabric-ccenv     2.4       da4f00cb576a   4 weeks ago    517MB
hyperledger/fabric-baseos    2.4       0287ebf8aaf3   4 weeks ago    6.94MB
hyperledger/fabric-ca        1.5       4ea287b75c63   6 months ago   69.8MB

示例代码中使用的镜像标签都为latest,但如果在pull时直接选择latest可能会报错,因此我们在上面镜像拉取完成后手动使用以下命令为镜像打上latest标签:

# docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库:标签)
docker tag 625237d887db hyperledger/fabric-tools:latest
docker tag ee643d889779 hyperledger/fabric-peer:latest
docker tag df64446ac2df hyperledger/fabric-orderer:latest
docker tag da4f00cb576a hyperledger/fabric-ccenv:latest
docker tag 0287ebf8aaf3 hyperledger/fabric-baseos:latest
docker tag 4ea287b75c63 hyperledger/fabric-ca:latest

最终的镜像为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4rE5aU7F-1649231335514)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202203301519799.png “最终的镜像”)]

运行测试

启动fabric网络

  1. 进入fabric-sample的test-network目录
cd fabric-samples/test-network
  1. 运行./network.sh up 启动网络
Creating network "fabric_test" with the default driver
Creating volume "docker_orderer.example.com" with default driver
Creating volume "docker_peer0.org1.example.com" with default driver
Creating volume "docker_peer0.org2.example.com" with default driver
Creating peer0.org1.example.com ... done
Creating orderer.example.com    ... done
Creating peer0.org2.example.com ... done
Creating cli                    ... done
CONTAINER ID   IMAGE                               COMMAND             CREATED                  STATUS
PORTSNAMES
7738c1e84751   hyperledger/fabric-tools:latest     "/bin/bash"         Less than a second ago   Up Less than a second                   cli
1f24de2c6cd5   hyperledger/fabric-peer:latest      "peer node start"   2 seconds ago            Up Less than a second   0.0.0.0:9051->9051/tcp, :::9051->9051/tcp, 0.0.0.0:19051->19051/tcp, :::19051->19051/tcp                peer0.org2.example.com
bfc48b20360c   hyperledger/fabric-orderer:latest   "orderer"           2 seconds ago            Up Less than a second   0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:7053->7053/tcp, :::7053->7053/tcp, 0.0.0.0:17050->17050/tcp, :::17050->17050/tcp   orderer.example.com
b9a61fdaf47a   hyperledger/fabric-peer:latest      "peer node start"   2 seconds ago            Up Less than a second   0.0.0.0:7051->7051/tcp, :::7051->7051/tcp, 0.0.0.0:17051->17051/tcp, :::17051->17051/tcp                peer0.org1.example.com

最终出现以上输出日志则表示网络启动成功,每个加入Fabric网络的Node和User都需要隶属于某个组织,以上网络中包含了两个平行组织————peer0.org1.example.compeer0.org2.example.com,它还包括一个作为ordering service维护网络的orderer.example.com

创建channel

上节已经在机器上运行了peer节点和orderer节点,现在可以使用network.sh为Org1和Org2之间创建channel。channel是特定网络成员之间的私有通道,只能被属于该通道的组织使用,并且对网络的其他成员是不可见的。每个channel都有一个单独的区块链账本,属于该通道的组织可以让其下peer加入该通道,以让peer能够存储channel上的帐本并验证账本上的交易。
使用以下命令创建自定义通道testchannel:

./network.sh createChannel -c testchannel

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XEXE761B-1649231335514)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108151123057.png ‘./network.sh createChannel -c testchannel’)]

部署chaincode

建议部署操作全部在root账户下进行,否则可能发生未知错误,以下流程为笔者在非root用户下所遇问题,最终重建虚拟机全部指令在root账户下才完成部署。

创建通道后,您可以开始使用智能合约与通道账本交互。智能合约包含管理区块链账本上资产的业务逻辑,由成员运行的应用程序网络可以在账本上调用智能合约创建,更改和转让这些资产。可以通过./network.sh deployCC命令部署智能合约,但本过程可能会出现很多问题。
使用以下命令部署chaincode:

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

此命令执行后可能会出现错误:scripts/deployCC.sh: line 114: log.txt: Permission denied,很明显这是权限不足所致,加上sudo试试:

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

加上sudo后出现新的错误:deployCC.sh: line 59: go: command not found。检查本用户go命令可用,检查root用户go命令可用,单单sudo后不能用。查阅资料后发现这是因为linux系统为了安全,限制在使用sudo时会清空自定义的环境变量,最简单的解决方法是在/etc/sudoers文件中直接将该限制注释1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hAOc9s5n-1649231335514)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108131722335.png ‘vim /etc/sudoers’)]
加上注释后重新执行上条命令,又出现了新的错误:

go: github.com/golang/protobuf@v1.3.2: Get "https://proxy.golang.org/github.com/golang/protobuf/@v/v1.3.2.mod": dial tcp 172.217.160.81:443: i/o timeout

很明显这是因为本地网络无法访问proxy.golang.org所致,在命令行输入go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct命令配置国内代理2后再次执行。令人意外的是错误不变,设置的代理没有生效?手动使用go get github.com/golang/protobuf手动下载安装后再次运行错误还是不变,此时检查本地GOPATH目录下已有github.com/golang/protobuf包,为什么没有识别到?此时灵机一动,使用go env查看GOPATH环境变量,发现与本地用户不一致,原来sudo命令会使用rootgo环境变量,而之前设置的代理、下载的包都只能在本地用户下生效,因此这个问题最终的解决方案是直接切换到root用户下重新配置go代理并运行。成功运行后可看见如下结果:

2021-08-15 00:45:54.064 PDT [chaincodeCmd] ClientWait -> INFO 001 txid [ebeb8df6904f45b81fb30714f7eecb30b4bbfd32f4acc809f34f7c660e396eb8] committed with status (VALID) at localhost:7051
2021-08-15 00:45:54.144 PDT [chaincodeCmd] ClientWait -> INFO 002 txid [ebeb8df6904f45b81fb30714f7eecb30b4bbfd32f4acc809f34f7c660e396eb8] committed with status (VALID) at localhost:9051
Chaincode definition committed on channel 'testchannel'
Using organization 1
Querying chaincode definition on peer0.org1 on channel 'testchannel'...
Attempting to Query committed status on peer0.org1, Retry after 3 seconds.
+ peer lifecycle chaincode querycommitted --channelID testchannel --name basic
+ res=0
Committed chaincode definition for chaincode 'basic' on channel 'testchannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
Query chaincode definition successful on peer0.org1 on channel 'testchannel'
Using organization 2
Querying chaincode definition on peer0.org2 on channel 'testchannel'...
Attempting to Query committed status on peer0.org2, Retry after 3 seconds.
+ peer lifecycle chaincode querycommitted --channelID testchannel --name basic
+ res=0
Committed chaincode definition for chaincode 'basic' on channel 'testchannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
Query chaincode definition successful on peer0.org2 on channel 'testchannel'
Chaincode initialization is not required

合约交互

在安装fabric中我们已经设置了fabric可执行文件的环境变量,需保证可以成功在test-network目录下使用peer命令。

  1. 设置FABRIC_CFG_PATH变量,其下需包含core.yaml文件
export FABRIC_CFG_PATH=$PWD/../config/
# export FABRIC_CFG_PATH=/usr/local/fabric/config/
  1. 设置其它Org1组织的变量依赖
# Environment variables for Org1
# CORE_PEER_TLS_ROOTCERT_FILE和CORE_PEER_MSPCONFIGPATH环境变量指向Org1的organizations文件夹中的身份证书。
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
  1. 初始化chaincode
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C testchannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitLedger","Args":[]}'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tLBgzBUh-1649231335515)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108151634613.png ‘初始化chaincode’)]
4. 查询账本资产列表

peer chaincode query -C testchannel -n basic -c '{"Args":["GetAllAssets"]}'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-APLs128t-1649231335515)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108151637440.png ‘查询账本资产列表’)]
5. 修改账本资产

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C testchannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"TransferAsset","Args":["asset6","Christopher"]}'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-anN9BqkY-1649231335516)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108151646082.png ‘修改账本资产’)]
6. 关闭网络

./network.sh down

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

因为asset-transfer (basic)链码的背书策略需要交易同时被Org1Org2签名,所以链码调用指令需要使用--peerAddresses标签来指向peer0.org1.example.compeer0.org2.example.com;因为网络的TLS被开启,指令也需要用--tlsRootCertFiles标签指向每个peer节点的TLS证书。

相关实验源码已上传:https://github.com/wefantasy/FabricLearn

参考


  1. qq_JWang_03215367. 解决command not found 报错. 慕课. [2018-07-31] ↩︎

  2. 沐沐子枫. failed to normalize chaincode path: ‘go list’ failed with: go. 博客园. [2020-11-27] ↩︎

基于Debian搭建Hyperledger Fabric 2.4开发环境及运行简单案例相关推荐

  1. zookeeper 虚拟机搭建好后 外部链接不上_Ubuntu Server搭建Hyperledger Fabric 2.1学习环境...

    最近在学习Hyperledger Fabric,它是由 Linux 基金会发起创建的开源区块链分布式账本. Hyperledger Fabric是一个开源区块链实现,开发环境建立在 VirtualBo ...

  2. java sencha_基于SenchaCmd搭建ExtJS 6.2版本开发环境(图文教程)

    因为各种原因,需要在extjs项目中开发点新功能,由于之前没好好接触过extjs,我前端领域主要学的是React技术栈.所以开始找资料搭建ExtJs运行环境. 说一段小插曲,由于看见extjs项目下有 ...

  3. 学习 Hyperledger Fabric 记录 -1开发环境准备:

    至少要熟悉fabric.之前部署过简单的案例及cello项目,后来更换工作后,又放下了,国内环境来说,联盟链的市场毕竟还是风口.在此记录下,所有的学习过程. 开发环境准备: 系统环境:阿里云服务器 2 ...

  4. (一)基于SenchaCmd搭建ExtJS 6.2版本开发环境(图文教程)

    由于工作中可能会用到ExtJS,而且之前从未接触过,于是找资料开始搭建ExtJS,整理下构建步骤,用作记录. 参考文档地址: https://cloud.tencent.com/developer/a ...

  5. 搭建Hyperledger Fabric网络

    注意:进行本文操作的前提是已完成Hyperledger Fabric的开发环境搭建,具体搭建步骤可参考[Hyperledger Fabric开发环境搭建(https://blog.csdn.net/y ...

  6. ESP32 ESP-IDF开发环境搭建,Windows下基于ESP-IDF | Cmake | VScode插件的 ESP32 开发环境搭建

      之前的一篇博客 Windows上基于ESP-IDF搭建ESP32开发环境 发布后,深受好评.几个月过去了,乐鑫的esp-idf-tools安装工具发生了较大的变化,VsCode插件的功能也愈加完善 ...

  7. (Fabric 超级账本学习【5】)Fabric2.4网络环境下——搭建Hyperledger Fabric区块链浏览器

    博主最近在搭建Hyperledger Fabric区块链浏览器过程中也学习了很多博主的搭建流程,踩了很多雷,踩 了很多坑,现将成功搭建好的Hyperledger Fabric区块链浏览器详细流程分享如 ...

  8. 使用Grunt搭建自动化的web前端开发环境-完整教程

    jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! AD: jQuery在使用grunt,bootstrap在使用grunt, ...

  9. 前端自动化构建工具:用Gulp4.0搭建一个基本的前端开发环境

    一个项目的完成一般需要经过三个步骤:初始化.开发和部署.在前端开发过程中,我们经常需要依靠一些自动化构建工具来优化前端工作流程,来帮助我们完成一系列繁琐的工作,例如浏览器热更新.ES6编译.代码压缩. ...

最新文章

  1. 编程珠玑第二章习题答案
  2. 【辟谣】java中的final方法在新版的jvm中能提高效率?
  3. Android中的APinner2
  4. 网络驱动器设备:iscsi服务器
  5. .Net Core下通过Proxy 模式 使用 WCF
  6. 【Java】常见的Eclipse快捷键
  7. concurrent模块的使用
  8. Creo 由方程创建曲线
  9. 11(3)-AirSim+四旋翼仿真-AirSim中人工势场法方法改进
  10. F28335的ADC采集电压不对(ADC采集模块的输入信号的两个端子是:正极:ADCINAx ,负极是:ADCL0)
  11. 普通话/汉语的语音识别:DFSMN-CTC-SMBR模型
  12. 计算机类公务员提升空间,本人在公务员省考裸考申论61分,在之后还有多大的提升空间?...
  13. centos6的yum源
  14. 人脸识别摄像头开发板和模组选型
  15. hadoop之大数据生态系统的前世今生
  16. 指尖心跳,通过手指测量心率波形
  17. android 视频添加音乐,手机怎么给视频加音乐,安卓手机软件怎么给视频添加音乐比较方便...
  18. 直击网易人工智能事业部:闷声发大财的新面孔
  19. 知识图谱学习(笔记整理)
  20. 解密AI芯片的加速原理

热门文章

  1. linux 读 键盘,Linux下直接读键盘
  2. 关于SSD 4K对齐
  3. 如何禁用计算机内网,如何禁止局域网电脑随意安装程序?
  4. 好用的mac录屏软件推荐:白菜录屏mac中文免费版
  5. 妙用Spring的事务超时时间timeout
  6. 今日谈:BoltDB数据库,一款纯Go实现的KV数据库
  7. 计算机基础知识做网页,专业知识—计算机基础知识之网页制作 .doc
  8. 今年广东5G网络覆盖超九成人口
  9. 【VBA自用常用模板1】WORD/WPS办公宏/常用宏
  10. X射线系统、超声波系统及MRI数字成像原理解析