当前位置: 首页 > news >正文

Hyperledger Fabric官方中文教程-改进笔记(十五)-从通道中删除组织

注意:

作为本教程的前提条件,应当先通过本专栏 《向通道添加一个组织》 一文中的步骤,创建一个包含三个组织的区块链网络。(你也可以查阅官网 向通道添加一个组织 )


本教程将从包含 Org1、Org2 和 Org3 的 Hyperledger Fabric 测试网络中移除 Org2。

停止 Org2 Peer

在从 Fabric 网络中移除 Org2 之前,先停止 Org2 的 peer。

docker stop peer0.org2.example.com

获取配置

我们将在本地克隆的 fabric-samplestest-network 子目录根目录下进行操作。

cd fabric-samples/test-network

以 Org1 管理员身份执行以下命令。

# 你可以一次性执行这些命令
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${PWD}/../config/
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/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

现在我们可以执行以下命令获取最新的配置区块:

peer channel fetch config channel-artifacts/config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"

该命令会将二进制 protobuf 通道配置区块保存为 config_block.pb。请注意,文件名和扩展名的选择是任意的。但建议遵循一种约定,能够同时标识所表示的对象类型以及其编码(protobuf 或 JSON)。

当你执行 peer channel fetch 命令时,日志中会显示如下输出:

2024-03-18 14:35:27.837 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
2024-03-18 14:35:27.845 CST 0002 INFO [cli.common] readBlock -> Received block: 4
2024-03-18 14:35:27.845 CST 0003 INFO [channelCmd] fetch -> Retrieving last config block: 4
2024-03-18 14:35:27.848 CST 0004 INFO [cli.common] readBlock -> Received block: 4

将配置转换为 JSON 并精简

通道配置区块被存储在 channel-artifacts 文件夹中,以便将更新过程与其他制品分开。进入 channel-artifacts 文件夹来完成接下来的步骤:

cd channel-artifacts

现在我们将使用 configtxlator 工具将该通道配置区块解码为 JSON 格式(人类可读并可修改):

configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json

我们还必须去除所有与本次修改无关的头部、元数据、创建者签名等。我们通过 jq 工具来完成这一操作(你需要在本地安装 jq 工具):

jq '.data.data[0].payload.data.config' config_block.json >config.json

该命令会生成一个精简后的 JSON 对象 —— config.json,它将作为我们配置更新的基准。

:jq命令中的’>'会覆盖掉原来的同名文件,如果存在的话。上面的configtxlator命令也是

从通道中移除 Org2

我们将再次使用 jq 工具,把 Org2MSP 从通道的 application group 字段中删除:

jq 'del(.channel_group.groups.Application.groups.Org2MSP)' config.json > modified_config.json

从配置块中移除 Org2 加密材料

现在我们有两个需要关注的 JSON 文件 —— config.jsonmodified_config.json。初始文件包含三个组织,而“修改后的”文件仅包含 Org1 和 Org3 的数据。此时,只需重新编码这两个 JSON 文件并计算它们之间的差异即可。

首先,把 config.json 转换为名为 config.pb 的 protobuf:

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

接下来,把 modified_config.json 编码为 modified_config.pb

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

现在使用 configtxlator 来计算这两个配置 protobuf 的差异。该命令会输出一个新的 protobuf 二进制文件,命名为 config_update.pb

configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output config_update.pb

将差异对象解码为 JSON 格式:

configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json

现在我们得到了一个解码后的更新文件 —— config_update.json —— 需要将其包装在一个 envelope 消息中。此步骤会重新生成我们之前去掉的 header 字段。我们将该文件命名为 config_update_in_envelope.json

echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json

使用这个格式正确的 JSON —— config_update_in_envelope.json —— 我们将最后一次调用 configtxlator 工具,把它转换为 Fabric 需要的完整 protobuf 格式。我们将最终的更新对象命名为 config_update_in_envelope.pb

configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb

签名并提交配置更新

在将配置写入账本之前,我们需要相关管理员用户的签名。

首先,以 Org1 的身份签署该更新 proto。回到 test-network 目录:

cd ..

导出 Org1 的环境变量:

export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${PWD}/../config/
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/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

执行以下命令以 Org1 身份签署更新:

peer channel signconfigtx -f channel-artifacts/config_update_in_envelope.pb

导出 Org2 的环境变量:

export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${PWD}/../config/
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/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

执行以下命令以 Org2 身份签署更新:

peer channel signconfigtx -f channel-artifacts/config_update_in_envelope.pb

导出 Org3 的环境变量:

export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID=Org3MSP
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
export CORE_PEER_ADDRESS=localhost:11051

执行以下命令以 Org3 身份签署更新:

peer channel signconfigtx -f channel-artifacts/config_update_in_envelope.pb

现在我们最终执行 peer channel update 命令,将更新发送到通道:

peer channel update -f channel-artifacts/config_update_in_envelope.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"

如果更新提交成功,你会看到类似以下的消息:

2024-03-18 14:40:10.761 CST 0002 INFO [channelCmd] update -> Successfully submitted channel update

现在,移除 Org2 的所有操作已经完成。你可以通过以下命令查看 peer0.org1.example.com 和 peer0.org3.example.com 的日志:

docker logs peer0.org1.example.com -f
docker logs peer0.org3.example.com -f

查看 peer 的日志时,你会看到关于 peer0.org2.example.com 的 gossip 警告信息。由于 Org2 已经从 Fabric 网络中移除,Org1 和 Org3 的 peer 无法再连接到 Org2 peer。

2024-03-18 06:40:10.811 UTC 0086 WARN [gossip.gossip] func3 -> Failed determining organization of 87333f25423a5270cddbed5078fde14056ed2899e4ce7ffc6476e81f330201d1
2024-03-18 06:40:11.108 UTC 0087 WARN [peer.gossip.sa] OrgByPeerIdentity -> Peer Identity [...] cannot be desirialized. No MSP found able to do that.

重启 Org1 Peer 和 Org3 Peer

你可以通过重启 Org1 和 Org3 的 peer 来消除这些警告。

docker stop peer0.org1.example.com
docker start peer0.org1.example.com
docker stop peer0.org3.example.com
docker start peer0.org3.example.com

更新集合定义文件(可选)

如果你的链码中使用了私有数据集合,现在应当从集合定义中移除 Org2MSP,并更新链码,因为 Org2MSP 已经不再定义在 Fabric 网络中。例如,一个集合被定义为在 Org1 和 Org2 之间保存私有数据:

[{"name": "pdc1","policy": "OR('Org1MSP.member', 'Org2MSP.member')","requiredPeerCount": 0,"maxPeerCount": 3,"blockToLive": 1000000,"memberOnlyRead": true,"memberOnlyWrite": false,"endorsementPolicy": { "signaturePolicy": "OR('Org1MSP.member', 'Org2MSP.member')" }}
]

在移除 Org2 后,应当从集合定义中移除对 Org2MSP 的引用,因此集合现在只由 Org1 持有:

[{"name": "pdc1","policy": "OR('Org1MSP.member')","requiredPeerCount": 0,"maxPeerCount": 3,"blockToLive": 1000000,"memberOnlyRead": true,"memberOnlyWrite": false,"endorsementPolicy": { "signaturePolicy": "OR('Org1MSP.member')" }}
]

将集合转移到另一个组织(可选)

如果某个已存在的集合仅由被移除的组织持有,该怎么办?例如,以下集合 pdc2 仅由 Org2 持有:

[{"name": "pdc2","policy": "OR('Org2MSP.member')","requiredPeerCount": 0,"maxPeerCount": 3,"blockToLive": 1000000,"memberOnlyRead": true,"memberOnlyWrite": false,"endorsementPolicy": { "signaturePolicy": "OR('Org2MSP.member')" }}
]

正如 更新集合定义 所述,现有的集合必须包含在集合定义文件中,因此我们不能简单地将集合从文件中移除。

如果在更新链码定义时指定了集合配置,则必须包含所有现有集合的定义。

一种替代方案是,你可以将集合转移到另一个现有组织。在本例中,我们将 pdc2 转移到 Org3:

[{"name": "pdc2","policy": "OR('Org3MSP.member')","requiredPeerCount": 0,"maxPeerCount": 3,"blockToLive": 1000000,"memberOnlyRead": true,"memberOnlyWrite": false,"endorsementPolicy": { "signaturePolicy": "OR('Org3MSP.member')" }}
]

完成转移后,Org3 的 peer 会尝试从其他 peer 获取 pdc2 的私有数据。这被称为私有数据对账。私有数据对账会基于 core.yaml 中的 peer.gossip.pvtData.reconciliationEnabledpeer.gossip.pvtData.reconcileSleepInterval 配置周期性发生。由于 Org2 peer 已经从 Fabric 网络中移除,Org3 peer 将无法再从 Org2 peer 获取私有数据。你会在 Org3 的日志中看到如下警告信息:

2024-03-18 06:15:51.065 UTC 0047 WARN [gossip.privdata] fetchPrivateData -> Do not know any peer in the channel (channel1) that matches the policies , aborting channel=channel1
2024-03-18 06:15:51.065 UTC 0048 ERRO [gossip.privdata] reconcile -> reconciliation error when trying to fetch missing items from different peers: Empty membership channel=channel1
2024-03-18 06:15:51.065 UTC 0049 ERRO [gossip.privdata] run -> Failed to reconcile missing private info, error:  Empty membership channel=channel1

你可以在 Org3 的 peer 上配置 peer.gossip.pvtData.reconciliationEnabled=false 来停止对账并抑制错误日志。

http://www.dtcms.com/a/348096.html

相关文章:

  • 【机器学习】3 Generative models for discrete data
  • HTML网页游戏五子棋
  • 电路学习(四)二极管
  • Spring框架相关面试题
  • 【机器学习】4 Gaussian models
  • 【网络运维】Shell 脚本编程:while 循环与 until 循环
  • Python自学笔记11 Numpy的索引和切片
  • Shell脚本-expect
  • VirtualBox安装openEuler24.03
  • 【C++】函数返回方式详解:传值、传引用与传地址
  • 校园跑腿小程序源码 | 跑腿便利店小程序 含搭建教程
  • 如何在 Ubuntu 上安装和配置 Samba ?
  • 2025年渗透测试面试题总结-30(题目+回答)
  • Java 20 新特性及具体应用
  • Cisdem Video Converter for mac 优秀的视频格式转换工具
  • 夜间跌倒检测响应速度↑150%!陌讯多模态骨架追踪算法在智慧养老院的落地实践
  • 埃氏筛|树dfs|差分计数
  • JVM OOM问题排查与解决思路
  • Meta AI 剧变:汪滔挥刀重组,Llama 开源路线告急,超级智能梦碎还是重生?
  • 96、23种设计模式之原型模式(5/23)
  • STM32 USB 之大坑
  • ubuntu中网卡的 IP 及网关配置设置为永久生效
  • Ubuntu24.04环境下causal_conv1d和mamba_ssm安装
  • 嵌入式八股文面试题总结(QT、RTOS、Linux、ARM、C/C++)(持续更新)
  • QT-布局管理器
  • 音视频面试题集锦第 32 期
  • C语言指针5
  • 使用虚幻引擎5(UE5)开发类似《原神》的开放世界游戏:从技术架构到实践指南
  • LeetCode-542. 01 矩阵
  • (LeetCode 每日一题) 1493. 删掉一个元素以后全为 1 的最长子数组 (双指针)