
前言
本部分主要设计fabric环境安装,已经 fabric-sample
中 test-network
和 asset-transfer-basic
样例的运行
Fabric应用程序堆栈有五层:

- 必备软件:运行该软件所需的基础层,例如Docker。
- Fabric和Fabric示例:Fabric可执行文件与示例代码一起运行Fabric网络。
- 合约API:开发在Fabric网络上执行的智能合约。
- 应用程序SDK:开发您的区块链应用程序。
- 应用程序:您的区块链应用程序将利用应用程序SDK调用在Fabric网络上运行的智能合约。
fabric核心模块
模块名词 | 功能 | 类型 |
---|---|---|
peer | 主节点模块,负责存储区块链数据,运行维护代码 | 系统模块 |
order | 交易打包,排序模块 | 系统模块 |
cryptogen | 组织和证书生成模块 | 工具模块 |
configtxgen | 区块和交易生成模块 | 工具模块 |
configtxlator | 区块和交易解析模块 | 工具模块 |
- 工具模块负责证书文件,区块链创始块,通道创始块等相关文件和证书的生成工作,不参与系统的运行。
- cryptogen:模块主要用于生成组织结构和账号相关文件,任何fabric系统的开发都是从cryptogen模块开始,在系统设计完成后首要工作就是根据系统设计编写cryptogen的配置文件。
- configtxgen:
开发环境
系统:MacOS
必备软件
Prerequisites - 先决条件
- Homebrew:仅mac系统需要,用来管理下面所需要的软件包
- git:版本管理工具
- cURL:curl命令是个功能强大的网络工具,支持通过http、ftp等方式下载文件、上传文件
- Docker & Docker-compose:一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化
- Go:Docker是基于go语言的
- (only required if you will be writing Go chaincode or SDK applications)
- JQ:既JQuery,一个优秀的javascript类库
- (only required for the tutorials related to channel configuration transactions)
Homebrew
1 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" |
问题
- Error: Unknown command: cask
- Homebrew 2.5.x 之后删掉了
brew cask
- 直接使用
brew
,或者brew --cask
即可
升级后核心不可用
homebrew-core is a shallow clone
- 先按照提示执行
git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
- 如果系统不支持
unshallow
,则删掉核心后再update
1
2 rm -rf /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core
brew update
Git
1 | brew install git |
cURL
1 | brew install curl |
Docker
- Since Docker Desktop is a UI application on Mac, use
cask
to install it.
Homebrew v2.x:
1 | brew cask install --appdir="/Applications" docker |
Homebrew v3.x:
1 | brew install --cask --appdir="/Applications" docker |
- Docker Desktop must be launched to complete the installation so be sure to open the application after installing it:
1 | open /Applications/Docker.app |
- Once installed, confirm the latest versions of both
docker
anddocker-compose
executables were installed.
1 | docker --version |
加速
docker镜像在国外,为了后续下载加速,配置文件将镜像换成国内的
在
/etc/docker/daemon.json
文件中配置或者如下图所示在软件中配置:{"registry-mirrors":["https://reg-mirror.qiniu.com/"]}

Go
1 | brew install go |
- 可以根据喜好设置项目目录,下面为推荐目录结构
1 | export GOPATH:$Home/<user-defined-workspace>/go |
JQ
1 | brew install jq |
问题
- python版本问题
- 按照给出的指令顺序操作
--overwrite
表示强制
fabric
下载fabric
1 | cd $GOPATH/src/github.com/hyperledger |
- make将会在
build/bin
目录下生成二进制可执行文件
bootstrap.sh
路径:fabric/script/bootstrap.sh
主要功能:

SAMPLES:克隆fabric-samples
BINARIES:安装二进制文件
DOCKER:下载docker镜像
执行:
docker image
镜像名称 | 是否可选 | 镜像说明 |
---|---|---|
hyperledger/fabric-tools | 可选 | 包含crytogen、configtxgen、configtxlator我第二次工具的镜像文件 |
hyperledger/fabric-couchdb | 可选 | CouchDB的数据库镜像文件、状态数据库选择CouchDB的时候才需要 |
hyperledger/fabric-kafka | 可选 | Kafka的镜像文件 |
hyperledger/fabric-zookeeper | 可选 | Zookeeper的镜像文件 |
hyperledger/fabric-peer | 必选 | Peer节点的镜像文件 |
hyperledger/fabric-orderer | 必选 | 排序服务节点的镜像文件 |
hyperledger/fabric-javaenv | 可选 | java链码的基础镜像文件 |
hyperledger/fabric-ccenv | 必选 | Golang链码的基础镜像文件 |
hyperledger/fabric-ca | 可选 | fabric-ca的镜像文件,用到fabric-ca的时候才需要 |
fabric-sample
github源码:
1 | mkdir -p $HOME/go/src/github.com/<your_github_userid> |
- 创建go项目目录并使用curl下载sample文件
上面的curl命令将会执行以下步骤:
下载最新的Hyperledger Fabric Docker映像并将其标记为
latest
将以下特定于平台编译好的的Hyperledger Fabric CLI工具二进制文件和配置文件下载到
fabric-samples
/bin
和/config
目录中。这些二进制文件将帮助您与测试网络进行交互。
问题
报错:
- 此处网站
https://bit.ly/2ysbOFE
需要科学上网,在国内访问不了(针对Ubuntu / CentOS系统)
如果无法访问上述github文件,可以考虑添加docker镜像源
在文件
/etc/docker/daemon.json
中添加镜像源:
"registry-mirrors":["https://registry.docker-cn.com"]
查看镜像源:
1
2
3 docker info|grep Mirrors -A 1
Registry Mirrors:
https://registry.docker-cn.com/重启网络
1
2
3
4
5
6 Ubuntu
sudo /etc/init.d/networking restart
CentOS
sudo /etc/init.d/network restart
Mac
sudo ifconfig en0 down/up再次执行curl指令
(还是无法链接网站)
- 上面的网站主要是为了获得一个
bootstrap.sh
的脚本文件并执行
我们只需要去fabric中下载bootstrap.sh源码即可
- 需要先下载zip
https://github.com/hyperledger/fabric.git
(master分支)- 再将文件
fabric/scripts/bootstrap.sh
移动到目录$HOME/go/src/github.com/<your_github_userid>
下- 或者使用github单个文件下载工具DownGit
- 之后在此脚本目录下执行下面的指令即可
1 cat bootstrap.sh |bash -s
运行 bootstrap.sh 时如果发现无法下载fabric的二进制可执行文件和配置文件,如下图:
可能是因为网络不稳定,换一个好点的网络重新运行
也可以将这部分的代码单独拉出来执行
注意文件版本,根据自己的系统选择,darwin(=MacOS)、linux、win等
- 点击下面两个链接即可自动下载
或者在终端中执行下面的命令
1失败重复5次,重复间隔时间为3s,并保存为 .tar.gz 形式
$ curl -L –retry 5 –retry-delay 3 “https://github.com/hyperledger/fabric/releases/download/v2.3.1/hyperledger-fabric-darwin-amd64-2.3.1.tar.gz" | tar xz
$ curl -L –retry 5 –retry-delay 3 “https://github.com/hyperledger/fabric-ca/releases/download/v1.4.9/hyperledger-fabric-ca-darwin-amd64-1.4.9.tar.gz" | tar xz
1
2
3
4
5
6
7
8
9
10
11
12
13
14
3. 或者自行编译[fabric](https://github.com/hyperledger/fabric.git)和[fabric-ca](https://github.com/hyperledger/fabric-ca.git)源码得到,需要go环境依赖
```shell
# 编译fabric
$ cd fabric
$ make release
$ cd $GOPATH/src/github.com/hyperledger/fabric/release/linux-amd64/bin/
# 编译fabric-ca
$ cd fabric-ca
$ make fabric-ca-server
$ make fabric-ca-client
$ cd bin解压后得到两个bin文件夹和一个config文件夹,合并bin文件夹后将两者放到fabric-sample中
- 这些二进制文件将帮助您与测试网络进行交互
sample测试
运行测试网络
普通网络
运行脚本 network.sh
来启动测试网络,该脚本使用本地计算机上的Docker映像站立在Fabric网络上
- 到目录
fabric-samples/test-network
下执行命令
1 | $ ./network.sh up |
- 启动网络
- 此命令创建一个结构网络,该结构网络由两个对等节点,一个订购节点组成。您在运行时不会创建任何渠道,如果命令成功完成,您将看到正在创建的节点的日志

1 | $ ./network.sh down |
- 从以前的任何运行中删除任何容器或工件
1 | $ docker ps -a |
- 列出计算机上运行的所有Docker容器
- 网络中的每个对等方都必须属于一个组织。在测试网络中,每个组织各自运营一个对等方,
peer0.org1.example.com
和peer0.org2.example.com
。 - 每个Fabric网络还包括订购服务,可以看到订购节点
orderer.example.com
。
- 网络中的每个对等方都必须属于一个组织。在测试网络中,每个组织各自运营一个对等方,
1 | ./network.sh createChannel -c channelName |
- 创建Channel,系统默认命名为
mychannel
- channel名称限制
- 仅包含小写ASCII字母数字,点“。”和破折号“-”
- 少于250个字符
- 以字母开头
1 | ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go |
- 在channel上启动链码(此链码将在名为
mychannel
的通道上执行) - 可以在
fabric-sample
的asset-transfer-basic
文件夹中找到资产转移的示例代码 - 第一次部署链码的话,该脚本将安装链码依赖项
报错
第一次部署时无法下载依赖
只需要执行两个命令更改GO为国内代理即可,再此执行将成功
1
2go env -w GOPROXY=https://goproxy.io,direct
go env -w GO111MODULE=on
无法下载组建 InstallChaincode
网络问题,重启网络,再重新创建myChannel即可
1
2
3
4./network.sh down
./network.sh up
./network.sh createChannel
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
与网络互动,配置peer指令
- 均在
test-network
文件夹下执行
1 | 将fabroc-sample/bin下的二进制文件添加到CLI路径中() |
- 该
CORE_PEER_TLS_ROOTCERT_FILE
和CORE_PEER_MSPCONFIGPATH
环境变量指向的ORG1加密材料organizations
文件夹。
1 | peer channel list |
- 列出网络中所有的channel
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 mychannel -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":[]}' |
- 使用资产初始化分类帐
- 成功后就可以使用CLI来查询分类账
1 | peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}' |
- 获取已添加到渠道分类帐中的资产的列表
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 mychannel -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":[]}' |
- 当网络成员要转移或更改分类帐上的资产时,将调用链码。
- 此命令通过调用
asset-transfer-basic
链码来更改分类帐上资产的所有者
调用链代码后,我们可以使用另一个查询来查看该调用如何更改了区块链分类账上的资产。由于我们已经查询过Org1对等体,因此我们可以借此机会查询Org2对等体上运行的链码。
1 | Environment variables for Org2 |
- 设置环境变量以作为Org2进行操作
1 | peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}' |
查询运行在 mychannel 上的
asset-transfer-basic
链码peer0.org2.example.com
结果显示
"asset6"
已转移到Christopher:
与证书颁发机构建立网络
1 | ./network.sh up -ca |
1 | tree命令并不是默认安装的,如果没有该命令,先安装 |
显示MSP文件夹的结构和配置文件:
运行结构应用程序
资产转移
asset-transfer-basic
样本演示了如何使用资产初始化分类帐,查询那些资产,创建新资产,基于资产ID查询单个资产,更新现有资产以及将资产转移给新所有者。它涉及以下两个组件:
示例应用程序:调用区块链网络,调用以链码(智能合约)实现的交易。该应用程序位于以下
fabric-samples
目录中:1
asset-transfer-basic/application-javascript
智能合约本身,实现涉及与分类账交互的交易。智能合约(链码)位于以下
fabric-samples
目录中:1
asset-transfer-basic/chaincode-(javascript, java, go, typescript)
请注意,在本教程中,术语链码和智能合约可互换使用。在此示例中,我们将使用javascript链码。
主要步骤:
建立开发环境。我们的应用程序需要与之交互的网络,因此我们将为我们的智能合约和应用程序部署一个基本的网络。
探索样本智能合约。 我们将检查示例assetTransfer(javascript)智能合约,以了解其中的交易以及应用程序如何使用它们查询和更新分类账。
通过示例应用程序与智能合约进行交互。我们的应用程序将使用assetTransfer智能合约在分类账上创建,查询和更新资产。我们将深入研究应用程序及其创建的交易的代码,包括使用资产初始化分类账,查询资产,查询一系列资产,创建新资产以及将资产转让给新所有者。
启动网络
- 根据运行测试网络的步骤
1 | open /Applications/Docker.app # mac上启动docker desktop的方式 |
申请样本
1 | export PATH=${PWD}/../bin:$PATH |
- 设置peer指令环境变量
1 | cd fabric-sample/asset-transfer-basic/application-javascript |
- 打开一个新的终端,进入到示例代码文件中,
- 该目录包含使用Fabric SDK for Node.js开发的示例程序。
1 | npm install |
运行 npm 命令以安装应用程序依赖项。最多可能需要一分钟才能完成。
此过程将安装在的应用程序中定义的关键应用程序依赖项
package.json
。其中最重要的是fabric-network
Node.js模块;它使应用程序能够使用身份,钱包和网关来连接到渠道,提交交易并等待通知运行完成后将得到以下文件
代码解析
fabric-sample/asset-transfer-basic/application-javascript/app.js
- 仅调用方法
- 方法定义在
fabric-sample/test-application/javascript/
的CAUtil.js
和AppUtil.js
中
- 方法定义在
app.js:
当我们启动Fabric测试网络时,创建了一个管理员用户(字面上称为admin
)作为证书颁发机构(CA)的注册商。

- 调用函数
enrollAdmin()
生成 admin 的私钥,公钥和X.509证书。- 此过程使用证书签名请求(CSR)-专用密钥和公用密钥首先在本地生成,然后将公用密钥发送到CA,CA返回编码的证书供应用程序使用。
- 这些凭证然后存储在
application-javascript/wallet
中,使我们能够充当CA的管理员。 - 可以在
wallet/admin.id
文件中找到管理员的证书和私钥
注意
如果您决定通过断开网络并重新启动来重新开始,则必须
wallet
在重新运行javascript应用程序之前删除该文件夹及其标识,否则会出现错误。发生这种情况的原因是,在关闭测试网络时,关闭了证书颁发机构及其数据库,但是原始钱包仍保留在application-javascript目录中,因此必须将其删除。当您重新运行示例javascript应用程序时,将生成一个新的钱包和凭据。
- 调用
registerAndEnrollUser()
来注册并加入一个应用程序用户appUser
,该用户将用于与区块链网络进行交互- 与管理员注册类似,此功能使用CSR来注册,注册
appUser
和存储其凭据以及admin
钱包中的凭据。 - 现在,我们拥有两个独立用户的身份,
admin
并且appUser
该身份可以由我们的应用程序使用
- 与管理员注册类似,此功能使用CSR来注册,注册

应用程序正在通过网关 gateway 使用
chaincodeName
和channelName
名称来引用合约(本例是在 mychannel 中使用 asset-transfer-basic 合约)
当链码包包含多个智能合约时,可以在getContract()API上指定链码包的名称和要定位的特定智能合约。
1
const contract = await network.getContract('chaincodeName', 'smartContractName');
asLocalhost
settrue
告知它以localhost连接。在不将客户端与其他结构节点在同一网络上运行的部署中,该asLocalhost
选项将设置为false
。

SubmitTransaction()
函数用于调用chaincode的InitLedger
函数,以使用一些样本数据填充分类帐。- 在幕后,
submitTransaction()
函数将使用服务发现来为链码找到一组所需的认可对等体,在所需数目的对等体上调用链码,从这些对等体收集链码认可的结果,最后将事务提交给订购服务。 - 对等体在assets中指定,然后使用
ctx.stub.putState(...)
来验证(chaincode-javascript中)
- 在幕后,


require(‘fabric-network’); 模块中,定义在文件 fabric-network/lib/transaction.js 中
evaluateTransaction()
- 代表了区块链网络中与智能合约最简单的交互之一。只是查询账本内容而已
- 它只是选择一个在连接配置文件中定义的对等体,然后将请求发送到该对等体,并在此对其进行评估。智能合约查询对等方账本副本上的资产,并将结果返回给应用程序。
- 这种交互不会导致分类账的更新。
submitTransaction()
- 比
evaluateTransaction()
复杂得多,是一个完整的共识流程(提交-背书-检验) - SDK不会与单个peer进行交互,而是根据chaincode的背书政策,向区块链网络中每个需要的组织对等方发送
proposal
。这些对等方中的每一个都将使用该proposal
执行所请求的智能合约,以生成交易响应,该交易响应将对其背书(签署)并返回到SDK。SDK将所有已背书的交易响应收集到一个交易中,然后将其提交给oderer。oderer将来自各种应用程序客户端的交易收集并排序为一个交易块。这些块被分发到网络中的每个对等点,在此对每个事务进行验证和提交。最后,通过事件通知SDK,使其可以将控制权返回给应用程序。
CAUtil.js
enrollAdmin
registerAndEnrollUser
常见错误
- Post title:fabric-Getting Start
- Post author:Wei Jieyang
- Create time:2021-03-14 12:08:44
- Post link:https://jieyang-wei.github.io/2021/03/14/fabric-Getting Start/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.