拆解fabric-sample/first-network/拆解eyfn.sh——拓展账本增加新成员
This tutorial serves as an extension to the Building Your First Network (BYFN) tutorial, and will demonstrate the addition of a new organization – Org3 – to the application channel (mychannel) autogenerated by BYFN. It assumes a strong understanding of BYFN, including the usage and functionality of the aforementioned utilities.
原文参考
eyfn.sh脚本主要是用来拓展前一节中的fabric网络,在原来的Org1和Org2的基础上,新增Org3成员。
还是从eyfn.sh的执行过程来看一下新增成员的过程中经历了什么。
脚本拆解
执行命令
eyfn.sh脚本的执行还是保持原来的“./eyfn.sh up”
我们传入up以后,可以看到脚本调用了networkUp方法
#Create the network using docker compose
if [ "${MODE}" == "up" ]; then
networkUp
elif [ "${MODE}" == "down" ]; then ## Clear the network
networkDown
elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts
generateCerts
generateChannelArtifacts
createConfigTx
elif [ "${MODE}" == "restart" ]; then ## Restart the network
networkDown
networkUp
else
printHelp
exit 1
fi
方法跟踪
# Generate the needed certificates, the genesis block and start the network.
function networkUp () {
# generate artifacts if they don't exist
if [ ! -d "org3-artifacts/crypto-config" ]; then
##生成cert文件
generateCerts
##生成org3的节点资料
generateChannelArtifacts
##创建修改文件的配置
createConfigTx
fi
# start org3 peers
if [ "${IF_COUCHDB}" == "couchdb" ]; then
IMAGE_TAG=${IMAGETAG} docker-compose -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH_ORG3 up -d 2>&1
else
IMAGE_TAG=$IMAGETAG docker-compose -f $COMPOSE_FILE_ORG3 up -d 2>&1
fi
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to start Org3 network"
exit 1
fi
echo
echo "###############################################################"
echo "############### Have Org3 peers join network ##################"
echo "###############################################################"
docker exec Org3cli ./scripts/step2org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to have Org3 peers join network"
exit 1
fi
echo
echo "###############################################################"
echo "##### Upgrade chaincode to have Org3 peers on the network #####"
echo "###############################################################"
docker exec cli ./scripts/step3org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to add Org3 peers on network"
exit 1
fi
# finish by running the test
docker exec Org3cli ./scripts/testorg3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to run test"
exit 1
fi
}
方法分解
networkUp方法主要流程又分为下面几步:
- 检测是否存在证书、配置文件、新增部分配置文件等,如果不存在则新建;
- 启动Org3节点;
- 将Org3节点加入已有的mychannel通道;
- 在mychannel通道网络中更新链码,将链码版本从1.0升级到2.0;
- 执行脚本测试工作;
关键路径
生成并提交Org3的配置文件
# Use the CLI container to create the configuration transaction needed to add
# Org3 to the network
function createConfigTx () {
docker exec cli scripts/step1org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
}
篇幅原因,方法有删减
这里我们看到主要流程在step1org3.sh中,该脚本的介绍页表示了这是EYFN的第一步,创建并提交org3加入网络的配置事物文件
This script is designed to be run in the org3cli container as the first step of the EYFN tutorial. It creates and submits a configuration transaction to add org3 to the network previously setup in the BYFN tutorial.
其中主要执行命令如下:
# Fetch the config for the channel, writing it to config.json
fetchChannelConfig ${CHANNEL_NAME} config.json
# Modify the configuration to append the new org
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./channel-artifacts/org3.json > modified_config.json
# Compute a config update, based on the differences between config.json and modified_config.json, write it as a transaction to org3_update_in_envelope.pb
createConfigUpdate ${CHANNEL_NAME} config.json modified_config.json org3_update_in_envelope.pb
echo "========= Config transaction to add org3 to network created ===== "
echo "Signing config transaction"
signConfigtxAsPeerOrg 1 org3_update_in_envelope.pb
echo "========= Submitting transaction from a different peer (peer0.org2) which also signs it ========= "
peer channel update -f org3_update_in_envelope.pb -c ${CHANNEL_NAME} -o orderer.example.com:7050 --tls --cafile ${ORDERER_CA}
分别看一下上面用到的几个方法和命令
-
fetchChannelConfig
The reason why we have to pull the latest version of the config is because channel config elements are versioned.. Versioning is important for several reasons. It prevents config changes from being repeated or replayed (for instance, reverting to a channel config with old CRLs would represent a security risk). Also it helps ensure concurrency (if you want to remove an Org from your channel, for example, after a new Org has been added, versioning will help prevent you from removing both Orgs, instead of just the Org you want to remove).
官方说之所以必须提取配置的最新版本,是因为通道配置元素的版本化了,版本控制非常重要,它可以防止配置更改被重复或重播,还有助于确保并发性
用命令获取最新的区块信息
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL --cafile $ORDERER_CA
使用configtxlator proto_decode对区块信息进行解码操作
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config >"${OUTPUT}"
可以使用这个命令对所有的pb文件进行解密得到原文查看,官方也解释了这个命令:
This command saves the binary protobuf channel configuration block to config_block.pb. Note that the choice of name and file extension is arbitrary. However, following a convention which identifies both the type of object being represented and its encoding (protobuf or JSON) is recommended.
-
createConfigUpdate
Takes an original and modified config, and produces the config update tx which transitions between the two
根据原始和修改的config生成新的配置文件
configtxlator proto_encode --input "${ORIGINAL}" --type common.Config >original_config.pb configtxlator proto_encode --input "${MODIFIED}" --type common.Config >modified_config.pb configtxlator compute_update --channel_id "${CHANNEL}" --original original_config.pb --updated modified_config.pb >config_update.pb configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate >config_update.json configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope >"${OUTPUT}"
-
signConfigtxAsPeerOrg
peer channel signconfigtx -f "${TX}"
根据前一步生成的org3_update_in_envelope.pb文件进行签名操作,官方默认的修改策略是需要“MAJORITY”(超过半数)节点进行签名方可在账本中进行配置文件生效,由于我们demo中只有Org1和Org2一共2个节点,所以需要2个节点都需要签名才行。
However, we need signatures from the requisite Admin users before the config can be written to the ledger. The modification policy (mod_policy) for our channel Application group is set to the default of “MAJORITY”, which means that we need a majority of existing org admins to sign it. Because we have only two orgs – Org1 and Org2 – and the majority of two is two, we need both of them to sign. Without both signatures, the ordering service will reject the transaction for failing to fulfill the policy.
- peer channel update
上一步中提到的需要2个节点进行签名,在上一步中我们使用了Org1进行签名,这一步主要是用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}
后续的启动Org3节点、将Org3节点加入已有的mychannel通道、在mychannel通道网络中更新链码,将链码版本从1.0升级到2.0、执行脚本测试工作与之前的byfn.sh脚本中类似,只是将Org从1和2改成了3,将链码版本号从1.0改为2.0其余均一样。
谢谢。