Hyperledger Fabric組織的動態新增和刪除

丿風色幻想發表於2022-04-09

前言

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 網路為:
初始 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 服務:
hard.ifantasy.net:
    container_name: hard.ifantasy.net
    extends:
        file: docker-base.yaml
        service: ca-base
    command: sh -c 'fabric-ca-server start -d -b ca-admin:ca-adminpw --port 7050'
    environment:
        - FABRIC_CA_SERVER_CSR_CN=hard.ifantasy.net
        - FABRIC_CA_SERVER_CSR_HOSTS=hard.ifantasy.net
    volumes:
        - ${LOCAL_CA_PATH}/hard.ifantasy.net/ca:${DOCKER_CA_PATH}/ca
    ports:
        - 7450:7050
  1. 啟動 hard 的 CA 服務
docker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d hard.ifantasy.net
  1. 註冊 hard 的組織賬號:
echo "Working on tls"
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH//ca/crypto/ca-cert.pem
export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH//ca/admin
fabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@:7050
fabric-ca-client register -d --id.name peer1hard --id.secret peer1hard --id.type orderer -u https://:7050

echo "Working on hard"
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/hard.ifantasy.net/ca/crypto/ca-cert.pem
export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/hard.ifantasy.net/ca/admin
fabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@hard.ifantasy.net:7450
fabric-ca-client register -d --id.name peer1 --id.secret peer1 --id.type peer -u https://hard.ifantasy.net:7450
fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u https://hard.ifantasy.net:7450
  1. 配置 hard 的組織證書:
echo "Preparation============================="
mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/assets
cp $LOCAL_CA_PATH/hard.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/assets/ca-cert.pem
cp $LOCAL_CA_PATH//ca/crypto/ca-cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/assets/tls-ca-cert.pem
echo "Preparation============================="
echo "Enroll Admin"
export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/hard.ifantasy.net/assets/ca-cert.pem
export FABRIC_CA_CLIENT_MSPDIR=msp
fabric-ca-client enroll -d -u https://admin1:admin1@hard.ifantasy.net:7450
mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp/admincerts
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

echo "Enroll Peer1"
export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/hard.ifantasy.net/registers/peer1
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/hard.ifantasy.net/assets/ca-cert.pem
export FABRIC_CA_CLIENT_MSPDIR=msp
fabric-ca-client enroll -d -u https://peer1:peer1@hard.ifantasy.net:7450
# for TLS
export FABRIC_CA_CLIENT_MSPDIR=tls-msp
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/hard.ifantasy.net/assets/tls-ca-cert.pem
fabric-ca-client enroll -d -u https://peer1hard:peer1hard@:7050 --enrollment.profile tls --csr.hosts peer1.hard.ifantasy.net
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
mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/registers/peer1/msp/admincerts
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

mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/msp/admincerts
mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/msp/cacerts
mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/msp/tlscacerts
mkdir -p $LOCAL_CA_PATH/hard.ifantasy.net/msp/users
cp $LOCAL_CA_PATH/hard.ifantasy.net/assets/ca-cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/msp/cacerts/
cp $LOCAL_CA_PATH/hard.ifantasy.net/assets/tls-ca-cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/msp/tlscacerts/
cp $LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/hard.ifantasy.net/msp/admincerts/cert.pem
cp $LOCAL_ROOT_PATH/config/config-msp.yaml $LOCAL_CA_PATH/hard.ifantasy.net/msp/config.yaml
echo "End hard============================="
  1. compose/docker-compose.yaml 中新增 hard 的 peer 服務:
peer1.hard.ifantasy.net:
    container_name: peer1.hard.ifantasy.net
    extends:
        file: docker-base.yaml
        service: peer-base
    environment:
        - CORE_PEER_ID=peer1.hard.ifantasy.net
        - CORE_PEER_ADDRESS=peer1.hard.ifantasy.net:7051
        - CORE_PEER_LOCALMSPID=hardMSP
        - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.hard.ifantasy.net:7051
    volumes:
        - ${LOCAL_CA_PATH}/hard.ifantasy.net/registers/peer1:${DOCKER_CA_PATH}/peer
    ports:
        - 7451:7051
  1. 啟動 hard 的 peer1 節點:
docker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d peer1.hard.ifantasy.net

此時所有容器如下:

(base) root@DebianA:2_FabricNetworkUpdate# peer channel getinfo -c mychannel
CONTAINER ID   IMAGE                                                                                                                                                                   COMMAND                  CREATED              STATUS              PORTS                              NAMES
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
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
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
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
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
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
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
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
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
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
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
export LOCAL_ROOT_PATH=$PWD
export LOCAL_CA_PATH=$LOCAL_ROOT_PATH/orgs
export DOCKER_CA_PATH=/tmp
export COMPOSE_PROJECT_NAME=fabriclearn
export DOCKER_NETWORKS=network
export FABRIC_BASE_VERSION=2.4
export FABRIC_CA_VERSION=1.5
echo "init terminal hard"
export FABRIC_CFG_PATH=$LOCAL_ROOT_PATH/config
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="hardMSP"
export CORE_PEER_ADDRESS=peer1.hard.ifantasy.net:7451
export CORE_PEER_TLS_ROOTCERT_FILE=$LOCAL_CA_PATH/hard.ifantasy.net/assets/tls-ca-cert.pem
export CORE_PEER_MSPCONFIGPATH=$LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp
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 組織管理員來獲取通道最新配置:

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

以上命令將通道配置區塊以二進位制 protobuf 形式儲存在 config_block.pb 中,輸出檔案的名字和副檔名儘管可以任意指定,然後可以在命令列中看到以下日誌:

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

因為我們在建立 mychannel 後並沒有進行任何的通道更新操作,所以目前最新 mychannel 的配置區塊是初始區塊 0,在更新一次後的下一節中我們會發現獲取的配置區塊不再是0。

轉換配置格式並簡化

現在可以用 configtxlator 工具將這個通道配置解碼為 JSON 格式(以便被友好地閱讀和修改),然後使用 jq 工具裁剪其頭部、後設資料、建立者簽名等所有和增加組織無關的內容:

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 的組織定義

然後使用命令生成hard組織定義檔案:

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

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

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

其次,將 modified_config.json 編碼成 modified_config.pb

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

然後,使用 configtxlator 去計算兩個 protobuf 配置的差異,並將輸出的 protobuf 內容寫入hard_update.pb :

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

再次,我們將這個檔案解碼成可編輯的JSON 格式,並命名為 hard_update.json

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

之後,我們需要用信封訊息來包裝解碼後的更新檔案 hard_update.json ,這個步驟要把之前裁剪掉的頭部資訊還原回來,將這個檔案命名為hard_update_in_envelope.json

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

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 管理員來簽名這個通道更新:
source envpeer1soft
peer channel signconfigtx -f update/hard_update_in_envelope.pb
  1. web 管理員簽名並提交通道更新(由於提交更新命令 peer channel update 會自動附帶提交者的簽名,所以可直接提交通道更新):
source envpeer1web
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:

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

將hard組織加入通道

經過以上步驟後, mychannel 通道的配置已經更新幷包含了 hard 組織,現在只需要讓 hard 的 peer 節點主動加入並同步區塊最新資料即可。 peer 拉取 mychannel 創世區塊:

source envpeer1hard
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 通過這個區塊連線到通道:

peer channel join -b mychannel.block

以上命令執行完畢後,檢視當前塊高度為7:

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

刪除舊組織

本節將演示在上節網路中刪除一箇舊組織——soft(軟體組)[2]

獲取通道最新配置

通過 web 組織管理員來獲取通道最新配置:

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

以上命令將通道配置區塊以二進位制 protobuf 形式儲存在 config_block.pb 中,輸出檔案的名字和副檔名儘管可以任意指定,然後可以在命令列中看到以下日誌:

(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
2022-04-04 16:59:42.952 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
2022-04-04 16:59:42.954 CST 0002 INFO [cli.common] readBlock -> Received block: 6
2022-04-04 16:59:42.954 CST 0003 INFO [channelCmd] fetch -> Retrieving last config block: 6
2022-04-04 16:59:42.961 CST 0004 INFO [cli.common] readBlock -> Received block: 6

轉換配置格式並簡化

configtxlator 工具將這個通道配置解碼為 JSON 格式(以便被友好地閱讀和修改),然後使用 jq 工具裁剪其頭部、後設資料、建立者簽名等所有和刪除組織無關的內容:

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
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
configtxlator proto_encode --input update/config.json --type common.Config --output update/config.pb
  1. modified_config.json 編碼成 modified_config.pb
configtxlator proto_encode --input update/modified_config.json --type common.Config --output update/modified_config.pb
  1. 使用 configtxlator 去計算兩個 protobuf 配置的差異,並將輸出的 protobuf 內容寫入 soft_update.pb
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
configtxlator proto_decode --input update/soft_update.pb --type common.ConfigUpdate | jq . > update/soft_update.json
  1. 用信封訊息來包裝解碼後的更新檔案 soft_update.jsonsoft_update_in_envelope.json
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
configtxlator proto_encode --input update/soft_update_in_envelope.json --type common.Envelope --output update/soft_update_in_envelope.pb

簽名並提交配置更新

  1. web 簽名通道更新:
source envpeer1web
peer channel signconfigtx -f update/soft_update_in_envelope.pb
  1. hard 簽名並提交通道更新:
source envpeer1hard
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 容器日誌中看到如下資訊:
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節點已經無法拉取通道配置:
(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
2022-04-04 19:43:54.133 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
2022-04-04 19:43:54.134 CST 0002 INFO [cli.common] readBlock -> Expect block, but got status: &{FORBIDDEN}
Error: can't read the block: &{FORBIDDEN}

以上命令執行完畢後,檢視當前塊高度為8:

(base) root@DebianA:2_FabricNetworkUpdate# source envpeer1web
(base) root@DebianA:2_FabricNetworkUpdate# peer channel getinfo -c mychannel
2022-04-04 20:42:47.530 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
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] ↩︎

相關文章