fabric中所有的配置都是存在区块中的,包括有哪些联盟,有哪些组织机构等信息,fabric在启动网络的时候会加载这些信息。最初的联盟信息是保存在创世块中的。
在fabric中创建联盟的本质是修改系统channel的配置文件,同时将配置添加到新区快中的过程。
fabric中的联盟和通道是一对一的关系,联盟必须和通道channel并存。
1,初始配置解析
使用byfn脚本启动后,fabric网络的配置如下
该联盟的配置文件在$GOPATH/src/github.com/hyperledger/fabric-samples/first-networks/configtx.yaml
目录
Profiles标签下有几个子标签,分别是
TwoOrgsOrdererGenesis
TwoOrgsChannel
SampleDevModeKafka
SampleMultiNodeEtcdRaft
在byfn.sh启动脚本中,默认使用的启动命令就是用了TwoOrgsOrdererGenesis
configtxgen -profile TwoOrgsOrdererGenesis -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
TwoOrgsOrdererGenesis的配置如下:
TwoOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
要添加新的联盟,也就是要修改这里的配置。
接下来验证一下链上的区块是否真的使用该配置
进入cli容器,设置order_ca
环境变量,切换到切换到OrdererOrgs
的admin用户(系统通道的相关操作必须由OrdererOrgs
的admin用户来执行):
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 CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER_CA
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin@example.com/msp
使用peer channel fetch
命令获取系统通道的创世区块
peer channel fetch config ./channel-artifacts/sys_config_block.pb -o orderer.example.com:7050 -c byfn-sys-channel --tls --cafile $ORDERER_CA
其中-c
参数是--channelID
的简写,要使用系统通道ID,即在调用configtxgen
创建orderer创世区块时所指定的channelID,在byfn.sh中定义了该id:SYS_CHANNEL="byfn-sys-channel"
回到宿主机,把pb文件转换成json文件便于查看:
exit
configtxlator proto_decode --input ./channel-artifacts/sys_config_block.pb --type common.Block | jq .data.data[0].payload.data.config > ./channel-artifacts/sys_config.json
如果想要添加一个联盟,就相当于在截图367行那里添加新的配置,但不能在这个文件修改,要在最初的configtx.yaml里面修改
2,添加联盟
我们的目的是要配置出另一个联盟,并为此联盟新建一个channel
修改configtx.yaml
选中部分为新增部分
由于Org1的配置文件及其他证书文件都已经定义好,因此这里直接没有重新定义Org3,Org4,而是直接使用Org1作为另外一个单独的联盟,这样比较方便
修改后,网络的架构应该是这样
修改完配置文件后,用该配置文件重新生成创世块
configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/sys-channel.block
将其内容转换成JSON,并抽取出新联盟的配置信息到TestConsortium.json
中
configtxlator proto_decode --input ./channel-artifacts/sys-channel.block --type common.Block | jq .data.data[0].payload.data.config.channel_group.groups.Consortiums.groups.TestConsortium > ./channel-artifacts/TestConsortium.json
把这部分数据放入刚才第一步生成的sys_config.json文件中的group就对了,手动添加容易出错,所以通过工具来完成。
如果第一步没有做,这里还要把原来的创世区块的内容转换成json,如果上面已经转过了,可以跳过此步骤
进入cli容器,切换到order的环境变量
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 CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER_CA
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin@example.com/msp
获取创世区块
peer channel fetch config ./channel-artifacts/sys_config_block.pb -o orderer.example.com:7050 -c byfn-sys-channel --tls --cafile $ORDERER_CA
退出容器,在宿主机把pb转换成json
configtxlator proto_decode --input ./channel-artifacts/sys_config_block.pb --type common.Block | jq .data.data[0].payload.data.config > ./channel-artifacts/sys_config.json
更新json
将新联盟TestConsortium的配置定义TestConsortium.json
添加到channel的Consortiums
的TestConsortium
中,并将其写入sys_updated_config.json
jq -s '.[0] * {"channel_group":{"groups":{"Consortiums":{"groups": {"TestConsortium": .[1]}}}}}' ./channel-artifacts/sys_config.json ./channel-artifacts/TestConsortium.json >& ./channel-artifacts/sys_updated_config.json
可以用文本比较工具比较一下sys_updated_config.json和sys_config.json的区别,就可以看出来
配置增量
将原始的配置sys_config.json编码成protobuf
configtxlator proto_encode --input ./channel-artifacts/sys_config.json --type common.Config --output ./channel-artifacts/sys_config.pb
将更新后的配置sys_updated_config.json编码成protobuf
configtxlator proto_encode --input ./channel-artifacts/sys_updated_config.json --type common.Config --output ./channel-artifacts/sys_updated_config.pb
protobuf配置增量计算
configtxlator compute_update --channel_id byfn-sys-channel --original ./channel-artifacts/sys_config.pb --updated ./channel-artifacts/sys_updated_config.pb --output ./channel-artifacts/sys_config_update.pb
生成配置更新并将其包装在信封中
将sys_config_update.pb编码成json
configtxlator proto_decode --input ./channel-artifacts/sys_config_update.pb --type common.ConfigUpdate | jq . > ./channel-artifacts/sys_config_update.json
封装头部信息,生成sys_config_update_in_envelope.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"byfn-sys-channel", "type":2}},"data":{"config_update":'$(cat ./channel-artifacts/sys_config_update.json)'}}}' | jq . > ./channel-artifacts/sys_config_update_in_envelope.json
将添加了头信息的sys_config_update_in_envelope.json信封编码成protobuf
configtxlator proto_encode --input ./channel-artifacts/sys_config_update_in_envelope.json --type common.Envelope --output ./channel-artifacts/sys_config_update_in_envelope.pb
向orderer发送配置更新
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 CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER_CA
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin@example.com/msp
peer channel update -f ./channel-artifacts/sys_config_update_in_envelope.pb -c byfn-sys-channel -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA
在执行peer channel update
命令之前,可以再执行一下上文的fetch
命令,看看网络配置所在的区块高度,和update之后做个对比
peer channel fetch config ./channel-artifacts/sys_config_block.pb -o orderer.example.com:7050 -c byfn-sys-channel --tls --cafile $ORDERER_CA
以上就是创建联盟的全过程,总结一下整个步骤:
1,修改配置文件configtx.yaml,添加新联盟(TestConsortium)信息
2,根据配置文件生成新联盟的配置块,或者叫创世块
configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/sys-channel.block
3,将其内容转换成JSON并抽取出新联盟的配置信息到TestConsortium.json
中
configtxlator proto_decode --input ./channel-artifacts/sys-channel.block --type common.Block | jq .data.data[0].payload.data.config.channel_group.groups.Consortiums.groups.TestConsortium > ./channel-artifacts/TestConsortium.json
4,进入cli容器,配置OrdererOrgs的admin环境变量
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 CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER_CA
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin@example.com/msp
5,获取当前系统channel的创世区块配置文件
peer channel fetch config ./channel-artifacts/sys_config_block.pb -o orderer.example.com:7050 -c byfn-sys-channel --tls --cafile $ORDERER_CA
6,回到宿主机,把刚才生成的配置转换成sys_config.json
configtxlator proto_decode --input ./channel-artifacts/sys_config_block.pb --type common.Block | jq .data.data[0].payload.data.config > ./channel-artifacts/sys_config.json
7,将第3步中TestConsortium.json
与第5步sys_config.json
合并,并写入到新的文件sys_updated_config.json
jq -s '.[0] * {"channel_group":{"groups":{"Consortiums":{"groups": {"TestConsortium": .[1]}}}}}' ./channel-artifacts/sys_config.json ./channel-artifacts/TestConsortium.json >& ./channel-artifacts/sys_updated_config.json
8,将原始的配置sys_config.json
编码成protobuf
configtxlator proto_encode --input ./channel-artifacts/sys_config.json --type common.Config --output ./channel-artifacts/sys_config.pb
9,将更新后的配置sys_updated_config.json
编码成protobuf
configtxlator proto_encode --input ./channel-artifacts/sys_updated_config.json --type common.Config --output ./channel-artifacts/sys_updated_config.pb
10,将第7步和第8步的两个protobuf配置进行增量计算
configtxlator compute_update --channel_id byfn-sys-channel --original ./channel-artifacts/sys_config.pb --updated ./channel-artifacts/sys_updated_config.pb --output ./channel-artifacts/sys_config_update.pb
11,将sys_config_update.pb
编码成json
configtxlator proto_decode --input ./channel-artifacts/sys_config_update.pb --type common.ConfigUpdate | jq . > ./channel-artifacts/sys_config_update.json
12,封装头部信息,生成sys_config_update_in_envelope.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"byfn-sys-channel", "type":2}},"data":{"config_update":'$(cat ./channel-artifacts/sys_config_update.json)'}}}' | jq . > ./channel-artifacts/sys_config_update_in_envelope.json
13,将添加了头信息的sys_config_update_in_envelope.json信封编码成protobuf
configtxlator proto_encode --input ./channel-artifacts/sys_config_update_in_envelope.json --type common.Envelope --output ./channel-artifacts/sys_config_update_in_envelope.pb
14,进入cli容器并配置环境变量(同4),向orderer发送配置更新
peer channel update -f ./channel-artifacts/sys_config_update_in_envelope.pb -c byfn-sys-channel -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA
转载请注明来源