Hyperledger Fabric无系统通道启动及通道的创建和删除
前言
在Hyperledger Fabric组织的动态添加和删除中,我们已经完成了在运行着的网络中动态添加和删除组织,但目前为止,我们启动 orderer 节点的方式都是通过系统通道的方式,这样自带系统通道的网络很不简洁优雅。好在 Fabric 2.3 以上就开始支持无系统通道创建应用通道的功能,本文将对此功能进行详细解释和介绍,然后通过无系统通道的方式启动联盟链网络并在此基础上完成通道的添加和删除。本实验必要的准备工作和 DNS 配置请参考 准备工作。
背景介绍
实验准备
本文网络结构直接将 Hyperledger Fabric定制联盟链网络工程实践 中创建的 1_3Org2Peer1Orderer1TLS 复制为 3_RunWithNoSystemChannel (建议直接将本案例仓库 FabricLearn 下的 3_RunWithNoSystemChannel 目录拷贝到本地运行)。默认情况下,所有命令皆在 3_RunWithNoSystemChannel 根目录下执行,在开始后面的实验前按照以下命令启动基础实验网络:
- 设置环境变量
source envpeer1soft - 启动CA网络
./0_Restart.sh - 注册用户
./1_RegisterUser.sh - 构造证书
./2_EnrollUser.sh
本实验初始 docker 网络为:

本文工作
以无系统通道的方式启动 Hyperledger Fabric 网络,然后先用 configtxgen 工具创建新通道 mychannel 和 testchannel ,并使用 osnadmin 工具通过 orderer 的 admin 服务使 orderer 加入这两条通道(实验代码已上传至:https://github.com/wefantasy/FabricLearn 的 3_RunWithNoSystemChannel 下)[1]:
| 项 | 运行端口 | 说明 |
|---|---|---|
council.ifantasy.net |
7050 | council 组织的 CA 服务, 为联盟链网络提供 TLS-CA 服务 |
orderer.ifantasy.net |
7150 | orderer 组织的 CA 服务, 为联盟链网络提供排序服务 |
orderer1.orderer.ifantasy.net |
7151 | orderer 组织的排序服务 |
orderer1.orderer.ifantasy.net |
7152 | orderer 组织的 ADMIN 服务 |
soft.ifantasy.net |
7250 | soft 组织的 CA 服务, 包含成员: peer1 、 admin1 |
peer1.soft.ifantasy.net |
7251 | soft 组织的 peer1 成员节点 |
web.ifantasy.net |
7350 | web 组织的 CA 服务, 包含成员: peer1 、 admin1 |
peer1.web.ifantasy.net |
7351 | web 组织的 peer1 成员节点 |
无系统通道启动
- 修改
compose/docker-base.yaml中orderer-base内容为:
orderer-base:
image: hyperledger/fabric-orderer:${FABRIC_BASE_VERSION}
environment:
- ORDERER_HOME=${DOCKER_CA_PATH}/orderer
- ORDERER_GENERAL_LISTENPORT=7777
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_BOOTSTRAPMETHOD=none
- ORDERER_CHANNELPARTICIPATION_ENABLED=true
# - ORDERER_GENERAL_GENESISMETHOD=file
# - ORDERER_GENERAL_GENESISFILE=${DOCKER_CA_PATH}/orderer/genesis.block
- ORDERER_GENERAL_LOCALMSPDIR=${DOCKER_CA_PATH}/orderer/msp
- ORDERER_GENERAL_LOGLEVEL=debug
- ORDERER_GENERAL_TLS_ENABLED=true
- ORDERER_GENERAL_TLS_CERTIFICATE=${DOCKER_CA_PATH}/orderer/tls-msp/signcerts/cert.pem
- ORDERER_GENERAL_TLS_PRIVATEKEY=${DOCKER_CA_PATH}/orderer/tls-msp/keystore/key.pem
- ORDERER_GENERAL_TLS_ROOTCAS=[${DOCKER_CA_PATH}/orderer/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem]
- ORDERER_ADMIN_TLS_ENABLED=true
- ORDERER_ADMIN_TLS_CERTIFICATE=${DOCKER_CA_PATH}/orderer/tls-msp/signcerts/cert.pem
- ORDERER_ADMIN_TLS_PRIVATEKEY=${DOCKER_CA_PATH}/orderer/tls-msp/keystore/key.pem
- ORDERER_ADMIN_TLS_ROOTCAS=[${DOCKER_CA_PATH}/orderer/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem]
- ORDERER_ADMIN_TLS_CLIENTROOTCAS=[${DOCKER_CA_PATH}/orderer/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem]
- ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:8888
- ORDERER_METRICS_PROVIDER=prometheus
- ORDERER_OPERATIONS_LISTENADDRESS=0.0.0.0:9999
- ORDERER_DEBUG_BROADCASTTRACEDIR=data/logs
networks:
- ${DOCKER_NETWORKS}
相比源文件主要修改如下:
ORDERER_GENERAL_GENESISMETHOD:将启动方式改为noneORDERER_CHANNELPARTICIPATION_ENABLED:无系统通道启动,该字段必须设置为 true- 添加
ORDERER_ADMIN_TLS_*相关设置, 后续排序节点使用osnadmin加入通道依赖于配置, 它的服务和证书与ORDERER独立,可以选择其他的证书。
- 修改
compose/docker-compose.yaml中orderer-base内容为:
orderer1.orderer.ifantasy.net:
container_name: orderer1.orderer.ifantasy.net
extends:
file: docker-base.yaml
service: orderer-base
environment:
- ORDERER_HOST=orderer1.orderer.ifantasy.net
- ORDERER_GENERAL_LOCALMSPID=ordererMSP
volumes:
- ${LOCAL_CA_PATH}/orderer.ifantasy.net/registers/orderer1:${DOCKER_CA_PATH}/orderer
# - ${LOCAL_ROOT_PATH}/data/genesis.block:${DOCKER_CA_PATH}/orderer/genesis.block
ports:
- 7151:7777
- 7152:8888
- 7153:9999
相比源文件,主要添加了 ADMIN 、 ORDERER_OPERATIONS_LISTENADDRESS 的端口监听。
- 在
envpeer1soft中添加ORDERER ADMIN的环境变量:
export ORDERER_CA=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem
export ORDERER_ADMIN_TLS_SIGN_CERT=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/signcerts/cert.pem
export ORDERER_ADMIN_TLS_PRIVATE_KEY=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/keystore/key.pem
- 无系统通道启动
orderer和peer节点:
docker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d peer1.soft.ifantasy.net peer1.web.ifantasy.net orderer1.orderer.ifantasy.net
无系统通道启动成功后的容器环境:

新建通道
新建通道文件
接下来我们将创建两个通道,它们分别是 mychannel 和 testchannel :
configtxgen -profile OrgsChannel -outputCreateChannelTx $LOCAL_ROOT_PATH/data/mychannel.tx -channelID mychannel
configtxgen -profile OrgsChannel -outputBlock $LOCAL_ROOT_PATH/data/mychannel.block -channelID mychannel
configtxgen -profile OrgsChannel -outputCreateChannelTx $LOCAL_ROOT_PATH/data/testchannel.tx -channelID testchannel
configtxgen -profile OrgsChannel -outputBlock $LOCAL_ROOT_PATH/data/testchannel.block -channelID testchannel
在上面我们同时使用了 -outputCreateChannelTx 和 -outputBlock 参数创建了两个通道的 tx 文件和 block 文件,其中 block 文件为加入通道时所使用的创世区块文件,可以由对应的 tx 文件计算而来。
排序节点加入通道
在排序节点加入通道前,我们可以使用以下命令查看当前的通道:
source envpeer1soft
osnadmin channel list -o orderer1.orderer.ifantasy.net:7152 --ca-file $ORDERER_CA --client-cert $ORDERER_ADMIN_TLS_SIGN_CERT --client-key $ORDERER_ADMIN_TLS_PRIVATE_KEY

这里的参数 ORDERER_CA 、 ORDERER_ADMIN_TLS_SIGN_CERT 、 ORDERER_ADMIN_TLS_PRIVATE_KEY 必须与上面 compose/docker-base.yaml 中的 ORDERER_ADMIN_TLS_* 相关证书文件一致。端口必须与 ORDERER_ADMIN_LISTENADDRESS 一致,否则可能会出现以下错误:
error: Get "https://orderer1.orderer.ifantasy.net:7151/participation/v1/channels": net/http: HTTP/1.x transport connection broken: malformed HTTP response "\x00\x00\x06\x04\x00\x00\x00\x00\x00\x00\x05\x00\x00@\x00"
如果没有报错,可以使用 osnadmin channel join 根据创世区块加入通道:
osnadmin channel join --channelID mychannel --config-block $LOCAL_ROOT_PATH/data/mychannel.block -o orderer1.orderer.ifantasy.net:7152 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"
osnadmin channel join --channelID testchannel --config-block $LOCAL_ROOT_PATH/data/testchannel.block -o orderer1.orderer.ifantasy.net:7152 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"

这里 --config-block 指向的文件必须为 block 文件,否则可能会出现错误:
osnadmin: error: parsing arguments: failed to retrieve channel id - block is empty. Try --help
所有工作完成后,可以再次使用 osnadmin channel list 命令查看已加入的通道:

节点加入通道
节点加入通道只需要能访问通道对应的 block 创世区块文件即可,为了方便管理,我们先将创世区块复制到各组织的公共资产目录下:
cp $LOCAL_ROOT_PATH/data/mychannel.block $LOCAL_CA_PATH/soft.ifantasy.net/assets/
cp $LOCAL_ROOT_PATH/data/mychannel.block $LOCAL_CA_PATH/web.ifantasy.net/assets/
cp $LOCAL_ROOT_PATH/data/testchannel.block $LOCAL_CA_PATH/soft.ifantasy.net/assets/
cp $LOCAL_ROOT_PATH/data/testchannel.block $LOCAL_CA_PATH/web.ifantasy.net/assets/
现在使 soft 组织的 peer 节点加入创建的两个通道:
source envpeer1soft
peer channel join -b $LOCAL_CA_PATH/soft.ifantasy.net/assets/mychannel.block
peer channel join -b $LOCAL_CA_PATH/soft.ifantasy.net/assets/testchannel.block
peer channel list

然后使 soft 组织的 peer 节点加入创建的两个通道:
source envpeer1web
peer channel join -b $LOCAL_CA_PATH/web.ifantasy.net/assets/mychannel.block
peer channel join -b $LOCAL_CA_PATH/web.ifantasy.net/assets/testchannel.block
peer channel list

安装链码到指定通道
现在我们的网络中有 soft 和 web 两个组织,每个组织有个 peer1 节点,每个节点都加入了 mychannel 和 testchannel 两个通道,如果想将链码安装到 testchannel 通道,只需要按以下流程:
- 两个组织分别安装链码:
source envpeer1soft
# peer lifecycle chaincode package basic.tar.gz --path asset-transfer-basic/chaincode-go --label basic_1
peer lifecycle chaincode install basic.tar.gz
peer lifecycle chaincode queryinstalled
source envpeer1web
peer lifecycle chaincode install basic.tar.gz
peer lifecycle chaincode queryinstalled
export CHAINCODE_ID=basic_1:06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718

由于本项目是从 Hyperledger Fabric定制联盟链网络工程实践 中复制而来,所以这里直接安装该实验中打包过的链码 basic.tar.gz ,并且设置 CHAINCODE_ID 为链码安装后的 ID 。在安装时不必指定具体通道,因为安装行为是针对节点而非通道,即 将节点安装到 peer 节点。
- 两个组织分别批准链码:
source envpeer1soft
peer lifecycle chaincode approveformyorg -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --version 1.0 --sequence 1 --waitForEvent --init-required --package-id $CHAINCODE_ID
peer lifecycle chaincode queryapproved -C testchannel -n basic --sequence 1
source envpeer1web
peer lifecycle chaincode approveformyorg -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --version 1.0 --sequence 1 --waitForEvent --init-required --package-id $CHAINCODE_ID
peer lifecycle chaincode queryapproved -C testchannel -n basic --sequence 1
若想将链码安装到 testchannel 通道上,只需要在批准链码时指定 --channelID 为 testchannel 即可。此时已可以在 testchannel 上查看到链码批准情况:

- web 组织提交链码:
source envpeer1web
peer lifecycle chaincode commit -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --init-required --version 1.0 --sequence 1 --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE
peer chaincode invoke --isInit -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE -c '{"Args":["InitLedger"]}'

4. 初始化并调用链码:
peer chaincode invoke --isInit -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE -c '{"Args":["InitLedger"]}'
sleep 5
peer chaincode invoke -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE -c '{"Args":["GetAllAssets"]}'

删除通道
区块链的不可篡改性注定了我们无法从网络上删除通道,只能将新数据(正常事务或配置更新)附加到区块链网络[2]。到现在我们已经讨论过了组织、节点及通道的添加和删除方式,发现 Fabric 联盟链通常对删除操作并没有提供支持。
参考
yuan1028. fabric 2.3系统通道. 简书. [2021-01-21] ︎
JACOB WILSON. How do you delete a channel on Hyperledger fabric?. it-qa.com. [2019-04-05] ︎
Hyperledger Fabric无系统通道启动及通道的创建和删除的更多相关文章
- Hyperledger Fabric无排序组织以Raft共识算法启动多个Orderer服务、多组织共同运行维护Orderer服务
前言 在Hyperledger Fabric无系统通道启动及通道的创建和删除中,我们已经完成了以无系统通道的方式启动 Hyperledger Fabric 网络,并将链码安装到指定通道.但目前为止,实 ...
- Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务、TLS组织运行维护Orderer服务
前言 在实验Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务.多组织共同运行维护Orderer服务中,我们已经完成了让普通组织运行维护 Orderer 服务,但是 ...
- Hyperledger Fabric(v1.2.0)代码分析1——channel创建
Hyperledger Fabric(v1.2.0)代码分析1--channel创建 0. e2e_cli Hyperledger Fabric提供了一个e2e的例子,该例中创建了一个基础的区块链网络 ...
- Hyperledger Fabric 1.0 学习搭建 (四)--- 创建Fabric多节点集群
4.1.配置说明 首先可以根据官方Fabric自带的e2e_cli列子中的集群方案来生成我们自己的集群,与案例不同的是我们需要把容器都分配到不同的服务器上,彼此之间通过网络来进行通信,网络构建完成后则 ...
- 深入解析Hyperledger Fabric启动的全过程
在这篇文章中,使用fabric-samples/first-network中的文件进行fabric网络(solo类型的网络)启动全过程的解析.如有错误欢迎批评指正. 至于Fabric网络的搭建这里不再 ...
- 安装hyperledger fabric V1.0.1
安装文档位置: https://github.com/hyperledger/fabric fabric代码托管地址 https://hyperledger-fabric.readthedoc ...
- Hyperledger Fabric 部署在多个主机上
前言 在实验Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务.TLS组织运行维护Orderer服务中,我们已经完成了使用提供 TLS-CA 服务的 council ...
- Hyperledger Fabric 智能合约开发及 fabric-sdk-go/fabric-gateway 使用示例
前言 在上个实验 Hyperledger Fabric 多组织多排序节点部署在多个主机上 中,我们已经实现了多组织多排序节点部署在多个主机上,但到目前为止,我们所有的实验都只是研究了联盟链的网络配置方 ...
- 第6章 Hyperledger Fabric模型
This section outlines the key design features woven into Hyperledger Fabric that fulfill its promise ...
随机推荐
- 一文让你明白CPU上下文切换
我们都知道,Linux 是一个多任务操作系统,它支持远大于 CPU 数量的任务同时运行.当然,这些任务实际上并不是真的在同时运行,而是因为系统在很短的时间内,将 CPU 轮流分配给它们,造成多任务同时 ...
- 用注册表清除Office Word文档杀手病毒
不久前,笔者打开word文件时遇到了一件离奇的怪事,常用的Word文件怎么也打不开,总是出现提示框:"版本冲突:无法打开高版本的word文档".再仔细查看,文件夹里竟然有两个名字一 ...
- Linux 环境下安装 Nexus 私服存储库
镜像下载.域名解析.时间同步请点击阿里云开源镜像站 一.nexus私服存储库简介 Nexus 是一个强大的maven仓库管理器,它极大地简化了本地内部仓库的维护和外部仓库的访问.,还可以用来创建yum ...
- Ubuntu20安装nodejs和npm并切换阿里源
参考 阿里巴巴开源镜像站 Ubuntu20安装npm并切换阿里源 安装直接在终端执行 sudo apt-get install nodejs npm没有安装上就执行 sudo apt-get inst ...
- cute
环境准备 将靶机导入后将网络设置为NAT kali:192.168.0.102 cute:192.168.0.107 端口扫描 使用nmap对靶机进行端口扫描 nmap –A –p- 192.168. ...
- x64 番外篇——知识铺垫
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...
- java常见字节大小存储问题
JAVA中默认的编码方式 转:http://blog.csdn.net/scyatcs/article/details/31356823 编码问题存在两个方面:JVM之内和JVM之外.1.Java文件 ...
- BLOB 和 TEXT 有什么区别?
BLOB 是一个二进制对象,可以容纳可变数量的数据.TEXT 是一个不区分大小写 的 BLOB. BLOB 和 TEXT 类型之间的唯一区别在于对 BLOB 值进行排序和比较时区分大小 写,对 TEX ...
- 为什么使用 Executor 框架?
每次执行任务创建线程 new Thread()比较消耗性能,创建一个线程是比较耗时. 耗资源的. 调用 new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建, 线程之间的相互 ...
- Zookeeper 的典型应用场景 ?
Zookeeper 是一个典型的发布/订阅模式的分布式数据管理与协调框架,开发人员 可以使用它来进行分布式数据的发布和订阅. 通过对 Zookeeper 中丰富的数据节点进行交叉使用,配合 Watch ...