Fabric 2.3.2离线部署

Fabric离线部署

联盟链及Hyperledger Fabric简介

联盟链定义:

根据去中心化程度的不同,区块链分化出三种不同应用场景下的种类:

公有链:全网公开,广大用户均可参与

私有链:所有网络节点都掌握在一家机构中

联盟链:用于多个机构之间,允许授权的节点加入网络,可根据权限查询或修改信息

优缺点

相比于公有链,联盟链在效率和灵活性上更有优势

交易成本低,交易只需被几个受信的高算力节点验证即可,无需全网确认

节点规模小,故障可以通过人工干预较快修复

使用确定型的共识算法并缩短区块生成时间使得交易更快完成

读写权限受控制,提供更为安全的隐私保护

联盟链的参与者可以更容易地达成一致来更新链上规则、还原交易、修改余额等

相比于公有链,联盟链去中心化程度不够高

Hyperledger Fabric(超级账本)

简介

Hyperledger是一个区块链跨行业应用的开源项目,而其中Fabric是最成功的子项目。

支持以通用编程语言(Go/Java/Node.js)而非受约束的领域特定语言(DSL)编写智能合约。

支持可插拔的共识协议以适应特定的信任模型,节点的授权加入方便网络管理,无需发行加密货币来激励记账。

账本 Ledger

Fabric的账本由两个不同但相关的部分组成,分别是世界状态和区块链。

世界状态(World-State)保存了账本数据的当前值,同时可以被更改,其本质是一个数据库,支持LevelDB和CouchDB。

区块链(Blockchain)记录了所有更改日志,日志写入后无法被修改,这便于管理人员进行历史追踪。

身份与成员资格 Identity and Membership

Fabric使用X.509格式的证书作为身份验证,通过证书来标识整个网络中的所有参与者,并提供用于确定许可权的一些属性,证书通过证书颁发机构(CA)来颁发。

Fabric提供了一个成员资格服务提供商(MSP),用于确定哪些CA是受信任的、列出组织成员身份、识别参与者在组织内扮演的特定角色、定义网络和通道访问权限等。

智能合约与链码 Smart Contracts and Chaincode

智能合约用来定义业务交易逻辑,在世界状态下放置、获取、删除状态或者查询区块链交易记录。

链码是用于安装和实例化智能合约的技术容器,一个链码可以包含多个智能合约。

对等节点 Peer Node

对等节点(简称Peer)组件是Fabric区块链网络的基本元素,它托管着账本和智能合约,且可以同时托管多个账本和多个智能合约。

区块链网络拥有多个组织下的多个对等节点,对等方节点具有通过特定CA颁发的数字证书分配的身份。

通道 Channel

通道允许一组特定的对等节点和应用程序在区块链网络内相互通信,通道并不实际存在,而是由物理对等节点集合形成的逻辑结构。

每个通道都有一个完全独立的账本,这说明每个通道都有一个完全独立的区块链,以及完全独立的世界状态。

一个组织可以加入多个通道,从而参与多个独立的区块链网络。

排序服务 Ordering Service

Fabric 采用称为排序服务的特殊节点来执行交易的排序并生成区块,形成一种确定性的共识机制,由排序服务生成的任何块都可以保证是最终且正确的,不会产生分支。

排序服务维护着允许创建通道的组织列表,还对通道实施基本的访问控制,从而限制了谁可以对其进行数据读写和配置。

排序服务有三种实现,使排序节点之间对严格的交易顺序达成共识:

- Solo: 只有一个排序节点,无法容错,但可以用于开发测试环境,

- Kafka:崩溃容错(CFT)机制,选举领导者节点,跟随者复制其决策,

- Raft: 也是崩溃容错(CFT)机制,比Kafka易于配置和管理。

Fabric v2.0 test network功能简介与测试

说明

Hyperledger Fabric平台通过其通道体系结构和私有数据功能来实现机密性。在通道(channel)中,Fabric网络上的参与者建立了一个子网,每个成员都可以查看特定的一组交易。因此,只有那些参与通道的节点(node)才能访问智能合约(chaincode)和交易的数据,从而保留了两者的隐私和机密性。私有数据允许在通道上的成员之间进行收集,从而在不增加创建和维护单独通道的维护开销的情况下,提供与通道相同的保护。

一、安装fabric所需环境

编号 工具 版本
1 gcc 4.8.5
2 git 1.8.3.1
3 docker 19.03.9
4 docker-compose 2.1.0
5 go 1.16.7
6 protobuf 3.6.1
7 curl 7.29.0(本机自带)
8 node.js、npm 8.9.4、5.6.0
9 python 2.7.5(本机自带)

安装环境

# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)

# uname -r
3.10.0-957.el7.x86_64

# 时间要同步,如果时间相差太大会有问题
# 关闭防火墙

Docker 要求 CentOS 系统的内核版本高于 3.10,我的是3.10.0

需要提前升级内核,否则docker启动失败。这里不涉及升级内核

1、安装Gcc

# 如果可用yum就直接下载即可
yum -y install gcc

# 可以找一台能连接外网的虚机下载rpm包,完成之后保存上传到内网安装,后面组件同样适用
# 命令如下,下载gcc及依赖,下载不安装
yum install --downloadonly --downloaddir=/root/soft/gcc gcc*
# 后边所有文件都在/data/soft下,所有提前创建好/data目录,gcc放到/data/soft/下
[root@localhost]# mkdir /data/soft -p
# 把准备好的gcc.tar包上传到此目录下/data/soft下
# 解压gcc
[root@localhost data]# tar xf soft/gcc.tar.gz -C .
[root@localhost data]# cd gcc
# 强制安装此目录下所有rpm,不检索依赖
[root@localhost gcc]# rpm -Uvh --force --nodeps *.rpm
# 安装完成后查看gcc版本
[root@localhost gcc]# gcc –version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)

2、安装Git

#编译安装git前,它需要依赖这些curl-devel expat-devel gettext-devel openssl-devel zlib-devel依赖包。一般直接用yum命令安装一下就行了。这里提前下载好所需依赖包,打成tar包。
# 内网服务器不连外网,直接通过另一台可以连外网的服务器,将所需的依赖通过yum命令下载下来,将所有下载下来的rpm包都上传到这台服务器上安装
# 上传准备好的git-1.8.3.1.tar.gz及依赖包到soft下解压
# 强制安装
[root@localhost git]# rpm -Uvh --force --nodeps *.rpm
# 查看git
[root@localhost git-1.8.3.1]# git –version
git version 1.8.3.1

3、安装docker

# 上传docker-19.03.9.tgz到soft下
# 下载地址https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz
# 解压到data下
[root@localhost data]# tar xf soft/docker-19.03.9.tgz -C /data/
# 拷贝docker下文件到/usr/bin/
[root@localhost data]# cp /data/docker/* /usr/bin/
# 配置systemd管理docker
vim /lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
# 创建加速配置文件,内网可配置harbor地址
mkdir /etc/docker
[root@localhost data]# vim /etc/docker/daemon.json
{
    
    
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn","https://mirror.ccs.tencentyun.com","https://hub-mirror.c.163.com","https://xkhndtby.mirror.aliyuncs.com"]
}
#启动并设置开机启动
[root@localhost data]# systemctl daemon-reload
[root@localhost data]# systemctl start docker
[root@localhost data]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
# 查看版本
[root@localhost data]# docker --version
Docker version 19.03.9, build 9d988398e7

4、安装docker-compose

# 下载地址
https://github.com/docker/compose/releases/download/v2.1.0/docker-compose-linux-x86_64
# 上传docker-compose到soft下
# 移动到/usr/local/bin/下并改名docker-compose
[root@localhost data]# mv soft/docker-compose-linux-x86_64  /usr/local/bin/docker-compose
# 赋予权限
[root@localhost data]# chmod +x /usr/local/bin/docker-compose
# 查看版本
[root@localhost data]# docker-compose -v
Docker Compose version v2.1.0

5、安装Go

# 下载地址
wget https://golang.google.cn/dl/go1.16.7.linux-amd64.tar.gz
# 上go1.15.7.linux-amd64.tar.gz到/data/soft下
# 解压到/usr/loacal下
[root@localhost data]# tar xf soft/go1.16.7.linux-amd64.tar.gz -C /usr/local/
[root@localhost soft]# ln -s /usr/local/go/bin/* /usr/bin/
# 配置环境变量
# 执行该命令打开文件,在 profile 文件最后添加如下内容
[root@localhost data]# vi /etc/profile
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
# 使环境变量生效
[root@localhost data]# source /etc/profile
# 查看版本
[root@localhost data]# go version
go version go1.16.7 linux/amd64

# 外网可以打开,内网没用
# 开启Go的MODULE支持
go env -w GO111MODULE=off
# 软件源替换
go env -w GOPROXY=https://goproxy.cn,direct

6、安装protobuf

# 创建soft/protobuf上传依赖包到此目录下
# 依赖包
# 大多数依赖包都可以在此上面找到:http://www.rpmfind.net/linux/rpm2html/search.php?query=
ansible-2.8.0-2.el7.noarch.rpm、basesystem-10.0-7.el7.centos.noarch.rpm
nspr-4.21.0-1.el7.i686.rpm、nspr-4.21.0-1.el7.x86_64.rpm
[root@localhost protobuf]# ll
total 15312
-rw-r--r--. 1 root root 15402787 Nov  5 00:22 ansible-2.8.0-2.el7.noarch.rpm
-rw-r--r--. 1 root root     5124 Nov  5 00:22 basesystem-10.0-7.el7.centos.noarch.rpm
-rw-r--r--. 1 root root   131452 Nov  5 00:22 nspr-4.21.0-1.el7.i686.rpm
-rw-r--r--. 1 root root   129772 Nov  5 00:22 nspr-4.21.0-1.el7.x86_64.rpm
# 强制安装依赖
[root@localhost protobuf]# rpm -Uvh --force --nodeps *.rpm
# 解压protobuf-all-3.6.1.tar.gz到data下
[root@localhost data]# tar xf soft/protobuf-all-3.6.1.tar.gz -C /data/
[root@localhost data]# cd protobuf-3.6.1/
# 编译安装会需要很长很长时间,一步步执行等着即可
[root@localhost protobuf-3.6.1]# ./configure -prefix=/usr/local/
[root@localhost protobuf-3.6.1]# make && make check && make install
# 终端输入查看protobuf是否安装成功
# protoc --version
libprotoc 3.6.1

7、 安装curl及python

# 系统自带,不用安装
[root@localhost data]# curl --version
curl 7.29.0 (x86_64-redhat-linux-gnu)
# 系统自带,不用安装
[root@localhost data]# python --version
Python 2.7.5

8、安装node.js

# 上传node-v8.9.4-linux-x64.tar.xz到/data/soft下
# 解压
[root@localhost data]# tar xf soft/node-v8.9.4-linux-x64.tar.xz -C /data/
# 配置软连接
[root@localhost data]# ln -s /data/node-v8.9.4-linux-x64/bin/npm /usr/local/bin/npm
[root@localhost data]# ln -s /data/node-v8.9.4-linux-x64/bin/node /usr/local/bin/node
# 版本信息
[root@localhost data]# node -v && npm -v
v8.9.4
5.6.0

二、安装fabric

1、下载fabric源码,编译fabric

# 新建存放fabric源码的目录并进入此目录:
mkdir -p $GOPATH/src/github.com/hyperledger
cd $GOPATH/src/github.com/hyperledger

# 1.下载fabric源码,输入命令:git clone https://github.com/hyperledger/fabric
# 找一台可连接外网的机器下载下来,并上传到相对于目录$GOPATH/src/github.com/hyperledger
# 接着下载:git clone https://github.com/hyperledger/fabric-samples.git
# fabric-samples下载完成之后,移动到fabric/scripts/下
# 之后打包fabric并上传对应机器,接着往下做
# 2.查看fabric所有版本,并切换fabric版本
(1)、首先,进入fabric目录,输入命令:cd fabric
(2)、查看版本,输入命令:git tag
(3)、切换版本,用fabric 2.3.2版本,输入命令:git checkout v2.3.2

# 1.编译fabric,输入命令:make release
# 2.编译成功后,进入底下的cmd文件夹,输入命令:cd cmd
# 3.其中discover是服务发现命令,只需要检查另外六个是否安装好,输入以下命令:
../release/linux-amd64/bin/peer version
../release/linux-amd64/bin/orderer version
../release/linux-amd64/bin/configtxgen -version
../release/linux-amd64/bin/configtxlator version
../release/linux-amd64/bin/cryptogen version
../release/linux-amd64/bin/idemixgen version
# 出现版本号为正常
peer:
 Version: 2.3.2
 Commit SHA: 0022e8f
 Go version: go1.15.7
 OS/Arch: linux/amd64
 Chaincode:
  Base Docker Label: org.hyperledger.fabric
  Docker Namespace: hyperledger
  
# 设置环境环境变量或者配置可执行文件,二选一即可
1.设置环境变量
vim /etc/profile
export PATH=$GOPATH/src/github.com/hyperledger/fabric/release/linux-amd64/bin/:$PATH
source /etc/profile
peer version			# 出现版本号为成功
  
  
# 配置可执行文件,并授权
cp $GOPATH/src/github.com/hyperledger/fabric/release/linux-amd64/bin/* /usr/local/bin
chmod -R 775 /usr/local/bin/configtxgen
chmod -R 775 /usr/local/bin/configtxlator
chmod -R 775 /usr/local/bin/cryptogen
chmod -R 775 /usr/local/bin/peer
chmod -R 775 /usr/local/bin/orderer
chmod -R 775 /usr/local/bin/idemixgen
chmod -R 775 /usr/local/bin/discover

2、Fabric镜像下载

进入scripts目录底下,输入命令:
cd $GOPATH/src/github.com/hyperledger/fabric/scripts
镜像下载之前,先添加配置下镜像加速地址,不然下载会很慢
# 输入命令:
# 并输入下面的内容,添加镜像加速地址:
vim /etc/docker/daemon.json
	{
    
    
		"registry-mirrors": ["https://aeckruos.mirror.aliyuncs.com"]
	}
# 保存后,使配置的镜像加速地址生效
ystemctl daemon-reload
systemctl restart docker

# 执行底下的bootstrap.sh脚本文件,输入命令:./bootstrap.sh -b 只下载镜像包 这里下载需要点时间,可能网络延迟,会失败,多执行几遍就好
可通过命令查看所下载的镜像:docker images

# 下载完成之后,打包并上传到相对应机器并导入
打包命令:docker save $(docker images | grep -E 'fabric|couchdb' | awk '{print $1}') -o fabric-images.tar
导入命令:docker load -i fabric-images.tar

3、下载Fabric-ca,编译Fabric-ca-server和Fabirc-ca-client

首先,回到hyperledger那个目录底下,下载fabric-ca源码,命令如下:
cd $GOPATH/src/github.com/hyperledger
git clone https://github.com/hyperledger/fabric-ca
# 找一台可连接外网的机器下载下来,并上传到相对于目录$GOPATH/src/github.com/hyperledger/

# 编译下载的源码,依次输入以下命令:
cd $GOPATH/src/github.com/hyperledger/fabric-ca
make fabric-ca-server && make fabric-ca-client

# 配置编译好的可执行文件,输入以下命令:
cd $GOPATH/src/github.com/hyperledger/fabric-ca/bin
cp * /usr/local/bin/

chmod -R 755 /usr/local/bin/fabric-ca-server
chmod -R 755 /usr/local/bin/fabric-ca-client

# 检查是否可执行:
fabric-ca-server version
# 输出
fabric-ca-server:
 Version: 1.5.1-snapshot-05fe243
 Go version: go1.15.7
 OS/Arch: linux/amd64
fabric-ca-client version
# 输出
fabric-ca-client:
 Version: 1.5.1-snapshot-05fe243
 Go version: go1.15.7
 OS/Arch: linux/amd64
 
# 二选一即可
vim /etc/profile
export PATH=$GOPATH/src/github.com/hyperledger/fabric-ca/bin/:$PATH
source /etc/profile
fabric-ca-server version	# 出现版本号为成功
fabric-ca-client version    # 出现版本号为成功

4、fabric-sdk-go源码下载

# 开发客户端安装golang-sdk,fabric-sdk-go是提供的Go语言开发包,应用程序可以利用fabric-sdk-go与fabric网络进行交互并访问链码
# 找一台可连接外网的机器下载下来,并上传到相对于目录$GOPATH/src/github.com/hyperledger/
# 回到hyperledger那个目录底下,下载fabric-sdk-go源码,命令如下:
cd $GOPATH/src/github.com/hyperledger
git clone https://github.com/hyperledger/fabric-sdk-go

5、测试网络

# 首先,进入fabric/scripts/fabric-samples/test-network目录,命令如下:
cd $GOPATH/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network
# 开始启动测试网络,输入命令:
./network.sh up
# 运行后如下图所示,可以看到出现容器,没出现错误,说明fabric环境已经搭建好了:
# Fabric 2.3.2编译时需要go版本是1.15.7以上的,不然编译会报错。
# 如启动失败,请下载https://github.com/hyperledger/fabric/releases/download/v2.3.2/hyperledger-fabric-linux-amd64-2.3.2.tar.gz
# 下载完毕后解压到fabric-samples目录下

在这里插入图片描述

环境搭建成功!

三、测试网络的组成部分

1.启动网络

# 1.与Fabric网络交互的每个节点和用户都必须属于网络成员的组织(organization)。属于Fabric网络成员的组织群通常称为联盟(consortium)。test network有两个联盟成员,Org1和Org2。该demo还包括维护网络订购服务的一个订购者(orderer)组织。

# Peer节点是任何Fabric网络的基本组成部分。Peer节点存储区块链帐本(ledger)并在将交易提交到分帐之前对其进行验证。Peer节点运行包含业务逻辑的智能合约,该业务逻辑用于管理区块链账本上的资产。
# 检查network.sh脚本创建的节点是否在启动后运行
./network.sh up
docker ps -a

在这里插入图片描述

2.建立通道

# 启动网络后,服务器上运行着Peer节点和Orderer节点,我们可以使用该脚本为Org1和Org2之间的事务创建Fabric通道。通道是特定网络成员之间的专用通信层。通道只能由受邀加入该通道的组织使用,并且对网络的其他成员不可见。每个通道都有一个单独的区块链账本。被邀请的组织将其他组织“加入”通道以存储通道帐本并验证通道上的交易。

在Org1和Org2之间创建通道并将他们的Peer节点加入通道(未指定名称时将使用默认名称:mychannel)
./network.sh createChannel
# 在日志中可以看到
========= Channel successfully joined ===========
# 当然,为了区分不同通道,也可以创建自定义名称的通道(例如:fabricchannel)
./network.sh createChannel -c fabricchannel
# 熟悉test network之后,可以在启动网络时直接创建通道
./network.sh up createChannel

在这里插入图片描述

3.启动合约

# 创建通道后,可以开始使用智能合约与通道账本进行交互。智能合约包含管理区块链账本上资产的业务逻辑。网络成员可以调用智能合约以在账本上创建资产,以及更改和转移这些资产,还可以调用智能合约以查询并读取账本上的数据。
# 在通道上启动智能合约
./network.sh deployCC
# 根据提示执行命令
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

在这里插入图片描述

在这里插入图片描述

5.测试功能

# 启动test network之后,可以使用peer CLI与其进行交互,peer CLI允许用户调用已部署的智能合约,更新通道,安装和部署新的智能合约。
在test-network目录下,将一些二进制文件添加到CLI路径下:
export PATH=${
    
    PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
# 设置环境变量来允许用户以Org1的形式来操作peer CLI:
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
# 通过资产信息来初始化账本
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":[]}'
# 执行后可以看到
-> INFO 001 Chaincode invoke successful. result: status:200
# 现在可以从CLI查询账本
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
# 将看到
[
  {
    
    "ID": "asset1", "color": "blue", "size": 5, "owner": "Tomoko", "appraisedValue": 300},
  {
    
    "ID": "asset2", "color": "red", "size": 5, "owner": "Brad", "appraisedValue": 400},
  {
    
    "ID": "asset3", "color": "green", "size": 10, "owner": "Jin Soo", "appraisedValue": 500},
  {
    
    "ID": "asset4", "color": "yellow", "size": 10, "owner": "Max", "appraisedValue": 600},
  {
    
    "ID": "asset5", "color": "black", "size": 15, "owner": "Adriana", "appraisedValue": 700},
  {
    
    "ID": "asset6", "color": "white", "size": 15, "owner": "Michel", "appraisedValue": 800}
]

在这里插入图片描述

6.转移或更改账上资产的所有者

# asset6所有者改成Christopher
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":"TransferAsset","Args":["asset6","Christopher"]}'
# 将看到
EST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200

在这里插入图片描述

7.org2查询资产

# 之后我们可以使用另一个查询来查看该调用如何更改了账上资产。对Org2进行环境变量的配置
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${
    
    PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${
    
    PWD}/organizations/peerOrganizations/org2.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:9051
# 查询运行在peer0.org2.example.com的资产转移智能合约
peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'
# 也可以看到asset6已经转移到Christopher名下
{
    
    "ID":"asset6","color":"white","size":15,"owner":"Christopher","appraisedValue":800}

在这里插入图片描述

8.关闭网络

# 执行之后会清除容器
./network.sh down

在这里插入图片描述

到此一个简单的Fabric网络测试便完成了

需要相关fabric包的可以私聊我,免费分享。

猜你喜欢

转载自blog.csdn.net/YourMr/article/details/121511139