fabric2.2 测试网络部署及操作流程(Ubuntu 18+)
枫叶海棠 -警告
在执行测试项目时,多次使用并修改此文件,部分地方没有及时更新.如果问题请联系 487008159 更正.
必看项目:fabric-samples
工作目录 : ~/go/src/github.com/hyperledger/fabric-samples/test-network
#!/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/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
组织 2env-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/Admin@org2.example.com/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/Admin@example.com/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: zhnlion@126.com
# 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/hyperledge...
下载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
.
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
设置包 IDpeer 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/xubinbin102...
升级链码更新背书策略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
.
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/Admin@org1.example.com/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/Admin@example.com/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/Admin@org1.example.com/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
│ │ ├── Admin@org1.example.com
│ │ └── User1@org1.example.com
新增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/Admin@org1.example.com/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/Admin@org2.example.com/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/Admin@org1.example.com/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/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 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 blockblock 1: Org1 anchor peer updateblock 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 官方文档
选项解释备注-sread (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/Admin@org2.example.com/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/Admin@org3.example.com/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/Admin@org3.example.com/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,tlscp ../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
备份账本和MSPsdocker 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
设置包IDexport 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