跟随 hyperledger 官方文档提供的 fabric-samples , 详细查看了 byfn.sh 脚本中的详细步骤, 再接着看 eyfn.sh 脚本中,向已有网络中添加机构的详细步骤。
将在 byfn.sh 的基础上, 主要详细描述 eyfn.sh 脚本中的每个步骤。
首先通过命令,直接构建基础包含 Org1 和 Org2 的网络
./byfn.sh down ./byfn.sh generate ./byfn.sh up
然后用 vim 修改目录下的 docker-compose-cli.yaml 和 docker-compose-org3.yaml 文件的日志级别为 DEBUG:
cli: container_name: cli image: hyperledger/fabric-tools:$IMAGE_TAG tty: true stdin_open: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock #- FABRIC_LOGGING_SPEC=INFO - FABRIC_LOGGING_SPEC=DEBUG
以及
Org3cli: container_name: Org3cli image: hyperledger/fabric-tools:$IMAGE_TAG tty: true stdin_open: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock #- FABRIC_LOGGING_SPEC=INFO - FABRIC_LOGGING_SPEC=DEBUG
做好准备事项后, 开始进入添加 Org3 机构的处理。
一,
使用 cryptogen 命令, 为 Org3 生成对应的 ca, key 和 msp 等信息。
进入 first-network 中 org3-artifacts 目录,执行以下命令:
cryptogen generate --config=./org3-crypto.yaml
和之前的一样,命令产生一个新的文件夹,存放了 Org3 对应的身份验证信息。
然后再使用 configtxgen 命令产生 Org3 的配置信息文件(后面往渠道中添加 Org3 将使用到这个生成的文件)
export FABRIC_CFG_PATH=$PWD && configtxgen -printOrg Org3MSP > ../channel-artifacts/org3.json
注意,这里已经是把包含 cryptogen 和 configtxgen 的 bin 目录加入到环境变量中。
这个命令在 channel-artifacts 目录中创建 Org3 的配置信息文件。
在进入下一步之前,将 orderer 的 MSP 信息文件复制到 org3 中的 crypto-config 目录下, 目的是为了能让 Org3 和网络中的 orderer 节点进行交互
cd ../ && cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/
二,
准备 cli 的环境, 在 byfn.sh 的详细解析中, 提到 cli 是依赖了 Org1 和 Org2 以及 orderer 服务的一个 docker 镜像,即代表了整个 hyperledger 的网络,将在 cli 的基础上操作 Org3 机构的添加。
进入 cli 镜像中
docker exec -it cli bash
首先设置两个环境变量
export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem && export CHANNEL_NAME=mychannel
三,
获取最新的渠道配置信息,在对渠道配置进行修改(添加一个机构)之前,先获取到当前渠道的最新配置信息,因为渠道配置信息是带有版本号的,在修改之前获取最新版本的配置信息,匹配上版本信息号,配置修改才能成功。
执行以下命令,
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
返回了许多信息,最后一行值得注意:
这里返回的块数是2 ,当前链中个三个 block 分别是 :
block 0: genesis block 创世块 block 1: Org1 anchor peer update Org1 的锚节点更新 block 2: Org2 anchor peer update Org2 的锚节点更新
其中,后面的两块来自于 byfn.sh 脚本。
四,
获取最新版本的配置信息后,可以把 Org3 的信息添加到配置中了。
这里将使用到 configtxlator 命令, 这个命令可以将 fetch 返回的 protobuf 格式的文件转换成可以被人看懂的 json 格式的文件。
还有 jq 工具,可以帮助去掉文件中的空格,签名串等信息, 只保留想要的配置改变信息。
执行以下命令:
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json
可以看到 protobuf 格式的文件 config_block.pb 被转换成一个 config.json 文件。
五,
接下来将在 config.json 的基础上,将 Org3 的信息加入到渠道中。
首先使用 cryptogen 产生的 org3.json 文件和 config.json 进行拼接
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./channel-artifacts/org3.json > modified_config.json
将在当前目录下产生 modified_config.json 文件, 这里产生的区别就是,原来的 config.json 文件中,只包含了 Org1 和 Org2 ,而新生成的文件中还包含了 Org3 .
接下来,根据这两个文件,计算出配置改变的信息部分。
通过把原来的 config.json 转成 pb 格式, 把 modified_config.json 转成 bp 格式, 然后使用命令计算成修改的部分
configtxlator proto_encode --input config.json --type common.Config --output config.pb configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output org3_update.pb
执行完成后将产生3个 pb 文件,需要用到的是最后产生的。
将产生的 org3_update.pb 文件转换成 json 格式, 然后再由此 json 文件产生一个信封消息(envelope message)文件,然后再由这份文件产生最终的配置更新文件,
configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate | jq . > org3_update.json echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb
执行后,产生了所需的文件。
之后,在提交之前,需要使用 Org1 和 Org2 对当前渠道的改变进行签名验证。
因为当前 cli 网络是根据 Org1 MSP 信息启动的,所以直接执行签名命令即可
peer channel signconfigtx -f org3_update_in_envelope.pb
对于 Org2 ,需要改变相应的环境变量,
CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 peer channel signconfigtx -f org3_update_in_envelope.pb
经过 Org1 和 Org2 的签名后,可以执行更新命令了
peer channel update -f org3_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA
通过命令行返回结果,可以看到更新事务已成功提交。
六,
更新完渠道配置后,还需要将 Org3 添加到渠道中。
开启一个新的终端,到 fabric-samples 目录下, 执行以下命令
docker-compose -f docker-compose-org3.yaml up -d
可以看到添加了一个新的 Org3cli 的 docker 镜像。
进入 Org3cli 中,
docker exec -it Org3cli bash
首先设置下环境变量
export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem && export CHANNEL_NAME=mychannel
现在,让 Org3 请求 orderer 节点,返回当前 ledger 的创世块,证明 orderer 节点可以验证 Org3在当前渠道中的身份。
peer channel fetch 0 mychannel.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
这里的 0 表示的,既是创世块。
查看返回结果, orderer 验证了 Org3 的身份。
此时,执行 peer channel join 命令, 即可将 Org3 加入到 channel 中
身份信息验证通过,并成功提交加入渠道的事务。
七,
加入渠道后,现在可以尝试调用 chaincode 了。
peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/
安装成功,返回状态码 200.
此时,返回之前的 cli, Org1 和 Org2 的那个网络,更新此时的 chaincode
peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/ CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/
改变环境变量切换到 Org2 ,重新执行安装命令
安装成功, 状态码返回200.
更新 chaincode, 执行以下命令
peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')"
和之前一样,初始化了 a 和 b 参数的值, 用 -P 参数指定了 endorsement 政策
更新完成后,可以通过 query 或者 invoke 对设置的值进行查询和修改
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'