peer如何加入一个channel
第一步:获取channel的genesis block
这个block是在channel创建的时候生成的本地文件。
如果已经找不到了,那么可以重新从orderer获取,方法如下:
#!/bin/bash
export CORE_PEER_LOCALMSPID=SameOrgMSP
export CORE_PEER_MSPCONFIGPATH=msp
peer channel fetch 0 mychannel.pb -o orderer.example.com:7050 -c mychannel
从orderer拉取channel的genesis block(fetch 0指的是拉取第0个block,即genesis block)并存放在本地文本mychannel.pb,这是一个protocol buffer格式的文件。当然不可读了。
注意如果channel的orderer地址曾经发生过改变,那么mychannel.pb中存放的orderer地址和目前使用的地址(orderer.example.com:7050)就会不一致,而此时如果使用mychannel.pb来join channel就会失败,因为orderer地址不匹配。
聪明的你可能立马会想到,那可以从orderer拉取最新的channel配置块啊,他里面的orderer信息必然是正确的。
peer channel fetch config mychannel.pb -o orderer.example.com:7050 -c mychannel
(fetch config指的是拉取最新的config block)
遗憾的是,这个方法也行不通;在peer加入channel的时候要求提供的block number必须为0,也就是必须为genesis block,而拿到的最新的配置块的block number肯定不是0。
Error: proposal failed (err: rpc error: code = Unknown desc = chaincode error (status: 500, message: Cannot create ledger from genesis block, due to Expected block number=0, recived block number=4))
这岂不是两难了。怎么办呢,幸好fabric留了一个漏洞,不知道是不是bug。
我们可以把拉下来的 genesis block进行修改,把里面的orderer地址改了,改成正确的orderer地址,然后再加入channel,这样既能使用正确的orderer地址,又保证block number为0。
步骤1.2: 把genesis block转换成json格式。
configtxlator proto_decode --input mychannel.pb --type common.Block --output mychannel.json
步骤1.3:修改orderer地址
"OrdererAddresses": {
"mod_policy": "/Channel/Orderer/Admins",
"value": {
"addresses": [
- "orderer.ordererorg.example.com:7050"
+ "orderer.example.com:7050"
]
},
如上例子,我们把orderer地址从原来的"orderer.ordererorg.example.com:7050"改成了新的"orderer.example.com:7050"。
步骤1.4:重新把json格式转换回pb格式
configtxlator proto_encode --input mychannel.json --type common.Block --output mychannel-new.pb
第二步:加入channel
#!/bin/bash
CHANNEL=mychannel
PEER=peer0
export CORE_PEER_ID=${PEER}.org1.example.com
export CORE_PEER_ADDRESS=${PEER}.org1.example.com:7051
export CORE_PEER_LOCALMSPID=PeerOrgMSP
export CORE_PEER_MSPCONFIGPATH=msp
#peer channel join -b ./${CHANNEL}.block
peer channel join -b ./${CHANNEL}-new.pb
另外思考一个问题,经过修改后的genesis block显然已经不是最初的那个genesis block了,那么在新加入的这个peer上channel的genesis block是修改后的genesis block呢,还是从orderer同步过来的最原始的那个genesis block呢?
另外还要注意一点:
一个peer只能加入一个channel一次,所以如果一个peer已经在一个channel里面了,那么就不能再加入了。
Error: proposal failed (err: rpc error: code = Unknown desc = chaincode error (status: 500, message: Cannot create ledger from genesis block, due to LedgerID already exists))