写在最前
在使用Fabric-SDK-Go@1.0.0操作Fabric网络时遇到了bug。Fabric-SDK-GO的当前版本没有办法在没有系统通道的情况下创建应用通道,而Fabric的最新几个版本允许在没有系统通道的情况下搭建应用通道。为了解决这个矛盾并使用Fabric-SDK-GO完成后续的项目开发,所以只能将Fabric做降级。这里使用的Fabric版本为:2.2.10。
本篇博客不会完整地介绍整个系统通道的搭建过程,这里主要是为了配合使用Fabric-SDK-GO。
这里依然使用前序博文中的finance_network
网络示例来展示应用通道的搭建过程。在使用Fabric2.2搭建该网络时,生成证书及链码链接配置文件的过程可以直接参考博客:https://blog.csdn.net/yeshang_lady/article/details/134113296。 这里就不在赘述了。
1. 创建通道配置文件
**在有系统通道的情况下搭建应用通道时,在启动相关docker容器之前,一定要先创建系统通道(应用通道可以等到容器启动之后创建)。**所以这里要先创建系统通道配置文件configtx.yaml
,其具体内容如下:
yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: ./organizations/ordererOrganizations/finance.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"
OrdererEndpoints:
- orderer.finance.com:7050
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: ./organizations/peerOrganizations/org1.finance.com/msp
AnchorPeers:
- Host: peer0.org2.finance.com
Port: 7051
Policies:
Readers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org1MSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('Org1MSP.peer')"
- &Org2
Name: Org2MSP
ID: Org2MSP
MSPDir: ./organizations/peerOrganizations/org2.finance.com/msp
AnchorPeers:
- Host: peer0.org2.finance.com
Port: 9051
Policies:
Readers:
Type: Signature
Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org2MSP.admin', 'Org2MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org2MSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('Org2MSP.peer')"
Capabilities:
Channel: &ChannelCapabilities
V2_0: true
Orderer: &OrdererCapabilities
V2_0: true
Application: &ApplicationCapabilities
V2_0: true
Application: &ApplicationDefaults
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
LifecycleEndorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Endorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Capabilities:
<<: *ApplicationCapabilities
Orderer: &OrdererDefaults
OrdererType: etcdraft
Addresses:
- orderer.finance.com:7050
EtcdRaft:
Consenters:
- Host: orderer.finance.com
Port: 7050
ClientTLSCert: ./organizations/ordererOrganizations/finance.com/orderers/orderer.finance.com/tls/server.crt
ServerTLSCert: ./organizations/ordererOrganizations/finance.com/orderers/orderer.finance.com/tls/server.crt
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
Channel: &ChannelDefaults
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ChannelCapabilities
Profiles:
TwoOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
接着,便可以创建系统通道了:
bash
#在finance_network目录下执行
configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block -configPath ./
如果在启动docker容器之前没有创建系统通道的话,可能会提示如下错误:panic: unable to bootstrap orderer. Error reading genesis block file: read /var/hyperledger/orderer/orderer.genesis.block: is a directory。
出现这种错误是因为在docker配置文件中指定了系统通道文件路径,docker容器会自己创建相关文件。
2. 创建docker配置文件
这里创建compose/compose-withsystem.yaml
文件作为docker容器配置文件,这里要增加系统通道相关的环境变量。文件具体内容如下:
yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2.1'
volumes:
orderer.finance.com:
peer0.org1.finance.com:
peer1.org1.finance.com:
peer0.org2.finance.com:
networks:
test:
name: fabric_finance
services:
orderer.finance.com:
container_name: orderer.finance.com
image: hyperledger/fabric-orderer:latest
environment:
- FABRIC_LOGGING_SPEC=INFO
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_LISTENPORT=7050
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_BOOTSTRAPMETHOD=file
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
- ORDERER_OPERATIONS_LISTENADDRESS=orderer.finance.com:9443
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=true
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
- ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1
- ORDERER_KAFKA_VERBOSE=true
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ../system-genesis-block/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ../organizations/ordererOrganizations/finance.com/orderers/orderer.finance.com/msp:/var/hyperledger/orderer/msp
- ../organizations/ordererOrganizations/finance.com/orderers/orderer.finance.com/tls/:/var/hyperledger/orderer/tls
- orderer.finance.com:/var/hyperledger/production/orderer
ports:
- 7050:7050
- 9443:9443
networks:
- test
peer0.org1.finance.com:
container_name: peer0.org1.finance.com
image: hyperledger/fabric-peer:latest
environment:
#Generic peer variables
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_finance
- FABRIC_LOGGING_SPEC=INFO
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
# Peer specific variabes
- CORE_PEER_ID=peer0.org1.finance.com
- CORE_PEER_ADDRESS=peer0.org1.finance.com:7051
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.org1.finance.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.finance.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.finance.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_OPERATIONS_LISTENADDRESS=peer0.org1.finance.com:9444
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ../organizations/peerOrganizations/org1.finance.com/peers/peer0.org1.finance.com/msp:/etc/hyperledger/fabric/msp
- ../organizations/peerOrganizations/org1.finance.com/peers/peer0.org1.finance.com/tls:/etc/hyperledger/fabric/tls
- peer0.org1.finance.com:/var/hyperledger/production
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 7051:7051
- 9444:9444
networks:
- test
peer1.org1.finance.com:
container_name: peer1.org1.finance.com
image: hyperledger/fabric-peer:latest
environment:
#Generic peer variables
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_finance
- FABRIC_LOGGING_SPEC=INFO
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
# Peer specific variabes
- CORE_PEER_ID=peer1.org1.finance.com
- CORE_PEER_ADDRESS=peer1.org1.finance.com:8051
- CORE_PEER_LISTENADDRESS=0.0.0.0:8051
- CORE_PEER_CHAINCODEADDRESS=peer1.org1.finance.com:8052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:8052
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.finance.com:8051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.finance.com:8051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_OPERATIONS_LISTENADDRESS=peer1.org1.finance.com:9446
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ../organizations/peerOrganizations/org1.finance.com/peers/peer1.org1.finance.com/msp:/etc/hyperledger/fabric/msp
- ../organizations/peerOrganizations/org1.finance.com/peers/peer1.org1.finance.com/tls:/etc/hyperledger/fabric/tls
- peer1.org1.finance.com:/var/hyperledger/production
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 8051:8051
- 9446:9446
networks:
- test
peer0.org2.finance.com:
container_name: peer0.org2.finance.com
image: hyperledger/fabric-peer:latest
environment:
#Generic peer variables
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test
- FABRIC_LOGGING_SPEC=INFO
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
# Peer specific variabes
- CORE_PEER_ID=peer0.org2.finance.com
- CORE_PEER_ADDRESS=peer0.org2.finance.com:9051
- CORE_PEER_LISTENADDRESS=0.0.0.0:9051
- CORE_PEER_CHAINCODEADDRESS=peer0.org2.finance.com:9052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:9052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.finance.com:9051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.finance.com:9051
- CORE_PEER_LOCALMSPID=Org2MSP
- CORE_OPERATIONS_LISTENADDRESS=peer0.org2.finance.com:9445
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ../organizations/peerOrganizations/org2.finance.com/peers/peer0.org2.finance.com/msp:/etc/hyperledger/fabric/msp
- ../organizations/peerOrganizations/org2.finance.com/peers/peer0.org2.finance.com/tls:/etc/hyperledger/fabric/tls
- peer0.org2.finance.com:/var/hyperledger/production
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 9051:9051
- 9445:9445
networks:
- test
cli:
container_name: cli
image: hyperledger/fabric-tools:latest
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
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ../organizations:/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations
- ../scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
depends_on:
- peer0.org1.finance.com
- peer1.org1.finance.com
- peer0.org2.finance.com
networks:
- test
然后启动容器,具体命令如下:
bash
#在finance_network目录下执行
sudo DOCKER_SOCK="/var/run/docker.sock" docker-compose -f compose/compose-withsystem.yaml up -d
创建应用通道及配置锚节点
接下来使用如下命令创建应用通道并配置各个组织的锚节点。
bash
#创建应用通道
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
#设置组织Org1的锚节点
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
#设置组织Org2的锚节点
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
接下来的peer节点加入通道及部署链码等的操作将使用Fabric-sdk-go来实现,具体参考博客:https://blog.csdn.net/yeshang_lady/article/details/134921528。
Tips:在使用Fabric-SDK-GO进行后续操作的时候,要对docker容器进行重启(注意,只需要重启docker容器)。因为Fabric-SDK-GO会依据我们生成的文件(channel.tx、Org1MSPanchors.tx、Org2MSPanchors.tx)重新进行创建应用通道及配置锚节点等操作。如果不重启,则会提示如下错误: create channel failed: create channel failed: SendEnvelope failed: calling orderer 'orderer.finance.com:7050' failed: Orderer Server Status Code: (400) BAD_REQUEST. Description: error applying config update to existing channel 'mychannel': error authorizing update: error validating ReadSet: proposed update requires that key [Group] /Channel/Application be at version 0, but it is currently at version 1