警告
在執行測驗專案時,多次使用并修改此檔案,部分地方沒有及時更新.如果問題請聯系 487008159 更正.
必看
- 專案:
fabric-samples - 作業目錄 :
~/go/src/github.com/hyperledger/fabric-samples/test-network
輔助腳本
身份環境變數
組織 1
- env-org1.sh
#!/bin/bash
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
組織 2
- env-org2.sh
#!/bin/bash
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:9051
排序組織
#!/bin/bash
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/[email protected]/msp
修改腳本
- 進入測驗網路
cd $GOPATH/src/github.com/hyperledger/fabric-samples/test-network
- 修改測驗腳本
vim ./network.sh
大概在51行,注釋掉二進制檔案檢查的那一項
function checkPrereqs() {
## Check if your have cloned the peer binaries and configuration files.
peer version > /dev/null 2>&1
# 注釋下面的部分
# if [[ $? -ne 0 || ! -d "../config" ]]; then
# errorln "Peer binary and configuration files not found.."
# errorln
# errorln "Follow the instructions in the Fabric docs to install the Fabric Binaries:"
# errorln "https://hyperledger-fabric.readthedocs.io/en/latest/install.html"
# exit 1
# fi
# 注釋上面的部分
# use the fabric tools container to see if the samples and binaries match your
# docker images
專案環境變數
export COMPOSE_PROJECT_NAME=fabric
export IMAGETAG=2.2.0
清理腳本
#########################################################################
# File Name: clear.sh
# Author: zll
# mail: [email protected]
# Created Time: 二 12/28 17:18:54 2021
#########################################################################
echo "停止所有容器"
docker stop $(docker ps -aq)
echo "移除所有容器"
docker rm $(docker ps -aq)
echo "清理聯盟資料"
./network.sh down
echo "移除 docker網路"
docker network prune -f
echo "清理卷"
docker volume prune -f
echo "設定環境變數"
export COMPOSE_PROJECT_NAME=fabric
export IMAGETAG=2.2.0
echo "啟動聯盟并創建通道"
./network.sh up createChannel
環境
下載 fabric-sample 原始碼
mkdir -p $GOPATH/src/github.com/hyperledger/
cd $GOPATH/src/github.com/hyperledger/
git clone https://gitee.com/Alikx/fabric-samples.git
- 進入專案
cd $GOPATH/src/github.com/hyperledger/fabric-samples/test-network
- 切換版本
git checkout v2.2.0
- 移動組態檔,先進
gopath的 bin目錄下,之前解二進制檔案連同組態檔都在這里.
mv config ~/go/src/github.com/hyperledger/fabric-samples
fabric二進制及組態檔
https://github.com/hyperledger/fabric/releases/tag/v2.2.0
- 下載
wget https://github.91chi.fun//https://github.com//hyperledger/fabric/releases/download/v2.2.0/hyperledger-fabric-linux-amd64-2.2.0.tar.gz
- 查看壓縮包中的檔案
root@k8s_node01:~# tar --list -f hyperledger-fabric-linux-amd64-2.2.0.tar.gz
bin/
bin/peer
bin/orderer
bin/discover
bin/configtxgen
bin/cryptogen
bin/idemixgen
bin/configtxlator
config/
config/configtx.yaml
config/core.yaml
config/orderer.yaml
- 解壓
mkdir hyperledger-fabric-linux-amd64-2.2.0
tar -zxvf hyperledger-fabric-linux-amd64-2.2.0.tar.gz -C hyperledger-fabric-linux-amd64-2.2.0
- 拷貝
mv config $GOPATH/src/github.com/hyperledger/fabric-samples/
日志監控
開啟監控
此步驟不是必需的,但對鏈碼進行故障診斷非常有用,要監控智能合同的日志,管理員可以使用logspout工具查看一組Docker容器的聚合輸出,該工具將來自不同Docker容器的輸出流收集到一個地方,以便于從單個視窗查看正在發生的事情,這可以幫助管理員在安裝智能合同時除錯問題,幫助開發人員在呼叫智能合同時除錯問題,由于一些容器的創建純粹是為了啟動智能合同,并且只存在很短的時間,因此從您的網路收集所有日志是有幫助的,
A script to install and configure Logspout, monitordocker.sh, is already included in the commercial-paper sample in the Fabric samples. We will use the same script in this tutorial as well. The Logspout tool will continuously stream logs to your terminal, so you will need to use a new terminal window. Open a new terminal and navigate to the test-network directory.
cd fabric-samples/test-network
You can run the monitordocker.sh script from any directory. For ease of use, we will copy the monitordocker.sh script from the commercial-paper sample to your working directory
cp ../commercial-paper/organization/digibank/configuration/cli/monitordocker.sh .
# if you're not sure where it is
find . -name monitordocker.sh
然后,您可以通過運行以下命令啟動Logspout:
./monitordocker.sh fabric_test
您應該會看到類似于以下內容的輸出:
Starting monitoring on all containers on the network docker_test
f96a6fae3c8cadcb8f3b5ac0f4fb808b45d1d30cc26498451974bd6a1b16a4b7
您一開始不會看到任何日志,但當我們部署鏈碼時,這種情況會發生變化,使這個終端視窗寬,字體小可能會有幫助,
如果找不到網路,就使用個下面命令查看下網路,實際上網路名字就是上面修改過的名字.
docker network ls
啟動網路
重繪環境變數
source init-env.sh
export CHANNEL=mychannel
export ORDERER_TLS_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
方式一啟動
./network.sh up createChannel
方式二啟動
./network.sh up
生成通道交易檔案
configtxgen \
-profile TwoOrgsChannel \
-outputCreateChannelTx ./channel-artifacts/$CHANNEL.tx \
-channelID $CHANNEL \
-configPath configtx
創建通道區塊
peer channel create \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c $CHANNEL \
-f ./channel-artifacts/$CHANNEL.tx \
--outputBlock ./channel-artifacts/channel1.block \
--tls \
--cafile
組織1 的peer加入通道
設定環境變數
source env-org1.sh
加入通道
由于我們已經以Org1管理員的身份使用peer CLI,因此讓我們將Org1的Peer加入到通道中,由于Org1提交了通道創建交易,因此我們的檔案系統上已經有了通道創世塊,使用以下命令將Org1的Peer加入通道,
peer channel join -b ./channel-artifacts/$CHANNEL.block
環境變數CORE_PEER_ADDRESS已設定為以peer0.org1.example.com為目標,命令執行成功后將生成peer0.org1.example.com加入通道的回應:
2021-11-23 03:50:44.103 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:50:44.234 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
查詢已加入的通道
peer channel list
- 日志
2021-11-23 03:51:13.257 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
channel1
mychannel
組織2 的peer加入通道
設定環境變數
source env-org2.sh
列出當前peer 加入的通道
peer channel list
從排序服務中獲取通道區塊資料
peer channel fetch 0 \
./channel-artifacts/channel_org2.block \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c $CHANNEL \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-23 05:06:29.092 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 05:06:29.097 UTC [cli.common] readBlock -> INFO 002 Received block: 0
加入通道
peer channel join -b ./channel-artifacts/channel_org2.block
2021-11-23 05:11:20.912 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 05:11:21.071 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
查詢結果
peer channel list
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer channel list
2021-11-23 05:12:03.257 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
channel1
mychannel
安裝鏈碼
打包鏈碼
- 進去go語言鏈碼包
cd ../chaincode/fabcar/go
- 下載依賴
GO111MODULE=on
go mod vendor
- 回到作業目錄
cd ../../../test-network
- 管理員1和管理員2 (一個打包另一個直接拿來用就好了)打包鏈碼
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/go/ --lang golang --label fabcar_1
執行完該命令會在當前目錄下生成 鏈碼包檔案 fabcar.tar.gz .
安裝鏈碼
在Org1 的peer 上安裝鏈碼
切換身份為組織 1 的管理員
source env-org1.sh
安裝鏈碼
peer lifecycle chaincode install fabcar.tar.gz
查詢已安裝的鏈碼
peer lifecycle chaincode queryinstalled
在Org2的 peer 上安裝鏈碼
切換身份為組織 2 的管理員
source env-org2.sh
安裝鏈碼
peer lifecycle chaincode install fabcar.tar.gz
查詢已安裝的鏈碼
peer lifecycle chaincode queryinstalled
設定包 ID
peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: fabcar_1:a5a64c81bd0ff978378580a452d6ea21f8c39ebce3645c712edab3b795b8d722, Label: fabcar_1
export CC_PACKAGE_ID=fabcar_1:a5a64c81bd0ff978378580a452d6ea21f8c39ebce3645c712edab3b795b8d722
默認策略下
組織 1 批準
source env-org1.sh
peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile $ORDERER_TLS_CA
組織 2 批準
source env-org2.sh
peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile $ORDERER_TLS_CA
檢查批準情況
peer lifecycle chaincode checkcommitreadiness \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--sequence 1 \
--tls \
--cafile $ORDERER_TLS_CA \
--output json
- 日志
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
提交
peer lifecycle chaincode commit \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--sequence 1 \
--tls \
--cafile $ORDERER_TLS_CA \
--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
修改策略方式(默認策略執行后,此策略不需要執行)
注意:升級策略可執行此步驟,
組織 1 批準
source env-org1.sh
peer lifecycle chaincode approveformyorg \
-signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
組織 2 批準
source env-org2.sh
peer lifecycle chaincode approveformyorg \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
檢查批準情況
peer lifecycle chaincode checkcommitreadiness \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--output json
提交
peer lifecycle chaincode commit \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--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
查詢已提交
peer lifecycle chaincode querycommitted \
--channelID $CHANNEL \
--name fabcar \
--cafile $ORDERER_TLS_CA
呼叫鏈碼
peer chaincode invoke -o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--tls \
--cafile $ORDERER_TLS_CA \
-C $CHANNEL \
-n fabcar \
--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":[]}'
- 日志
2021-11-23 03:43:29.125 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
- 查詢
peer chaincode query \
-C $CHANNEL \
-n fabcar \
-c '{"Args":["queryAllCars"]}'
- 日志
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
寫資料
source env-org1.sh
peer chaincode invoke \
--tls \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--cafile $ORDERER_TLS_CA \
-C $CHANNEL \
-n fabcar \
-c '{"Args":["createCar","CAR12","China","changan","red","Binny"]}' \
--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
peer chaincode query \
-C $CHANNEL \
-n fabcar \
-c '{"Args":["queryCar","CAR12"]}'
執行到此處,就可以除錯 SDK 了
https://gitee.com/xubinbin1024/fabric_sdk_demo_node_v2.2
升級鏈碼
更新背書策略
You can use the chaincode definition to update an endorsement policy without having to repackage or re-install the chaincode. Channel members can approve a chaincode definition with a new endorsement policy and commit it to the channel.
批準
您可以使用鏈碼定義來更新背書策略,而無需重新打包或重新安裝鏈碼,渠道成員可以批準帶有新的背書策略的鏈碼定義,并將其提交給渠道,
peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name fabcar \
--version 2.0 \
--package-id $CC_PACKAGE_ID \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')"
檢查批準情況
這里我認為有一個 bug,如果是新定義的是更新背書策略,那么檢查的時候也要攜帶新的背書策略這個選項.
peer lifecycle chaincode checkcommitreadiness \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--output json
- 日志
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
提交
peer lifecycle chaincode commit \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--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
- 日志
2021-11-23 03:41:47.755 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [1f08b845f0462c415d70799360cc9e72c41e9e768a26a5eef240ed14cd061d0e] committed with status (VALID) at localhost:9051
2021-11-23 03:41:47.806 UTC [chaincodeCmd] ClientWait -> INFO 002 txid [1f08b845f0462c415d70799360cc9e72c41e9e768a26a5eef240ed14cd061d0e] committed with status (VALID) at localhost:7051
- 查詢已提交
peer lifecycle chaincode querycommitted \
--channelID mychannel \
--name fabcar \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 日志
Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
修改通道中 orderer 相關配置
基于現有的網路,修改 Batch 塊的 max_message_count.
單獨測驗此程序的步驟(unnecessary)
清理網路
docker stop $(docker ps -a)
docker rm $(docker ps -a)
重啟網路并創建通道
export COMPOSE_PROJECT_NAME=fabric
export IMAGE_TAG=2.2.0
export ORDERER_CONTAINER=localhost:7050
export TLS_ROOT_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CH_NAME=mychannel
./network.sh up createChannel
獲取通道配置
# you can issue all of these commands at once
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
peer channel fetch config \
configtx/config_block.pb \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
解碼通道配置
rm update
mkdir update
configtxlator proto_decode --input configtx/config_block.pb --type common.Block --output update/config_block.json
提取更新配置部分
jq '.data.data[0].payload.data.config' update/config_block.json > update/config.json
查看原始值
jq '.channel_group.groups.Orderer.values.BatchSize.value.max_message_count' update/config.json
賦值并寫入新檔案
jq '.channel_group.groups.Orderer.values.BatchSize.value.max_message_count=13' update/config.json > update/config13.json
查看新值
jq '.channel_group.groups.Orderer.values.BatchSize.value.max_message_count' update/config13.json
編碼更新檔案
configtxlator proto_encode --input update/config13.json --type common.Config --output update/config13.pb
configtxlator proto_encode --input update/config.json --type common.Config --output update/config.pb
configtxlator compute_update --channel_id mychannel --original update/config.pb --updated update/config13.pb --output update/config13_update.pb
configtxlator proto_decode --input update/config13_update.pb --type common.ConfigUpdate --output update/config13_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"'mychannel'", "type":2}},"data":{"config_update":'$(cat update/config13_update.json)'}}}' | jq . > update/config13_update_in_envelope.json
configtxlator proto_encode --input update/config13_update_in_envelope.json --output update/config13_update_in_envelope.pb --type common.Envelope
編碼原始檔案
configtxlator proto_encode --input update/config.json --type common.Config --output update/config.pb
計算增量
configtxlator compute_update --channel_id mychannel --original update/config.pb --updated update/config13.pb --output update/config13_update.pb
解碼增量
configtxlator proto_decode --input update/config13_update.pb --type common.ConfigUpdate --output update/config13_update.json
封裝增量
echo '{"payload":{"header":{"channel_header":{"channel_id":"'mychannel'", "type":2}},"data":{"config_update":'$(cat update/config13_update.json)'}}}' | jq . > update/config13_update_in_envelope.json
編碼完成更新檔案
configtxlator proto_encode --input update/config13_update_in_envelope.json --output update/config13_update_in_envelope.pb --type common.Envelope
切換身份(關鍵)
因為更新的 orderer的部分,所以以 orderer 身份更新
- 切換身份
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/[email protected]/msp
簽名
peer channel signconfigtx \
-f update/config13_update_in_envelope.pb \
-o localhost:7050 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
提交
peer channel update -f update/config13_update_in_envelope.pb -c mychannel -o localhost:7050 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-12-23 14:46:38.359 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-12-23 14:46:38.445 CST [channelCmd] update -> INFO 002 Successfully submitted channel update
檢查
拉取最新區塊
- 環境變數可以不改(非必須)
# you can issue all of these commands at once
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
- 拉取
peer channel fetch config \
configtx/config_block1.pb \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
解碼通道配置
configtxlator proto_decode --input configtx/config_block1.pb --type common.Block --output update/config_block1.json
提取更新配置部分
jq '.data.data[0].payload.data.config' update/config_block1.json > update/config1.json
查看原始值
jq '.channel_group.groups.Orderer.values.BatchSize.value.max_message_count' update/config1.json
清理(如果需要)
清理
停止日志監控,停止網路,移除網路,移除卷
docker stop logspout && docker rm logspout && docker stop $(docker ps -aq) && docker rm $(docker ps -aq) && docker network prune && docker volume prune
移除鏈碼相關鏡像
docker rmi $(docker ps | grep "dev-peer" | awk '{print $3}')
- 查看運行中的容器
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.IMAGE}}"
- 移除
docker rm $(docker ps | grep "hyperledger" | awk '{print $1}')
向組織中新增peer
- 作業目錄 :
~/go/src/github.com/hyperledger/fabric-samples/test-network - 組織:
org1
查看當前組織中pee的個數
tree -L 5
│ └── peerOrganizations
│ ├── org1.example.com
│ │ ├── ca
│ │ │ ├── ca.org1.example.com-cert.pem
│ │ │ └── priv_sk
│ │ ├── connection-org1.json
│ │ ├── connection-org1.yaml
│ │ ├── msp
│ │ │ ├── admincerts
│ │ │ ├── cacerts
│ │ │ ├── config.yaml
│ │ │ └── tlscacerts
│ │ ├── peers
│ │ │ └── peer0.org1.example.com
│ │ ├── tlsca
│ │ │ ├── priv_sk
│ │ │ └── tlsca.org1.example.com-cert.pem
│ │ └── users
│ │ ├── [email protected]
│ │ └── [email protected]
新增peer 證書檔案
編輯證書組態檔
啟動網路的步驟中,查看輸出日志
Creating Org1 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
修改組態檔 ./organizations/cryptogen/crypto-config-org1.yaml.
vim ./organizations/cryptogen/crypto-config-org1.yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
# ---------------------------------------------------------------------------
# Org1
# ---------------------------------------------------------------------------
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
# ---------------------------------------------------------------------------
# "Specs"
# ---------------------------------------------------------------------------
# Uncomment this section to enable the explicit definition of hosts in your
# configuration. Most users will want to use Template, below
#
# Specs is an array of Spec entries. Each Spec entry consists of two fields:
# - Hostname: (Required) The desired hostname, sans the domain.
# - CommonName: (Optional) Specifies the template or explicit override for
# the CN. By default, this is the template:
#
# "{{.Hostname}}.{{.Domain}}"
#
# which obtains its values from the Spec.Hostname and
# Org.Domain, respectively.
# ---------------------------------------------------------------------------
# - Hostname: foo # implicitly "foo.org1.example.com"
# CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above
# - Hostname: bar
# - Hostname: baz
# ---------------------------------------------------------------------------
# "Template"
# ---------------------------------------------------------------------------
# Allows for the definition of 1 or more hosts that are created sequentially
# from a template. By default, this looks like "peer%d" from 0 to Count-1.
# You may override the number of nodes (Count), the starting index (Start)
# or the template used to construct the name (Hostname).
#
# Note: Template and Specs are not mutually exclusive. You may define both
# sections and the aggregate nodes will be created for you. Take care with
# name collisions
# ---------------------------------------------------------------------------
Template:
Count: 2 # 此處由1 改為 2
SANS:
- localhost
# Start: 5
# Hostname: {{.Prefix}}{{.Index}} # default
# ---------------------------------------------------------------------------
# "Users"
# ---------------------------------------------------------------------------
# Count: The number of user accounts _in addition_ to Admin
# ---------------------------------------------------------------------------
Users:
Count: 1
- 執行網路拓展命令
cryptogen extend --config=./organizations/cryptogen/crypto-config-org1.yaml --input=organizations
- 再次查看目錄結構
ls organizations/peerOrganizations/org1.example.com/peers
peer0.org1.example.com peer1.org1.example.com
啟動新peer節點
查看當前節點
docker ps --format "table {{.ID}} \t {{.Names}}" | grep 'peer'
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# docker ps --format "table {{.ID}} \t {{.Names}}"
CONTAINER ID NAMES
a6b9c523c562 dev-peer0.org2.example.com-fabcar_1-762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
a20f2648b557 dev-peer0.org1.example.com-fabcar_1-762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
f69bca3357cc logspout
f19399557a69 cli
263f14b81a51 peer0.org2.example.com
5513a783cb6a peer0.org1.example.com
1eca52dd33b4 orderer.example.com
新增 docker-compose 配置
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
networks:
fabric_test:
driver: bridge
external: true
services:
peer1.org1.example.com:
container_name: peer1.org1.example.com
tty: true
image: hyperledger/fabric-peer:$IMAGE_TAG
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_PEER_ID=peer1.org1.example.com
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
- CORE_CHAINCODE_LOGGING_LEVEL=INFO
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_ADDRESS=peer1.org1.example.com:7051
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_test
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: peer node start
ports:
- 8051:7051
- 8053:7053
volumes:
- /var/run/:/host/var/run/
- ./organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ./organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls
networks:
- fabric_test
啟動節點
docker-compose -f docker-compose.yaml up -d peer1.org1.example.com
- 查看節點資訊
docker ps --format "table {{.ID}}\t{{.Names}}" --filter name=org1
3cce207d4570 peer1.org1.example.com
5513a783cb6a peer0.org1.example.com
將新節點加入通道
- 配置環境變數
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:8051
peer channel fetch 0 \
./channel-artifacts/channel_org1_peer1.block \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 加入通道
mychannel
peer channel join -b ./channel-artifacts/channel_org1_peer1.block
2021-11-23 06:10:44.200 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 06:10:44.324 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
- 查看
peer channel list
2021-11-23 06:11:00.887 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
mychannel
安裝鏈碼
- 安裝鏈碼
peer lifecycle chaincode install fabcar.tar.gz
- 批準鏈碼
peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 查詢
peer lifecycle chaincode checkcommitreadiness \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--output json
- 呼叫鏈碼
peer chaincode query \
-C mychannel \
-n fabcar \
-c '{"Args":["queryAllCars"]}'
參考日志
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer lifecycle chaincode approveformyorg \
> -o localhost:7050 \
> --ordererTLSHostnameOverride orderer.example.com \
> --channelID mychannel \
> --name fabcar \
> --version 1.0 \
> --package-id $CC_PACKAGE_ID \
> --sequence 2 \
> --tls \
> --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-23 07:26:01.492 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [b1d45658ff7f90866adda7ff81199386cd8dff7cd05819c48228c63eecf6b56a] committed with status (VALID) at
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ENABLED=true
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_LOCALMSPID="Org2MSP"
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/[email protected]/msp
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_ADDRESS=localhost:9051
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer lifecycle chaincode approveformyorg \
> -o localhost:7050 \
> --ordererTLSHostnameOverride orderer.example.com \
> --channelID mychannel \
> --name fabcar \
> --version 1.0 \
> --package-id $CC_PACKAGE_ID \
> --sequence 2 \
> --tls \
> --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-23 07:26:33.901 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [078f3ee511dca0c29f0af021fdf154b3ca05a0ac62f2c7d05c8c77c804cb0f8a] committed with status (VALID) at
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer lifecycle chaincode checkcommitreadiness \
> --channelID mychannel \
> --name fabcar \
> --version 1.0 \
> --sequence 2 \
> --tls \
> --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
> --output json
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ENABLED=true
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_LOCALMSPID="Org1MSP"
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_ADDRESS=localhost:8051
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer chaincode query \
> -C mychannel \
> -n fabcar \
> -c '{"Args":["queryAllCars"]}'
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
向網路中新增組織
為 Org3生成證書檔案
在另一個終端中,addOrg3從 test-network.
cd addOrg3
首先,我們將為 Org3 對等方以及應用程式和管理員用戶創建證書和密鑰,因為我們正在更新一個示例通道,所以我們將使用 cryptogen 工具而不是使用證書頒發機構,以下命令使用 cryptogen 讀取org3-crypto.yaml檔案并在新org3.example.com檔案夾中生成 Org3 加密材料:
cryptogen generate --config=org3-crypto.yaml --output="../organizations"
您可以在目錄中找到生成的 Org3 加密材料以及 Org1 和 Org2 的證書和密鑰:test-network/organizations/peerOrganizations.
一旦我們創建了 Org3 加密材料,我們就可以使用 configtxgen 工具列印出 Org3 組織定義,
我們將通過告訴工具在當前目錄中查找configtx.yaml 它需要攝取的檔案來開始命令,
export FABRIC_CFG_PATH=$PWD
configtxgen -printOrg Org3MSP > ../organizations/peerOrganizations/org3.example.com/org3.json
上面的命令創建了一個 JSON 檔案 org3.json 并將其寫入下面檔案夾,
test-network/organizations/peerOrganizations/org3.example.com/
組織定義包含 Org3 的策略定義、Org3 的 NodeOU 定義以及兩個以 base64 格式編碼的重要證書:
- CA 根證書,用于建立組織間的信任根
- 一個 TLS 根證書,由 gossip 協議用于標識 Org3 以進行塊傳播和服務發現
我們將通過將此組織定義附加到通道配置來將 Org3 添加到通道中,
調出 Org3 組件
就是 啟動 組織 3 的 peer 節點
創建 Org3 證書材料后,我們現在可以啟動 Org3 對等體,從addOrg3目錄中,發出以下命令:
docker-compose -f docker/docker-compose-org3.yaml up -d
如果命令成功,您將看到 Org3 peer 的創建:
Creating peer0.org3.example.com ... done
此 Docker Compose 檔案已配置為跨我們的初始網路橋接,以便 Org3 對等節點與測驗網路的現有對等節點和排序節點進行決議,
獲取配置
讓我們去獲取頻道的最新配置塊 – channel1,
我們必須拉取最新版本的配置的原因是因為通道配置元素是版本化的,
出于多種原因,版本控制很重要,它可以防止重復或重放配置更改(例如,使用舊 CRL 恢復到通道配置將代表安全風險),它還有助于確保并發性(如果您想從頻道中洗掉組織,例如,在添加新組織后,版本控制將有助于防止您洗掉兩個組織,而不僅僅是要洗掉的組織),
導航回test-network目錄,因為 Org3 還不是頻道的成員,我們需要以另一個組織的管理員身份操作來獲取頻道配置,因為 Org1 是頻道的成員,所以 Org1 管理員有權從排序服務中獲取頻道配置,發出以下命令以作為 Org1 管理員進行操作,
# you can issue all of these commands at once
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
我們現在可以發出命令來獲取最新的配置塊:
peer channel fetch config channel-artifacts/config_block.pb \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--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發出命令后,日志中會顯示以下輸出:
2021-11-11 15:32:31.586 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-11 15:32:31.592 CST [cli.common] readBlock -> INFO 002 Received block: 2
2021-11-11 15:32:31.592 CST [channelCmd] fetch -> INFO 003 Retrieving last config block: 2
2021-11-11 15:32:31.595 CST [cli.common] readBlock -> INFO 004 Received block: 2
這告訴我們最近的配置塊channel1實際上是塊 2,而不是創世塊,
默認情況下,該 命令回傳目標通道的最新配置塊,在這種情況下是第三個塊,
這是因為測驗網路腳本為我們的兩個組織定義了錨點,并且在兩個單獨的通道更新事務中,因此,我們有以下配置序列:
- block 0: genesis block
- block 1: Org1 anchor peer update
- block 2: Org2 anchor peer update
通道組態檔夾下新增塊資訊檔案
├── channel-artifacts
│ ├── channel1.block
│ ├── channel1.tx
│ └── config_block.pb # 新增
將配置轉換為 JSON 并對其進行修剪
通道配置塊存盤在channel-artifacts檔案夾中,以使更新程序與其他工件分開,進入 channel-artifacts 檔案夾以完成以下步驟:
cd channel-artifacts
- 使用該configtxlator工具將這個通道配置塊解碼為 JSON 格式(可以被人類讀取和修改)
configtxlator proto_decode \
--input config_block.pb \
--type common.Block \
--output config_block.json
- 去除所有與我們想要進行的更改無關的標題、元資料、創建者簽名等
帶有陣列的情況下,加引號,這個命令給我們留下了一個精簡的 JSON 物件 config.json 它將作為我們配置更新的基線,
jq '.data.data[0].payload.data.config' config_block.json > config.json
添加 Org3 加密材
jq 語法參考
jq 官方檔案
| 選項 | 解釋 | 備注 |
|---|---|---|
| -s | read (slurp) all inputs into an array; apply filter to it | 使用-s 選項,jq 會將所有的 JSON 輸入放入一個陣列中并在這個陣列上使用 filter,"-s"選項不但影響到 filter 的寫法,如果在 filter 中需要對資料進行選擇和映射,其還會影響最終結果, |
jq -s '.[0] * .[1]' 輸入流1 輸入流2 > test.json
.[0]:由第1個輸入流產生的陣列資料.[1]:由第2個輸入流產生的陣列資料*:參考官方檔案
Multiplication, division, modulo: *, /, and %
These infix operators behave as expected when given two numbers. Division by zero raises an error. x % y computes x modulo y.
Multiplying a string by a number produces the concatenation of that string that many times. "x" * 0 produces null.
Dividing a string by another splits the first using the second as separators.
Multiplying two objects will merge them recursively: this works like addition but if both objects contain a value for the same key, and the values are objects, the two are merged with the same strategy.
增加配置資訊
我們將jq再次使用該工具將 Org3 配置定義 org3.json添加到通道的應用程式組欄位,并將輸出命名為 modified_config.json,
jq -s \
'.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' \
config.json \
../organizations/peerOrganizations/org3.example.com/org3.json \
> modified_config.json
增量計算,得到更新增量
現在我們有兩個感興趣的 JSON 檔案 config.json和 modified_config.json. 初始檔案僅包含 Org1 和 Org2 材料,而修改后的檔案包含所有三個 Org,
此時,只需重新編碼這兩個 JSON 檔案并計算增量即可,
- 首先,轉換
config.json回一個名為的protobuf config.pb
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計算這兩個配置protobufs之間的增量,此命令將輸出一個名為的新 protobuf 二進制檔案org3_update.pb
configtxlator compute_update \
--channel_id channel1 \
--original config.pb \
--updated modified_config.pb \
--output org3_update.pb
這個新的 proto org3_update.pb包含 Org3 定義和指向 Org1 和 Org2 材料的高級指標,
封裝更新資訊
在提交頻道更新之前,我們需要執行一些最后的步驟,
- 首先,讓我們將此物件解碼為可編輯的 JSON 格式并呼叫它
org3_update.json
configtxlator proto_decode \
--input org3_update.pb \
--type common.ConfigUpdate \
--output org3_update.json
現在,我們有一個解碼后的更新檔案org3_update.json.我們需要將它包裝一下,
這一步將回傳我們之前剝離的頭欄位,我們將此檔案命名為org3_update_in_envelope.json:
echo '{"payload":{"header":{"channel_header":{"channel_id":"'channel1'", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json
使用我們正確形成的 JSONorg3_update_in_envelope.json我們將configtxlator最后一次利用該工具并將其轉換為 Fabric 所需的完全成熟的 protobuf 格式,我們將命名我們的最終更新物件org3_update_in_envelope.pb:
configtxlator proto_encode \
--input org3_update_in_envelope.json \
--type common.Envelope \
--output org3_update_in_envelope.pb
簽署并提交配置更
簽署
現在有一個 protobuf 二進制檔案 org3_update_in_envelope.pb. 但是,在將配置寫入分類帳之前,我們需要必需的管理員用戶的簽名,
我們頻道應用程式組的修改策略 (mod_policy) 設定為默認值“MAJORITY”,這意味著我們需要大多數現有組織管理員對其進行簽名,
因為我們只有兩個組織——Org1 和 Org2——而且兩個組織中的大多數是兩個,==所以我們需要他們都簽名==,
如果沒有這兩個簽名,排序服務將拒絕未能滿足策略的交易,
- 首先,讓我們將此更新協議簽名為 Org1,導航回test-network 目錄:
請記住,我們匯出了必要的環境變數以作為 Org1 管理員進行操作,因此,以下命令會將更新簽名為 Org1,peer channel signconfigtx
peer channel signconfigtx -f channel-artifacts/org3_update_in_envelope.pb
最后一步是切換容器的身份以反映 Org2 Admin 用戶,我們通過匯出特定于 Org2 MSP 的四個環境變數來做到這一點,
設定 Org2 環境變數:
# you can issue all of these commands at once
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:9051
更新
最后,我們將發出peer channel update命令,Org2 Admin 的簽名將附加到此呼叫中,因此無需再次手動簽署 protobuf,(更新角色會自動簽署并且更新通道配置資訊)
peer channel update -f channel-artifacts/org3_update_in_envelope.pb -c channel1 -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
成功的通道更新呼叫會向通道上的所有對等方回傳一個新塊:塊 3,
如果您還記得,塊 0-2 是初始通道配置,Block 3 作為最新的通道配置,現在在通道上定義了 Org3,
您可以peer0.org1.example.com通過發出以下命令來檢查日志:
docker logs -f peer0.org1.example.com
將 Org3的節點加入頻道
此時,通道配置已更新為包括我們的新組織 Org3,這意味著它的對等節點現在可以加入channel1,
匯出以下環境變數以作為 Org3 管理員進行操作:
# you can issue all of these commands at once
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:11051
作為通道更新成功的結果,排序服務將驗證 Org3 是否可以拉取創世塊并加入通道,如果 Org3 未成功附加到通道配置,則排序服務將拒絕此請求,
使用命令來檢索這個塊:peer channel fetch
peer channel fetch 0 channel-artifacts/channel1.block \
-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
2021-11-11 17:40:23.213 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-11 17:40:23.220 CST [cli.common] readBlock -> INFO 002 Received block: 0
請注意,我們正在傳遞 0以指示我們想要通道分類帳上的第一個塊;即創世區塊,
如果我們簡單地傳遞命令 peer channel fetch config,那么我們將收到塊 3——定義了 Org3 的更新配置,但是,我們不能從下游塊開始我們的賬本——我們必須從塊 0 開始,
如果成功,該命令會將創世塊回傳名為channel1.block. 我們現在可以使用此塊channel1.block將peer加入通道,
發出命令peer channel join并傳入創世塊以將 Org3 peer 加入通道:
peer channel join -b channel-artifacts/channel1.block
2021-11-12 10:59:01.939 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-12 10:59:02.017 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
查詢結果
在 Org3的環境下查看該peer peer0.org3.example.com加入的通道
# you can issue all of these commands at once
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:11051
peer channel list
(base) test-network|5b8c439? ? peer channel list
2021-11-11 17:50:00.527 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
channel1
升級網路
升級orderer節點
升級每個orderer時,都需要執行以下操作,
配置orderer容器中的環境變數
vim upgrade.orderer.sh
方便起見,orderer容器運行時需要的環境變數可以記錄在檔案中,具體內容如下:
FABRIC_LOGGING_SPEC=INFO
FABRIC_CFG_PATH=/etc/hyperledger/fabric
ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
ORDERER_GENERAL_GENESISMETHOD=file
# 創世區塊
ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
ORDERER_GENERAL_LOCALMSPID=OrdererMSP
ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
# enabled TLS
ORDERER_GENERAL_TLS_ENABLED=true
ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
設定升級時的環境變數
在升級排序節點前匯入以下環境變數:
- ORDERER_CONTAINER:排序節點的容器名稱,注意,每個節點升級時你都樣設定一遍,
- LEDGERS_BACKUP:存放備份資料的路徑,就如下面的示例中,每個節點都有它自己的子目錄來存放它的賬本,目錄如果不存在的話,你需要手動創建,
- IMAGE_TAG:你期望升級到的Fabric版本,
示例如下:
export ORDERER_CONTAINER=orderer.example.com
export LEDGERS_BACKUP=backup
export IMAGE_TAG=2.2.3
檔案準備
- 備份位置
mkdir -p $LEDGERS_BACKUP/$ORDERER_CONTAINER
- 創世塊,msp,tls
cp ../system-genesis-block/genesis.block backup/orderer.genesis.block
cp -r ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp backup
cp -r ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls backup
停止容器
docker stop $ORDERER_CONTAINER
備份賬本
docker cp $ORDERER_CONTAINER:/var/hyperledger/production/orderer $LEDGERS_BACKUP/$ORDERER_CONTAINER
洗掉容器
docker rm -f $ORDERER_CONTAINER
升級容器
docker run -d \
-v /root/fabric-samples/test-network/backup/$ORDERER_CONTAINER/:/var/hyperledger/production/orderer/ \
-v /root/fabric-samples/test-network/backup:/var/hyperledger/orderer \
--env-file ./backup/env-update-container-orderer.yaml \
--name $ORDERER_CONTAINER \
--net fabric_test \
hyperledger/fabric-orderer:$IMAGE_TAG orderer
docker run -d \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/test-network/upgrade/backup/$ORDERER_CONTAINER/:/var/hyperledger/production/orderer/ \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/test-network/upgrade/backup/:/var/hyperledger/orderer/ \
--env-file ./upgrade.orderer.sh \
--name $ORDERER_CONTAINER \
hyperledger/fabric-orderer:$IMAGE_TAG orderer
升級peer節點
以peer0org1節點為例,以下操作每個peer節點都需要執行,
配置peer運行時的環境變數
方便起見,peer容器運行時需要的環境變數可以記錄在檔案中,具體內容如下:
CORE_PEER_LOCALMSPID=Org1MSP
CORE_PEER_GOSSIP_USELEADERELECTION=true
CORE_PEER_ID=peer0.org1.example.com
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
FABRIC_CFG_PATH=/etc/hyperledger/fabric
CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=net_byfn
CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
CORE_PEER_PROFILE_ENABLED=true
CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
CORE_PEER_LISTENADDRESS=0.0.0.0:7051
CORE_PEER_GOSSIP_ORGLEADER=false
CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:8051
CORE_PEER_TLS_ENABLED=true
FABRIC_LOGGING_SPEC=INFO
CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
設定升級時的環境變數
在升級peer節點前匯入以下環境變數:
- PEER_CONTAINER:peer節點的容器名稱,注意,每個節點升級時你都樣設定一遍,
- LEDGERS_BACKUP:存放備份資料的路徑,就如下面的示例中,每個節點都有它自己的子目錄來存放它的賬本,目錄如果不存在的話,你需要手動創建,
- IMAGE_TAG:你期望升級到的Fabric版本,例如v2.0,
示例如下:
export PEER_CONTAINER=peer0.org1.example.com
export LEDGERS_BACKUP=backup
export IMAGE_TAG=2.2.3
停止容器
docker stop $PEER_CONTAINER
備份賬本和MSPs
docker cp $PEER_CONTAINER:/var/hyperledger/production $LEDGERS_BACKUP/$PEER_CONTAINER
洗掉CC容器
CC_CONTAINERS=$(docker ps | grep dev-$PEER_CONTAINER | awk '{print $1}')
if [ -n "$CC_CONTAINERS" ] ; then docker rm -f $CC_CONTAINERS ; fi
洗掉peer容器
docker rm $PEER_CONTAINER
升級peer節點
docker run -d \
-e FABRIC_CFG_PATH=/etc/hyperledger/fabric \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/test-network/upgrade/$LEDGERS_BACKUP/$PEER_CONTAINER/:/var/hyperledger/production/ \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/fabric/ \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/config/core.yaml:/etc/hyperledger/fabric/core.yaml \
--env-file ./upgrade.org1.peer0.sh \
--name $PEER_CONTAINER \
hyperledger/fabric-peer:$IMAGE_TAG peer node start
升級peer節點資料庫
docker run --rm \
-v $LEDGERS_BACKUP/$PEER_CONTAINER:/var/hyperledger/production/ \
-v /var/run/:/host/var/run/ \
-v $FABRIC_SAMPLES/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp \
-v $FABRIC_SAMPLES/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls \
-p 7051:7051 \
--env-file env_peer.list \
--net net_byfn \
--name $PEER_CONTAINER \
hyperledger/fabric-peer:$IMAGE_TAG peer node upgrade-dbs
舊版本的鏈碼
進入原始碼
cd $GOPATH/src/github.com/hyperledger/fabric-samples/chaincode/sacc
下載依賴
GO111MODULE=on
go mod vendor
cd ../../test-network/
打包
peer lifecycle chaincode package sacc.tar.gz --path ../chaincode/sacc/ --lang golang --label sacc_1
更新環境變數
作為組織1管理員
source org1-env.sh
作為組織2管理員
source org2-env.sh
安裝
peer lifecycle chaincode install sacc.tar.gz
##查詢
peer lifecycle chaincode queryinstalled
設定包ID
export CC_PACKAGE_ID=sacc_1:b33357c4012471d8bd96ba48fd2a12ada5fedfbfd6d623590295778500a0368d
批準
peer lifecycle chaincode approveformyorg \
--init-required \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name sacc \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
檢查批準情況
peer lifecycle chaincode checkcommitreadiness \
--init-required \
--channelID mychannel \
--name sacc \
--version 1.0 \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--output json
提交
peer lifecycle chaincode commit \
--init-required \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name sacc \
--version 1.0 \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--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
查詢
peer lifecycle chaincode querycommitted --channelID mychannel --name sacc
初始化
peer chaincode invoke -o localhost:7050 \
--isInit \
--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 sacc \
--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 '{"Args":["name","binny"]}'
呼叫
peer chaincode query -C mychannel -n sacc -c '{"Args":["get","name"]}'
清理
docker stop logspout && docker rm logspout &&
docker rm -f $(docker ps | grep "hyperledger" | awk '{print $1}')
- 移除鏈碼相關鏡像
docker rmi $(docker images | grep "dev-peer" | awk '{print $3}')
- 移除 fabric相關鏡像
docker rmi $(docker images | grep "hyperledger" | awk '{print $3}')
docker network prune -f && docker volume prune -f
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/449774.html
標籤:其他
上一篇:服務器回傳狀態碼總結
