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

前言

基于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
    1. apt install git
  2. 安装最新版本cURL
    1. apt install curl
  3. 安装Golang
  4. 安装jq
    1. apt install jq

安装Fabric

官方脚本安装

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

  1. wget https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh
  2. chmod +x bootstrap.sh
  3. ./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并解压
  1. wget https://github.com/hyperledger/fabric/releases/download/v2.4.0/hyperledger-fabric-linux-amd64-2.4.0.tar.gz
  2. mkdir /usr/local/fabric
  3. tar -xzvf hyperledger-fabric-linux-amd64-2.3.2.tar.gz -C /usr/local/fabric
  1. 下载fabric-ca 1.5.2并解压
  1. wget https://github.com/hyperledger/fabric-ca/releases/download/v1.5.2/hyperledger-fabric-ca-linux-amd64-1.5.2.tar.gz
  2. tar -xzvf hyperledger-fabric-ca-linux-amd64-1.5.2.tar.gz
  3. mv bin/* /usr/local/fabric/bin
  1. 设置环境变量,在/etc/profile末尾添加
  1. #Fabric
  2. export FABRIC=/usr/local/fabric
  3. export PATH=$PATH:$FABRIC/bin
  1. 更新环境变量source /etc/profile

安装Docker

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

安装Docker镜像依赖

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

  1. docker pull hyperledger/fabric-tools:2.4
  2. docker pull hyperledger/fabric-peer:2.4
  3. docker pull hyperledger/fabric-orderer:2.4
  4. docker pull hyperledger/fabric-ccenv:2.4
  5. docker pull hyperledger/fabric-baseos:2.4
  6. docker pull hyperledger/fabric-ca:1.5

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

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

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

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

最终的镜像为:

运行测试

启动fabric网络

  1. 进入fabric-sample的test-network目录
  1. cd fabric-samples/test-network
  1. 运行./network.sh up 启动网络
  1. Creating network "fabric_test" with the default driver
  2. Creating volume "docker_orderer.example.com" with default driver
  3. Creating volume "docker_peer0.org1.example.com" with default driver
  4. Creating volume "docker_peer0.org2.example.com" with default driver
  5. Creating peer0.org1.example.com ... done
  6. Creating orderer.example.com ... done
  7. Creating peer0.org2.example.com ... done
  8. Creating cli ... done
  9. CONTAINER ID IMAGE COMMAND CREATED STATUS
  10. PORTS
  11. NAMES
  12. 7738c1e84751 hyperledger/fabric-tools:latest "/bin/bash" Less than a second ago Up Less than a second cli
  13. 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
  14. 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
  15. 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:

  1. ./network.sh createChannel -c testchannel

部署chaincode

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

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

使用以下命令部署chaincode:

  1. ./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试试:

  1. ./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]



加上注释后重新执行上条命令,又出现了新的错误:

  1. 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代理并运行。成功运行后可看见如下结果:

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

合约交互

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

  1. 设置FABRIC_CFG_PATH变量,其下需包含core.yaml文件
  1. export FABRIC_CFG_PATH=$PWD/../config/
  2. # export FABRIC_CFG_PATH=/usr/local/fabric/config/
  1. 设置其它Org1组织的变量依赖
  1. # Environment variables for Org1
  2. # CORE_PEER_TLS_ROOTCERT_FILE和CORE_PEER_MSPCONFIGPATH环境变量指向Org1的organizations文件夹中的身份证书。
  3. export CORE_PEER_TLS_ENABLED=true
  4. export CORE_PEER_LOCALMSPID="Org1MSP"
  5. export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
  6. export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
  7. export CORE_PEER_ADDRESS=localhost:7051
  1. 初始化chaincode
  1. 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":[]}'



4. 查询账本资产列表

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



5. 修改账本资产

  1. 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"]}'



6. 关闭网络

  1. ./network.sh down

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

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

参考


  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. Ubuntu下搭建Hyperledger Fabric v1.0环境

      多次尝试才正常启动了Fabric,如遇到各种莫名错误,请参考如下一步步严格安装,特别用户权限需要注意. 一.安装Ubuntu16 虚拟机或双系统,虚拟机有VirtualBox或者VMware,Ub ...

  2. Hyperledger Fabric 1.4 快速环境搭建

    自己的硕士研究方向和区块链有关,工程上一直以IBM的Hyperledger Fabric为基础进行开发,对该项目关注也有两年了.目前迎来了Hyperledger Fabric v1.4,这也是Fabr ...

  3. 基于AM3352/AM3354/AM3358/AM3359的Linux 开发环境搭建(上)

    遇到不少人新手小白问,前辈如何搭建一个优良的Linux 开发环境?之前一直都是在用win开发,现在想要尝试用Linux做开发等等一系列的问题.开源一直是给电子行业工作者提供了一种向技术更深处进发的机遇 ...

  4. 利用grunt-contrib-connect和grunt-connect-proxy搭建前后端分离的开发环境

    前后端分离这个词一点都不新鲜,完全的前后端分离在岗位协作方面,前端不写任何后台,后台不写任何页面,双方通过接口传递数据完成软件的各个功能实现.此种情况下,前后端的项目都独立开发和独立部署,在开发期间有 ...

  5. 【前端福利】用grunt搭建自动化的web前端开发环境-完整教程

    jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发人员,如果你现在还不知道grunt或者听说过 ...

  6. 转:【前端福利】用grunt搭建自动化的web前端开发环境-完整教程

    原文地址:http://blog.csdn.net/wangfupeng1988/article/details/46418203 jQuery在使用grunt,bootstrap在使用grunt,百 ...

  7. 用grunt搭建自动化的web前端开发环境实战教程(详细步骤)

    用grunt搭建自动化的web前端开发环境实战教程(详细步骤) jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用!前端自动化, ...

  8. 搭建Eclipse、Resin Web开发环境

    搭建Eclipse.Resin Web开发环境 一.当然是安装java开发环境 参看: Java环境的搭建 http://www.cnblogs.com/ghj1976/archive/2010/04 ...

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

    原稿:http://www.cnblogs.com/wangfupeng1988/p/4561993.html#!comments jQuery在使用grunt,bootstrap在使用grunt,百 ...

随机推荐

  1. tensorflow源码解析之framework-resource

    目录 什么是resource 如何使用resource 如何管理resource 常用resource 其它结构 关系图 涉及的文件 迭代记录 1. 什么是resource 我们知道,TF的计算是由设 ...

  2. vue中使用keepAlice的各种问题

    项目需求:从项目列表页index,进入到列表的详情页detail,再从detail返回到index,需要缓存index的数据 在App.vue中的配置 <template> <div ...

  3. Java案例——猫与狗(接口版)

    一.需求:对猫跟狗进行训练,加入跳高功能,采用抽象类和接口实现,并创建测试类测试 二.分析: 1.定义接口(Jummping) 成员方法 跳高(): /*定义跳高接口 * */public inter ...

  4. Centos7下开启防火墙,允许通过的端口

    1.查看防火墙状态 systemctl status firewalld 2.如果不是显示active状态,需要打开防火墙 systemctl start firewalld 3.# 查看所有已开放的 ...

  5. 我写的 Python 代码,同事都说好

    原文链接: 我写的 Python 代码,同事都说好 人生苦短,我用 Python. 程序员的追求就是不写代码,早日财务自由.不对,一不小心把实话说出来了,应该是将代码写得简洁,优雅. Python 程 ...

  6. 74CMS 3.0 CSRF漏洞

    一. 启动环境 1.双击运行桌面phpstudy.exe软件 2.点击启动按钮,启动服务器环境 二.代码审计 1.双击启动桌面Seay源代码审计系统软件 2.因为74CMS3.0源代码编辑使用GBK编 ...

  7. Rust极简教程

    目录 简介 特性 特征 用途 安装 核心组件 常用命令 基础语法 数据类型 标量类型 复合类型 示例 条件语句 循环 输出&输入 输出 输出花括号 输出非基础类型 输入 所有权 切片 结构体 ...

  8. git tag、gitignore和git撤销提交

    前言 最近在git的使用过程中遇到了一些新的问题,所以写下来方便自己回忆. git tag 打标签 git tag -a v1.00 -m "注释" git tag 打标签命令 - ...

  9. 设置一段文字的大小为6px?

    谷歌最小12px, 其他浏览器可以更小 通过transform: scale实现

  10. 什么是 FreeMarker 模板?

    FreeMarker 是一个基于 Java 的模板引擎,最初专注于使用 MVC 软件架构进行动态网页生成.使用 Freemarker 的主要优点是表示层和业务层的完全分离.程序员可以处理应用程序代码, ...