Fabric 2.0 之动态添加组织

启动环境

  在开始本博客之前,请确保已安装对应版本的二进制工具、镜像以及git clone fabric-samples

cd fabric-samples/test-network

  如果之前启动过test-network下的network.sh脚本,执行以下命令清除之前的环境。

./network.sh down

  使用脚本启动测试网络(默认通道mychannel):

./network.sh up createChannel

  如果命令无误,shell窗口最后会打印:========= Channel successfully joined ===========
在这里插入图片描述

使用脚本添加Org3

  执行脚本,会看到生成Org3的证书,创建Org3组织定义,然后通道配置被更新、签名、提交到通道。

cd addOrg3
./addOrg3.sh up

  如果命令无误,shell窗口最后会打印:
  ========= Finished adding Org3 to your test network! =========
在这里插入图片描述

手动执行命令添加Org3到通道

  前一节我们使用官方提供的脚本,自动帮我们完成各种操作,为了更好地理解执行过程,本节我们尝试手动执行各种命令。
  清除先前的环境

./addOrg3.sh down

  返回原目录,再次构建两组织的fabric网络

cd ..     
./network.sh up createChannel

生成Org3的证书

  这里我们使用cryptogen 生成组织三Peer节点的证书,cryptogen根据addOrg3/org3-crypto.yaml生成证书。

cd addOrg3
../../bin/cryptogen generate --config=org3-crypto.yaml --output="../organizations"

  命令执行完会在test-network/organizations/peerOrganizations看到Org3的证书,生成完证书之后,我们可以使用configtxgen打印出Org3的定义,使用的是当前目录(fabric-samples/test-network/addOrg3)下的configtx.yaml文件。

export FABRIC_CFG_PATH=$PWD
../../bin/configtxgen -printOrg Org3MSP > ../organizations/peerOrganizations/org3.example.com/org3.json

  上面的命令创建一个JSON文件org3.json并将其写入test-network / organizations / peerOrganizations / org3.example.com文件夹。 组织定义包含Org3的策略定义以及以base64格式编码的三个重要证书:CA证书、TLS证书、admin用户证书

启动Org3的节点及Cli

docker-compose -f docker/docker-compose-org3.yaml up -d

  命令执行成功后,将会启动Peer:peer0.org3.example.com容器和Org3CLI容器。
在这里插入图片描述

准备Cli环境

  进入容器

docker exec -it Org3cli bash

  设置变量

export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CHANNEL_NAME=mychannel

获取配置

  我们需要获取最新版本的通道配置,由于Org3不是通道成员,因此我们这里使用Org1(或使用Org2)管理员身份进行操作。

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

  获取最新的配置

peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

  上面命令将二进制protobuf通道配置块保存到config_block.pb(名称和文件扩展名可任意设置),输出结果:
在这里插入图片描述
  通过上面截图,我们可以得知mychannel的最新配置块是块2(块号为2,也就是第三个块),而不是创世块。 这是因为测试网络脚本network.sh更新了Org1和Org2的锚节点。
  block 0: 创世块
  block 1: Org1 锚节点更新
  block 2: Org2 锚节点更新

通道配置块转换成JSON

  现在,我们将使用configtxlator工具将此通道配置块解码为JSON格式。 我们还必须删除所有与我们要进行的更改无关的标题,元数据,创建者签名等。 我们通过jq工具完成此任务:

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

  上面命令为我们提供了经过精简的JSON对象config.json,它将作为配置更新的基准。

添加Org3的证书

  我们将再次使用jq工具将Org3配置定义org3.json添加到application groups字段中,并输出经过修改的config.json。

jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./organizations/peerOrganizations/org3.example.com/org3.json > modified_config.json

  将config.json转换为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计算这两个配置协议之间的差异。 此命令将输出一个新的名为org3_update.pb的protobuf二进制文件:

configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output org3_update.pb

  org3_update.pb里面包含了Org3的定义以及指向Org1、Org2的高级指针,即增量更新,原有配置尽量不做更改。org3_update.pb转换为json文件:

configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate | jq . > org3_update.json

  增加头字段,生成新的文件org3_update_in_envelope.json

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

  转换为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

签名并提交配置更新

  在将配置写入账本之前,我们需要来自Admin用户的签名。通道修改策略(mod_policy)为默认值“ MAJORITY”,即大多数现有的组织管理员来对其进行签名。 因为我们只有两个组织 Org1和Org2 ,大多数是两个,所以我们都需要它们进行签名。
  由于先前我们登陆身份为Org1的管理员,这里我们先以Org1的身份进行签名:

peer channel signconfigtx -f org3_update_in_envelope.pb

  切换身份为Org2的管理员:

export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org2.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051

  执行peer channel update命令(Org2的签名附加到调用中)

peer channel update -f org3_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA

  如果执行成功,会返回一个新的块:block3。过程中也可以再开一个shell监控日志:

docker logs -f peer0.org1.example.com

Org3加入通道

  切换到Org3的admin

export CORE_PEER_LOCALMSPID="Org3MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org3.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org3.example.com:11051

  我们必须从区块0开始,注意此处不是block3

peer channel fetch 0 mychannel.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

  加入通道

peer channel join -b mychannel.block

配置Leader选举

  分为静态配置和动态选举。
  静态配置(所有Peer节点均在yaml文件中进行如下配置)

CORE_PEER_GOSSIP_USELEADERELECTION=false
CORE_PEER_GOSSIP_ORGLEADER=true

  动态选举

CORE_PEER_GOSSIP_USELEADERELECTION=true
CORE_PEER_GOSSIP_ORGLEADER=false

  由于新增加的组织Peer获取不到原有的成员视图,因此此选项类似于静态配置,刚开始每个Peer都宣称自己是Leader,当通道配置更新后,则仅有一个活跃的Leader。

完成链码周期2.0

  此处我们需要再打开一个shell窗口,利用官方脚本为Org1和Org2的Peer部署链码fabar:

cd fabric-samples/test-network
./network.sh deployCC

在这里插入图片描述
  可以留意到在checkcommitreadiness时,已经变成三个组织。我们可以通过以下步骤给Org3部署Fabcar链码,以下命令在test-network目录执行,无需在Org3CLI容器中执行:

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

  打包链码:

peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/go/ --lang golang --label fabcar_1

  安装链码:

peer lifecycle chaincode install fabcar.tar.gz

  Org3需要像Org1和Org2那样同意链码定义,因此需要先获取Package ID

peer lifecycle chaincode queryinstalled

  Package ID: fabcar_1:aca5cf806d53b8860e3bc4234af8fe9a017e7082d98108e07ffc7ea36dbc2e07, Label: fabcar_1
  同意链码定义

export CC_PACKAGE_ID=fabcar_1:aca5cf806d53b8860e3bc4234af8fe9a017e7082d98108e07ffc7ea36dbc2e07
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 1 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

  查询已提交的链码定义

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

在这里插入图片描述
  由于我们使用的是默认的背书策略,即大多数组织认可。之前我们需要Org1与Org2两个的同意,现在我们需要Org1、Org2、Org3中的任意两个同意即可。
  等待一段时间,Org3节点链码容器启动可能需要一定的时间。如下图,peer0.org3.example.com对应的链码容器已启动:
在这里插入图片描述
  在peer0.org3.example.com节点查询

peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'

  在peer0.org3.example.com节点invoke:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls true --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n fabcar --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:11051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt -c '{"function":"createCar","Args":["CAR11","Honda","Accord","Black","Tom"]}'

  在peer0.org3.example.com节点查询

peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'

在这里插入图片描述

结论

  虽然过程中较为复杂,但是最终的逻辑是一步一步得到一个以protobuf二进制格式表示的增量对象,然后获取必要数量的管理员签名以满足通道更新策略。过程中使用了configtxlator和jq工具以及Peer channel命令。

猜你喜欢

转载自blog.csdn.net/weixin_43839871/article/details/106432905