前言

Fabric定制联盟链网络工程实践中,我们虚拟了一个工作室的联盟链网络需求,并根据此需求分析了整个网络的架构且已经完成了一个简单 fabric 网络模型。本文将在其基础上,在 mychannel 通道上添加新的 hard 组织,并在之后删除 soft 组织,本实验必要的准备工作和 DNS 配置请参考 准备工作

背景介绍

实验准备

本节网络架构基于 Fabric定制联盟链网络工程实践 ,将项目中 1_3Org2Peer1Orderer1TLS 复制为 2_FabricNetworkUpdate 并进入目录(建议直接将本案例仓库 FabricLearn 下的 2_FabricNetworkUpdate 目录拷贝到本地运行),本文默认情况下,所有命令皆在 2_FabricNetworkUpdate 根目录下执行。按照以下命令启动基础网络:

  1. 设置环境变量 source envpeer1soft
  2. 启动CA网络 ./0_Restart.sh
  3. 注册用户 ./1_RegisterUser.sh
  4. 构造证书 ./2_EnrollUser.sh
  5. 配置通道 ./3_Configtxgen.sh
  6. 安装测试链码 ./4_TestChaincode.sh

本实验初始 docker 网络为:

本实验初始区块高度为6:

本文工作

本实验中向 Hyperledger Fabric 网络动态添加一个新组织 hard ,其包含一个组织节点 peer1 ,网络结构为(实验代码已上传至:https://github.com/wefantasy/FabricLearn2_FabricNetworkUpdate 下)[1]

运行端口 说明
council.ifantasy.net 7050 council 组织的 CA 服务, 为联盟链网络提供 TLS-CA 服务
orderer.ifantasy.net 7150 orderer 组织的 CA 服务, 为联盟链网络提供排序服务
orderer1.orderer.ifantasy.net 7151 orderer 组织的 orderer1 成员节点
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 成员节点
hard.ifantasy.net 7450 hard 组织的 CA 服务, 包含成员: peer1 、 admin1
peer1.hard.ifantasy.net 7451 hard 组织的 peer1 成员节点

添加新组织

本节将演示在基础网络中添加一个新组织——hard(硬件组)[1:1]

生成hard组织证书

在测试中我们可以简单的通过 cryptogen 来创建hard组织的所有证书,其具体方法不在赘述,本文将仍使用 fabric-ca 的形式创建 hard 组织所有证书。

  1. compose/docker-compose.yaml 中添加 hard 的 CA 服务:
  1. hard.ifantasy.net:
  2. container_name: hard.ifantasy.net
  3. extends:
  4. file: docker-base.yaml
  5. service: ca-base
  6. command: sh -c 'fabric-ca-server start -d -b ca-admin:ca-adminpw --port 7050'
  7. environment:
  8. - FABRIC_CA_SERVER_CSR_CN=hard.ifantasy.net
  9. - FABRIC_CA_SERVER_CSR_HOSTS=hard.ifantasy.net
  10. volumes:
  11. - ${LOCAL_CA_PATH}/hard.ifantasy.net/ca:${DOCKER_CA_PATH}/ca
  12. ports:
  13. - 7450:7050
  1. 启动 hard 的 CA 服务
  1. docker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d hard.ifantasy.net
  1. 注册 hard 的组织账号:
  1. echo "Working on tls"
  2. export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH//ca/crypto/ca-cert.pem
  3. export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH//ca/admin
  4. fabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@:7050
  5. fabric-ca-client register -d --id.name peer1hard --id.secret peer1hard --id.type orderer -u https://:7050
  6. echo "Working on hard"
  7. export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/hard.ifantasy.net/ca/crypto/ca-cert.pem
  8. export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/hard.ifantasy.net/ca/admin
  9. fabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@hard.ifantasy.net:7450
  10. fabric-ca-client register -d --id.name peer1 --id.secret peer1 --id.type peer -u https://hard.ifantasy.net:7450
  11. fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u https://hard.ifantasy.net:7450
  1. 配置 hard 的组织证书:
  1. echo "Preparation============================="
  2. mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/assets
  3. cp $LOCAL_CA_PATH/hard.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/assets/ca-cert.pem
  4. cp $LOCAL_CA_PATH//ca/crypto/ca-cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/assets/tls-ca-cert.pem
  5. echo "Preparation============================="
  6. echo "Enroll Admin"
  7. export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1
  8. export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/hard.ifantasy.net/assets/ca-cert.pem
  9. export FABRIC_CA_CLIENT_MSPDIR=msp
  10. fabric-ca-client enroll -d -u https://admin1:admin1@hard.ifantasy.net:7450
  11. mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp/admincerts
  12. cp $LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp/admincerts/cert.pem
  13. echo "Enroll Peer1"
  14. export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/hard.ifantasy.net/registers/peer1
  15. export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/hard.ifantasy.net/assets/ca-cert.pem
  16. export FABRIC_CA_CLIENT_MSPDIR=msp
  17. fabric-ca-client enroll -d -u https://peer1:peer1@hard.ifantasy.net:7450
  18. # for TLS
  19. export FABRIC_CA_CLIENT_MSPDIR=tls-msp
  20. export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/hard.ifantasy.net/assets/tls-ca-cert.pem
  21. fabric-ca-client enroll -d -u https://peer1hard:peer1hard@:7050 --enrollment.profile tls --csr.hosts peer1.hard.ifantasy.net
  22. cp $LOCAL_CA_PATH/hard.ifantasy.net/registers/peer1/tls-msp/keystore/*_sk $LOCAL_CA_PATH/hard.ifantasy.net/registers/peer1/tls-msp/keystore/key.pem
  23. mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/registers/peer1/msp/admincerts
  24. cp $LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/registers/peer1/msp/admincerts/cert.pem
  25. mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/msp/admincerts
  26. mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/msp/cacerts
  27. mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/msp/tlscacerts
  28. mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/msp/users
  29. cp $LOCAL_CA_PATH/hard.ifantasy.net/assets/ca-cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/msp/cacerts/
  30. cp $LOCAL_CA_PATH/hard.ifantasy.net/assets/tls-ca-cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/msp/tlscacerts/
  31. cp $LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/msp/admincerts/cert.pem
  32. cp $LOCAL_ROOT_PATH/config/config-msp.yaml $LOCAL_CA_PATH/hard.ifantasy.net/msp/config.yaml
  33. echo "End hard============================="
  1. compose/docker-compose.yaml 中添加 hard 的 peer 服务:
  1. peer1.hard.ifantasy.net:
  2. container_name: peer1.hard.ifantasy.net
  3. extends:
  4. file: docker-base.yaml
  5. service: peer-base
  6. environment:
  7. - CORE_PEER_ID=peer1.hard.ifantasy.net
  8. - CORE_PEER_ADDRESS=peer1.hard.ifantasy.net:7051
  9. - CORE_PEER_LOCALMSPID=hardMSP
  10. - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.hard.ifantasy.net:7051
  11. volumes:
  12. - ${LOCAL_CA_PATH}/hard.ifantasy.net/registers/peer1:${DOCKER_CA_PATH}/peer
  13. ports:
  14. - 7451:7051
  1. 启动 hard 的 peer1 节点:
  1. docker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d peer1.hard.ifantasy.net

此时所有容器如下:

  1. (base) root@DebianA:2_FabricNetworkUpdate# peer channel getinfo -c mychannel
  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3. df4642a0bf08 hyperledger/fabric-peer:2.4 "peer node start" About a minute ago Up About a minute 0.0.0.0:7451->7051/tcp peer1.hard.ifantasy.net
  4. d78d1b2cbaf3 hyperledger/fabric-ca:1.5 "sh -c 'fabric-ca-se…" 3 minutes ago Up 3 minutes 7054/tcp, 0.0.0.0:7450->7050/tcp hard.ifantasy.net
  5. 391fa186b804 dev-peer1.soft.ifantasy.net-basic_1-06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718-179d27e486b248e3bc94f5930c2c5260638efbd88263aed0ba6f76d9751bfddf "chaincode -peer.add…" 4 minutes ago Up 4 minutes dev-peer1.soft.ifantasy.net-basic_1-06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718
  6. 36af7b3c199a dev-peer1.web.ifantasy.net-basic_1-06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718-00e8af11004dcf6072478c9cb2633162b9675406392cbe9064feb13b007ea39e "chaincode -peer.add…" 4 minutes ago Up 4 minutes dev-peer1.web.ifantasy.net-basic_1-06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718
  7. 98427d7781e7 hyperledger/fabric-peer:2.4 "peer node start" 5 minutes ago Up 5 minutes 0.0.0.0:7351->7051/tcp peer1.web.ifantasy.net
  8. 117d9e5f6bd2 hyperledger/fabric-orderer:2.4 "orderer" 5 minutes ago Up 5 minutes 7050/tcp, 0.0.0.0:7151->7777/tcp orderer1.orderer.ifantasy.net
  9. 0f41245b6b73 hyperledger/fabric-peer:2.4 "peer node start" 5 minutes ago Up 5 minutes 0.0.0.0:7251->7051/tcp peer1.soft.ifantasy.net
  10. c22772b88471 hyperledger/fabric-ca:1.5 "sh -c 'fabric-ca-se…" 5 minutes ago Up 5 minutes 7054/tcp, 0.0.0.0:7150->7050/tcp orderer.ifantasy.net
  11. 69af68afd2ed hyperledger/fabric-ca:1.5 "sh -c 'fabric-ca-se…" 5 minutes ago Up 5 minutes 7054/tcp, 0.0.0.0:7350->7050/tcp web.ifantasy.net
  12. 6398c8406524 hyperledger/fabric-ca:1.5 "sh -c 'fabric-ca-se…" 5 minutes ago Up 5 minutes 7054/tcp, 0.0.0.0:7250->7050/tcp soft.ifantasy.net
  13. d0d2ddc99a82 hyperledger/fabric-ca:1.5 "sh -c 'fabric-ca-se…" 5 minutes ago Up 5 minutes 0.0.0.0:7050->7050/tcp, 7054/tcp
  1. 创建 hard 的 peer1 的环境变量文件 envpeer1hard
  1. export LOCAL_ROOT_PATH=$PWD
  2. export LOCAL_CA_PATH=$LOCAL_ROOT_PATH/orgs
  3. export DOCKER_CA_PATH=/tmp
  4. export COMPOSE_PROJECT_NAME=fabriclearn
  5. export DOCKER_NETWORKS=network
  6. export FABRIC_BASE_VERSION=2.4
  7. export FABRIC_CA_VERSION=1.5
  8. echo "init terminal hard"
  9. export FABRIC_CFG_PATH=$LOCAL_ROOT_PATH/config
  10. export CORE_PEER_TLS_ENABLED=true
  11. export CORE_PEER_LOCALMSPID="hardMSP"
  12. export CORE_PEER_ADDRESS=peer1.hard.ifantasy.net:7451
  13. export CORE_PEER_TLS_ROOTCERT_FILE=$LOCAL_CA_PATH/hard.ifantasy.net/assets/tls-ca-cert.pem
  14. export CORE_PEER_MSPCONFIGPATH=$LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp
  15. export ORDERER_CA=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/tlscacerts/tls--7050.pem

获取通道最新配置

在 fabric 中,通道配置内容是版本化的,这种配置可以在保证了并行性的同时防止通道配置更新被重放攻击。在以上流程我们已经生成了 hard 组织的所有需要的证书,但因为 hard 组织还不是通道 mychannel 的成员,所以我们需要通过另一个已在 mychannel 组织的管理员来获取通道配置(比如 soft 或者 web)。假如通过 soft 组织管理员来获取通道最新配置:

  1. source envpeer1soft
  2. peer channel fetch config update/config_block.pb -o orderer1.orderer.ifantasy.net:7151 -c mychannel --tls --cafile $ORDERER_CA

以上命令将通道配置区块以二进制 protobuf 形式保存在 config_block.pb 中,输出文件的名字和扩展名尽管可以任意指定,然后可以在命令行中看到以下日志:

  1. 2022-04-04 15:22:48.759 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
  2. 2022-04-04 15:22:48.761 CST 0002 INFO [cli.common] readBlock -> Received block: 5
  3. 2022-04-04 15:22:48.761 CST 0003 INFO [channelCmd] fetch -> Retrieving last config block: 0
  4. 2022-04-04 15:22:48.762 CST 0004 INFO [cli.common] readBlock -> Received block: 0

因为我们在创建 mychannel 后并没有进行任何的通道更新操作,所以目前最新 mychannel 的配置区块是初始区块 0,在更新一次后的下一节中我们会发现获取的配置区块不再是0。

转换配置格式并简化

现在可以用 configtxlator 工具将这个通道配置解码为 JSON 格式(以便被友好地阅读和修改),然后使用 jq 工具裁剪其头部、元数据、创建者签名等所有和增加组织无关的内容:

  1. configtxlator proto_decode --input update/config_block.pb --type common.Block | jq .data.data[0].payload.data.config > update/config.json

添加通道hard配置

接下来我们需要通过 configtxgen 生成 hard 组织的定义, configtxgen 的输出取决于配置文件 configtx.yaml 的内容,该文件的路径由环境变量 FABRIC_CFG_PATH 指定。在 config/configtx.yaml 内增加 hard 的组织定义:

然后使用命令生成hard组织定义文件:

  1. configtxgen -printOrg hardMSP > $LOCAL_CA_PATH/hard.ifantasy.net/hard.json

上面的命令会创建一个 hard.json 文件并将其写入到$LOCAL_CA_PATH/hard.ifantasy.net/文件夹下,后面将通过把该文件附加到 mychannel 通道配置中来实现将 hard 添加到通道中,该文件包含了 hard 组织的策略定义和三个 base64 格式的重要证书:

  • 组织根证书, 用于建立组织的根信任
  • TLS 根证书, 用于在 gossip 协议中识别 hard 组织的区块传播和服务发现
  • 管理员用户证书

接下来再次使用 jq 工具去追加 hard 的配置定义 hard.json 到通道的应用组字段,并将结果输出到文件 modified_config.json

  1. jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"hardMSP":.[1]}}}}}' update/config.json $LOCAL_CA_PATH/hard.ifantasy.net/hard.json > update/modified_config.json

现在, 我们已经获取了两个重要的 JSON 文件: config.jsonmodified_config.json 。通道初始配置 config.json 包含 soft 和 web 组织,而 modified_config.json 文件则包含了所有3个组织,之后则需要将这 2 个 JSON 文件重新编码并计算出差异部分。

首先,将 config.json 文件倒回到 protobuf 格式并输出到 config.pb

  1. configtxlator proto_encode --input update/config.json --type common.Config --output update/config.pb

其次,将 modified_config.json 编码成 modified_config.pb

  1. configtxlator proto_encode --input update/modified_config.json --type common.Config --output update/modified_config.pb

然后,使用 configtxlator 去计算两个 protobuf 配置的差异,并将输出的 protobuf 内容写入hard_update.pb :

  1. configtxlator compute_update --channel_id mychannel --original update/config.pb --updated update/modified_config.pb --output update/hard_update.pb

再次,我们将这个文件解码成可编辑的JSON 格式,并命名为 hard_update.json

  1. configtxlator proto_decode --input update/hard_update.pb --type common.ConfigUpdate | jq . > update/hard_update.json

之后,我们需要用信封消息来包装解码后的更新文件 hard_update.json ,这个步骤要把之前裁剪掉的头部信息还原回来,将这个文件命名为hard_update_in_envelope.json

  1. echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat update/hard_update.json)'}}}' | jq . > update/hard_update_in_envelope.json

最后,使用 configtxlator 工具将格式化好的 hard_update_in_envelope.json 转换为Fabric需要的 protobuf 格式的文件hard_update_in_envelope.pb

  1. configtxlator proto_encode --input update/hard_update_in_envelope.json --type common.Envelope --output update/hard_update_in_envelope.pb

签名并提交配置更新

我们在通道创世区块配置 configtx.yaml 中的通道应用组的修改策略设置是 MAJORITY ,因此我们需要已经存在于通道的大部分组织管理员去签名这个更新。而目前 mychannel 中只有两个组织—— soft 和 web ,所以需要两个组织都签名才能成功修改,否则排序服务会因为不满足策略而拒绝这个交易。签名并提交配置更新的流程如下:

  1. soft 管理员来签名这个通道更新:
  1. source envpeer1soft
  2. peer channel signconfigtx -f update/hard_update_in_envelope.pb
  1. web 管理员签名并提交通道更新(由于提交更新命令 peer channel update 会自动附带提交者的签名,所以可直接提交通道更新):
  1. source envpeer1web
  2. peer channel update -f update/hard_update_in_envelope.pb -c mychannel -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA

成功的通道更新调用会创建一个新的区块——区块7,并将其同步给所有在这个通道上的peer节点,此时通道 mychannel 的区块高度增加1:

  1. (base) root@DebianA:2_FabricNetworkUpdate# peer channel getinfo -c mychannel
  2. 2022-04-04 16:26:08.000 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
  3. Blockchain info: {"height":7,"currentBlockHash":"xDbfklqBLaaQ2x8L1omHKedmiQWibbDto6X9ED700pg=","previousBlockHash":"7ZN2T3iTtuWet26UQU4br9ZgrEu6927+/AOjhGELgKw="}

将hard组织加入通道

经过以上步骤后, mychannel 通道的配置已经更新并包含了 hard 组织,现在只需要让 hard 的 peer 节点主动加入并同步区块最新数据即可。 peer 拉取 mychannel 创世区块:

  1. source envpeer1hard
  2. peer channel fetch 0 mychannel.block -o orderer1.orderer.ifantasy.net:7151 -c mychannel --tls --cafile $ORDERER_CA

注意,这里的0表示我们想要拉取的区块高度——即创世区块,如果简单地执行peer channel fetch config命令会拉取最新的带有 hard 组织定义的区块——区块7, 但是任何一个账本都不能从一个下游区块开始记录,因此必须为0

如果成功,该命令将创世块返回到名为 mychannel.block 的文件,然后便可以使用使用 peer 通过这个区块连接到通道:

  1. peer channel join -b mychannel.block

以上命令执行完毕后,查看当前块高度为7:

  1. (base) root@DebianA:2_FabricNetworkUpdate# source envpeer1web
  2. (base) root@DebianA:2_FabricNetworkUpdate# peer channel getinfo -c mychannel
  3. 2022-04-04 20:28:54.457 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
  4. Blockchain info: {"height":7,"currentBlockHash":"UErIVVGNUXWW0g0EPE3t0PQnwVdc/GyXAjsotCpqgjQ=","previousBlockHash":"+ZrOH83va6XWuRttUKhRaeNAeV1CyNjkRiQlZbb/0lg="}

删除旧组织

本节将演示在上节网络中删除一个旧组织——soft(软件组)[2]

获取通道最新配置

通过 web 组织管理员来获取通道最新配置:

  1. source envpeer1web
  2. peer channel fetch config update/config_block.pb -o orderer1.orderer.ifantasy.net:7151 -c mychannel --tls --cafile $ORDERER_CA

以上命令将通道配置区块以二进制 protobuf 形式保存在 config_block.pb 中,输出文件的名字和扩展名尽管可以任意指定,然后可以在命令行中看到以下日志:

  1. (base) root@DebianA:2_FabricNetworkUpdate# peer channel fetch config update/config_block.pb -o orderer1.orderer.ifantasy.net:7151 -c mychannel --tls --cafile $ORDERER_CA
  2. 2022-04-04 16:59:42.952 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
  3. 2022-04-04 16:59:42.954 CST 0002 INFO [cli.common] readBlock -> Received block: 6
  4. 2022-04-04 16:59:42.954 CST 0003 INFO [channelCmd] fetch -> Retrieving last config block: 6
  5. 2022-04-04 16:59:42.961 CST 0004 INFO [cli.common] readBlock -> Received block: 6

转换配置格式并简化

configtxlator 工具将这个通道配置解码为 JSON 格式(以便被友好地阅读和修改),然后使用 jq 工具裁剪其头部、元数据、创建者签名等所有和删除组织无关的内容:

  1. configtxlator proto_decode --input update/config_block.pb --type common.Block | jq .data.data[0].payload.data.config > update/config.json

删除通道soft配置

  1. 使用 jq 工具去追加 soft 的删除命令并写入 modified_config.json
  1. jq 'del(.channel_group.groups.Application.groups.softMSP)' update/config.json > update/modified_config.json

其中,通道原始配置 config.json 包含全部3个组织,而 modified_config.json 文件则只包含2个组织 web 和 hard,之后需要将这 2 个 JSON 文件重新编码并计算出差异部分。

  1. config.json 文件倒回到 protobuf 格式并输出到 config.pb
  1. configtxlator proto_encode --input update/config.json --type common.Config --output update/config.pb
  1. modified_config.json 编码成 modified_config.pb
  1. configtxlator proto_encode --input update/modified_config.json --type common.Config --output update/modified_config.pb
  1. 使用 configtxlator 去计算两个 protobuf 配置的差异,并将输出的 protobuf 内容写入 soft_update.pb
  1. configtxlator compute_update --channel_id mychannel --original update/config.pb --updated update/modified_config.pb --output update/soft_update.pb
  1. 将这个文件解码成可编辑的 JSON 格式,并命名为 soft_update.json
  1. configtxlator proto_decode --input update/soft_update.pb --type common.ConfigUpdate | jq . > update/soft_update.json
  1. 用信封消息来包装解码后的更新文件 soft_update.jsonsoft_update_in_envelope.json
  1. echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat update/soft_update.json)'}}}' | jq . > update/soft_update_in_envelope.json
  1. 使用 configtxlator 工具将 soft_update_in_envelope.json 转换为 protobuf 格式 soft_update_in_envelope.pb
  1. configtxlator proto_encode --input update/soft_update_in_envelope.json --type common.Envelope --output update/soft_update_in_envelope.pb

签名并提交配置更新

  1. web 签名通道更新:
  1. source envpeer1web
  2. peer channel signconfigtx -f update/soft_update_in_envelope.pb
  1. hard 签名并提交通道更新:
  1. source envpeer1hard
  2. peer channel update -f update/soft_update_in_envelope.pb -c mychannel -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA

我们在通道创世区块配置 configtx.yaml 中的通道应用组中的修改策略设置是 MAJORITY ,因此我们需要已经存在于通道的大部分组织管理员去签名这个更新。而目前 mychannel 中有3个组织,所以只需要2个组织签名就可以成功修改,也就是说,我们把 soft 踢出通道并不需要经过它自己同意

验证删除结果

  1. 最后提交通道更新后,可在 orderer1 容器日志中看到如下信息:
  1. 2022-04-04 11:33:30.141 UTC 007c WARN [policies] SignatureSetToValidIdentities -> invalid identity error="MSP softMSP is not defined on channel" identity="(mspid=softMSP subject=CN=peer1,OU=peer,O=Hyperledger,ST=North Carolina,C=US issuer=CN=soft.ifantasy.net,OU=Fabric,O=Hyperledger,ST=North Carolina,C=US serialnumber=713584922830159624441374963904174405230312956160)"
  1. soft 组织的peer节点已经无法拉取通道配置:
  1. (base) root@DebianA:2_FabricNetworkUpdate# peer channel fetch config update/config_block.pb -o orderer1.orderer.ifantasy.net:7151 -c mychannel --tls --cafile $ORDERER_CA
  2. 2022-04-04 19:43:54.133 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
  3. 2022-04-04 19:43:54.134 CST 0002 INFO [cli.common] readBlock -> Expect block, but got status: &{FORBIDDEN}
  4. Error: can't read the block: &{FORBIDDEN}

以上命令执行完毕后,查看当前块高度为8:

  1. (base) root@DebianA:2_FabricNetworkUpdate# source envpeer1web
  2. (base) root@DebianA:2_FabricNetworkUpdate# peer channel getinfo -c mychannel
  3. 2022-04-04 20:42:47.530 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
  4. Blockchain info: {"height":8,"currentBlockHash":"FdrpWDsifgih6QzpB4tZ6LPWcYUy9DSDI6jngXiGnC0=","previousBlockHash":"UErIVVGNUXWW0g0EPE3t0PQnwVdc/GyXAjsotCpqgjQ="}

参考


  1. Hyperledger. 向通道添加组织. hyperledger-fabric.readthedocs.io. [2022-02-25]

  2. 小蜗牛爬楼梯. fabric1.4动态删除组织(删除peer节点). 简书. [2021-01-22]

Hyperledger Fabric组织的动态添加和删除的更多相关文章

  1. Hyperledger Fabric节点的动态添加和删除

    前言 在Hyperledger Fabric组织的动态添加和删除中,我们已经完成了在运行着的网络中动态添加和删除组织.本文将在其基础上,详细介绍了如何在 soft 组织上添加新的 peer2 节点,并 ...

  2. 插件~使用ECharts动态在地图上标识点~动态添加和删除标识点

    之前写过一个Echarts的文章,没有基础的同学可以先看这<上一篇>,对于一个地图和说,我们在初始化之后,你可能被在地图上标识出一些点,当然这根据你的业务去标识,而如果每次更新数据都加载全 ...

  3. [Flex] Accordion系列-动态添加或删除Accordion容器中项目

    <?xml version="1.0" encoding="utf-8"?> <!--Flex中如何使用addChild()和removeCh ...

  4. Unity NGUI中动态添加和删除sprite

    (以后,参考链接和作者将在文章首部给出,转载请保留此部分内容) 参考链接:http://www.narkii.com/club/thread-299977-1.html,作者:纳金网 比巴卜: 参考链 ...

  5. jquery 动态添加和删除 ul li列表

    今天需要实现一个jquery动态添加和删除  ul li列表中的li行,自己简单的实现乐一个,分享一下 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ...

  6. 原生JS动态添加和删除类

    原生JS动态添加和删除类 由于需要, 给按钮组监听点击事件(要求用事件委托),当有一个按钮被点击时,相应的给该按钮添加一个类(激活类),其他没有点击的按钮就要移出该类 添加和和删除类有三种方法 首先等 ...

  7. adoop集群动态添加和删除节点

    hadoop集群动态添加和删除节点说明 上篇博客我已经安装了Hadoop集群(hadoop集群的安装步骤和配置),现在写这个博客我将在之前的基础上进行节点的添加的删除. 首先将启动四台机器(一主三从) ...

  8. js动态添加和删除标签

    html代码 <h1>动态添加和删除标签</h1> <div id="addTagTest"> <table> <thead& ...

  9. SpringBoot定时任务升级篇(动态添加修改删除定时任务)

    需求缘起:在发布了<Spring Boot定时任务升级篇>之后得到不少反馈,其中有一个反馈就是如何动态添加修改删除定时任务?那么我们一起看看具体怎么实现,先看下本节大纲: (1)思路说明: ...

随机推荐

  1. 最小生成树MST算法(Prim、Kruskal)

    最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...

  2. C++中如何可以修改const函数内的成员变量的值?

    呵呵,你使用mutable关键字来定义变量就可以了.下面举例说明 C++关键字mutable Mutable (1)mutable的意思是"可变的,易变的",跟C++中的const ...

  3. Java study 4

    JAVA 学习第四天 今日学习内容 快捷键.复习.注释.字面量 快捷键 学习地址:IJ快捷键 复习 jdk下载.安装.部署环境.第一个Java程序入门学习,环境变量path 注释 注释:顾名思义就是用 ...

  4. S7-1200学习记录

    型号:CPU 1212C DC/DC/DC 硬件包括CPU模块.信号模块(输入输出).通信模块.屏幕面板 1.通信模块 S7-1200最多可以添加3块通信模块,可以使用点对点通信模块.PROFIBUS ...

  5. Java 框架、库和软件的精选列表(awesome java)

    原创翻译,原始链接 本文为awesome系列中的awesome java Awesome Java Java 框架.库和软件的精选列表 项目 Bean映射 简化 bean 映射的框架 dOOv - 为 ...

  6. 【freertos】004-任务创建与删除及其实现细节

    前言 后面都是已动态内存任务为例来分析. 注意: 由于当前学习是在linux上跑的freertos,对于freertos底层相关接口,从demo工程来看,都是posix标准相关. 鉴于freertos ...

  7. c#的委托实例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. 在java web工程中实现登入和安全验证

    登入页面的话我们之前做过直接可以拿来用翻一翻之前的博客就可以找到 在这个基础上添加验证功能 代码如下: 1 package security; 2 /** 3 * @author 鐜嬭儨鍗? 4 */ ...

  9. synchronized 的作用?

    在 Java 中,synchronized 关键字是用来控制线程同步的,就是在多线程的环境 下,控制 synchronized 代码段不被多个线程同时执行. synchronized 既可以加在一段代 ...

  10. 学习openldap03

    ldap统一认证架构 一.ldap目录服务介绍什么是目录服务?  目录是一类为了浏览和搜索数据而设计的特殊的数据库.例如,为人所熟知的微软公司的活动目录(active directory)就是目录数据 ...