E2E网络中动态添加组织和节点
思路:
生成新组织的加密材料
进入cli 容器,通过peer channel fetch命令获取通道的配置,并生成protobuf格式的config_block.pb文件。
使用configtxlator工具将protobuf 格式的config_block.pb文件转化成 JSON 文件,并删除一些头部信息。
向生成的JSON 文件中添加进新组织的内容。
将两个JSON 文件转化为两个protobuf 格式的文件。
使用configtxlator工具来计算两个protobuf文件的增量,并生成一个新的protobuf二进制文件。
将新生成的protobuf二进制文件,转化成json文件。
向这个json文件添加进原本删除掉的头部信息。
再将该json文件转化成一个新的protobuf文件。
使用管理员身份执行peer channel signconfigtx来对这个新的protobuf文件进行签名。
切换为另一个组织的管理员来进行签名。
发送peer channel update命令,来进行更新调用。
配置新组织的动态选举规则
启动新组织的Cli容器,导出ORDERER_CA和CHANNEL_NAME环境变量
执行peer channel fetch来获取创世区块。
使用peer channel join命令来加入区块。
在新的组织容器中执行peer chaincode install安装链码
进入原来的CLI容器,安装链码。切换环境变量到另一个组织管理员,来安装链码。
调用peer chaincode upgrade命令,来升级链码。并指定新的背书策略。
之后就可以进入新组织的容器内部,进行链码调用了
对于e2e网络动态添加组织
具体步骤
1.进入到e2e所在文件夹注释掉generateArtifacts.sh中的generateIdemixMaterial函数
2.编辑configtx.yaml文件删除Org3的相关信息并转为solo模式
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
---
################################################################################
#
# Section: Organizations
#
# - This section defines the different organizational identities which will
# be referenced later in the configuration.
#
################################################################################
Organizations:
# SampleOrg defines an MSP using the sampleconfig. It should never be used
# in production but may be used as a template for other definitions
- &OrdererOrg
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: OrdererOrg
# ID to load the MSP definition as
ID: OrdererMSP
# MSPDir is the filesystem path which contains the MSP configuration
MSPDir: crypto-config/ordererOrganizations/example.com/msp
# Policies defines the set of policies at this level of the config tree
# For organization policies, their canonical path is usually
# /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"
- &Org1
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: Org1MSP
# ID to load the MSP definition as
ID: Org1MSP
MSPDir: crypto-config/peerOrganizations/org1.example.com/msp
# Policies defines the set of policies at this level of the config tree
# For organization policies, their canonical path is usually
# /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
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')"
AnchorPeers:
# AnchorPeers defines the location of peers which can be used
# for cross org gossip communication. Note, this value is only
# encoded in the genesis block in the Application section context
- Host: peer0.org1.example.com
Port: 7051
- &Org2
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: Org2MSP
# ID to load the MSP definition as
ID: Org2MSP
MSPDir: crypto-config/peerOrganizations/org2.example.com/msp
# Policies defines the set of policies at this level of the config tree
# For organization policies, their canonical path is usually
# /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
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')"
AnchorPeers:
# AnchorPeers defines the location of peers which can be used
# for cross org gossip communication. Note, this value is only
# encoded in the genesis block in the Application section context
- Host: peer0.org2.example.com
Port: 7051
################################################################################
#
# SECTION: Capabilities
#
# - This section defines the capabilities of fabric network. This is a new
# concept as of v1.1.0 and should not be utilized in mixed networks with
# v1.0.x peers and orderers. Capabilities define features which must be
# present in a fabric binary for that binary to safely participate in the
# fabric network. For instance, if a new MSP type is added, newer binaries
# might recognize and validate the signatures from this type, while older
# binaries without this support would be unable to validate those
# transactions. This could lead to different versions of the fabric binaries
# having different world states. Instead, defining a capability for a channel
# informs those binaries without this capability that they must cease
# processing transactions until they have been upgraded. For v1.0.x if any
# capabilities are defined (including a map with all capabilities turned off)
# then the v1.0.x peer will deliberately crash.
#
################################################################################
Capabilities:
# Channel capabilities apply to both the orderers and the peers and must be
# supported by both. Set the value of the capability to true to require it.
Global: &ChannelCapabilities
# V1.1 for Global is a catchall flag for behavior which has been
# determined to be desired for all orderers and peers running v1.0.x,
# but the modification of which would cause incompatibilities. Users
# should leave this flag set to true.
V1_1: true
# Orderer capabilities apply only to the orderers, and may be safely
# manipulated without concern for upgrading peers. Set the value of the
# capability to true to require it.
Orderer: &OrdererCapabilities
# V1.1 for Order is a catchall flag for behavior which has been
# determined to be desired for all orderers running v1.0.x, but the
# modification of which would cause incompatibilities. Users should
# leave this flag set to true.
V1_1: true
# Application capabilities apply only to the peer network, and may be safely
# manipulated without concern for upgrading orderers. Set the value of the
# capability to true to require it.
Application: &ApplicationCapabilities
# V1.1 for Application is a catchall flag for behavior which has been
# determined to be desired for all peers running v1.0.x, but the
# modification of which would cause incompatibilities. Users should
# leave this flag set to true.
V1_2: true
################################################################################
#
# SECTION: Application
#
# - This section defines the values to encode into a config transaction or
# genesis block for application related parameters
#
################################################################################
Application: &ApplicationDefaults
# Organizations is the list of orgs which are defined as participants on
# the application side of the network
Organizations:
# Policies defines the set of policies at this level of the config tree
# For Application policies, their canonical path is
# /Channel/Application/<PolicyName>
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
# Capabilities describes the application level capabilities, see the
# dedicated Capabilities section elsewhere in this file for a full
# description
Capabilities:
<<: *ApplicationCapabilities
################################################################################
#
# SECTION: Orderer
#
# - This section defines the values to encode into a config transaction or
# genesis block for orderer related parameters
#
################################################################################
Orderer: &OrdererDefaults
# Orderer Type: The orderer implementation to start
# Available types are "solo" and "kafka"
OrdererType: solo
Addresses:
- orderer.example.com:7050
# Batch Timeout: The amount of time to wait before creating a batch
BatchTimeout: 2s
# Batch Size: Controls the number of messages batched into a block
BatchSize:
# Max Message Count: The maximum number of messages to permit in a batch
MaxMessageCount: 10
# Absolute Max Bytes: The absolute maximum number of bytes allowed for
# the serialized messages in a batch.
AbsoluteMaxBytes: 98 MB
# Preferred Max Bytes: The preferred maximum number of bytes allowed for
# the serialized messages in a batch. A message larger than the preferred
# max bytes will result in a batch larger than preferred max bytes.
PreferredMaxBytes: 512 KB
Kafka:
# Brokers: A list of Kafka brokers to which the orderer connects. Edit
# this list to identify the brokers of the ordering service.
# NOTE: Use IP:port notation.
Brokers:
- kafka0:9092
- kafka1:9092
- kafka2:9092
- kafka3:9092
# Organizations is the list of orgs which are defined as participants on
# the orderer side of the network
Organizations:
# Policies defines the set of policies at this level of the config tree
# For Orderer policies, their canonical path is
# /Channel/Orderer/<PolicyName>
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
# BlockValidation specifies what signatures must be included in the block
# from the orderer for the peer to validate it.
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
# Capabilities describes the orderer level capabilities, see the
# dedicated Capabilities section elsewhere in this file for a full
# description
Capabilities:
<<: *OrdererCapabilities
################################################################################
#
# CHANNEL
#
# This section defines the values to encode into a config transaction or
# genesis block for channel related parameters.
#
################################################################################
Channel: &ChannelDefaults
# Policies defines the set of policies at this level of the config tree
# For Channel policies, their canonical path is
# /Channel/<PolicyName>
Policies:
# Who may invoke the 'Deliver' API
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
# Who may invoke the 'Broadcast' API
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
# By default, who may modify elements at this config level
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
# Capabilities describes the channel level capabilities, see the
# dedicated Capabilities section elsewhere in this file for a full
# description
Capabilities:
<<: *ChannelCapabilities
################################################################################
#
# Profile
#
# - Different configuration profiles may be encoded here to be specified
# as parameters to the configtxgen tool
#
################################################################################
Profiles:
TwoOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
3.编辑docker-compose-cli.yaml文件删除kafaka和zookepper的相关信息,同时删除其base文件夹中的相关信息
docker-compose-cli.yaml文件
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
services:
orderer.example.com:
extends:
file: base/docker-compose-base.yaml
service: orderer.example.com
container_name: orderer.example.com
peer0.org1.example.com:
container_name: peer0.org1.example.com
extends:
file: base/docker-compose-base.yaml
service: peer0.org1.example.com
peer1.org1.example.com:
container_name: peer1.org1.example.com
extends:
file: base/docker-compose-base.yaml
service: peer1.org1.example.com
peer0.org2.example.com:
container_name: peer0.org2.example.com
extends:
file: base/docker-compose-base.yaml
service: peer0.org2.example.com
peer1.org2.example.com:
container_name: peer1.org2.example.com
extends:
file: base/docker-compose-base.yaml
service: peer1.org2.example.com
cli:
container_name: cli
image: hyperledger/fabric-tools
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=info
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_LOCALMSPTYPE=bccsp
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
volumes:
- /var/run/:/host/var/run/
- ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- orderer.example.com
- peer0.org1.example.com
- peer1.org1.example.com
- peer0.org2.example.com
- peer1.org2.example.com
docker-compose-base.yaml文件
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
services:
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer
environment:
- ORDERER_GENERAL_LOGLEVEL=info
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
# 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]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
ports:
- 7050:7050
peer0.org1.example.com:
container_name: peer0.org1.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
ports:
- 7051:7051
- 7052:7052
- 7053:7053
peer1.org1.example.com:
container_name: peer1.org1.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.org1.example.com
- CORE_PEER_ADDRESS=peer1.org1.example.com:7051
- CORE_PEER_CHAINCODEADDRESS=peer1.org1.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls
ports:
- 8051:7051
- 8052:7052
- 8053:7053
peer0.org2.example.com:
container_name: peer0.org2.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.org2.example.com
- CORE_PEER_ADDRESS=peer0.org2.example.com:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls
ports:
- 9051:7051
- 9052:7052
- 9053:7053
peer1.org2.example.com:
container_name: peer1.org2.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.org2.example.com
- CORE_PEER_ADDRESS=peer1.org2.example.com:7051
- CORE_PEER_CHAINCODEADDRESS=peer1.org2.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls:/etc/hyperledger/fabric/tls
ports:
- 10051:7051
- 10052:7052
- 10053:7053
4.回到e2e目录执行
network_setup.sh up
出现上图代表网络成功启动
手动添加Org3
1.生成org3的身份信息和加密材料
这个命令会读取org3-crypto.yaml文件,并利用cryptogen工具为Org3组织的两个 peer 生成秘钥和证书。并存放在当前目录的crypto-config文件夹下
cryptogen generate --config=./org3-crypto.yaml
org3-crypto.yaml源代码
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nod ---------------------------------------------------------------------------
PeerOrgs:
- Name: Org3
Domain: org3.example.com
EnableNodeOUs: true
CA:
Country: US
Province: California
Locality: San Francisco
Template:
Count: 2
Users:
Count: 1
使用configtxgen工具,读取configtx.yaml文件生成org3.json文件,并存放在/first-network/channel-artifacts/目录下
export FABRIC_CFG_PATH=$PWD && configtxgen -printOrg Org3MSP > ../channel-artifacts/org3.json
configtx.yaml源代码
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
---
################################################################################
#
# Section: Organizations
#
# - This section defines the different organizational identities which will
# be referenced later in the configuration.
#
################################################################################
Organizations:
- &Org3
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: Org3MSP
# ID to load the MSP definition as
ID: Org3MSP
MSPDir: crypto-config/peerOrganizations/org3.example.com/msp
# Policies defines the set of policies at this level of the config tree
# For organization policies, their canonical path is usually
# /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
Policies:
Readers:
Type: Signature
Rule: "OR('Org3MSP.admin', 'Org3MSP.peer', 'Org3MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org3MSP.admin', 'Org3MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org3MSP.admin')"
AnchorPeers:
# AnchorPeers defines the location of peers which can be used
# for cross org gossip communication. Note, this value is only
# encoded in the genesis block in the Application section context
- Host: peer0.org1.example.com
Port: 7051# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
---
################################################################################
#
# Section: Organizations
#
# - This section defines the different organizational identities which will
# be referenced later in the configuration.
#
################################################################################
Organizations:
- &Org3
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: Org3MSP
# ID to load the MSP definition as
ID: Org3MSP
MSPDir: crypto-config/peerOrganizations/org3.example.com/msp
AnchorPeers:
# AnchorPeers defines the location of peers which can be used
# for cross org gossip communication. Note, this value is only
# encoded in the genesis block in the Application section context
- Host: peer0.org3.example.com
Port: 7051
这个文件包含了Org3的策略定义,已经base64编码格式的三个重要证书:管理员用户证书(稍后充当Org3的管理员),CA根证书和TLS根目录证书。在稍后的步骤中,我们会将此JSON文件附加到通道配置。
最后,我们要将Orderer Org的MSP材料移植到Org3的 crypto-config目录中。 我们需要特别关注的是Orderer的TLS根证书,它将允许Org3实体与网络对等节点之间的安全通信
。
cd ../ && cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/
配置翻译工具configtxlator可以简化Fabric网络中的配置任务,可以在不同的等效数据格式之间轻松转换(比如:在 protobufs 和 JSON 之间)。
首先,进入 CLI 容器。在这个容器中,我们可以访问crypto-config目录中的两个组织和Orderer组织的MSP资料.
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
echo $ORDERER_CA && echo $CHANNEL_NAME
安装jq工具
apt update && apt install -y jq
2.获取channel的配置块
我们需要获取配置的最新版本,因为通道配置元素是版本化的。版本控制可以防止重复或重放配置更改。此外,还有助于确保并发性
(比如说删除通道中的某个组织,版本控制有助于防止删除两个组织,不仅仅是要删除的组织)
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
3.将配置块转化成JSON
我们使用configtxlator工具将通道的配置块解码为 JSON 格式。我们还要删除一些无关的标头,元数据,创建者签名等内容。我们需要通过 jq 工具实现这一目标
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json
生成一个 config.json 的 JSON 文件
4.添加 Org3 加密资料
我们将再次使用jq工具来配置ORG3。将org3.json附加到通道的应用程序组字段,输出为modified_config.json
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./channel-artifacts/org3.json > modified_config.json
现在,在CLI容器中,我们有了两个JSON文件,config.json 和 modified_config.json。 config.json文件中仅包含 Org1 和 Org2 相关配置,而modified 文件包含所有三个Orgs的配置。此时,我们只需重新编码这两个JSON文件并计算增量即可。
首先, 转换 config.json 回一个名为 protobuf 的config.pb文件:
configtxlator proto_encode --input config.json --type common.Config --output config.pb
接下来,编码modified_config.json为modified_config.pb:
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
现在configtxlator用来计算这两个配置protobuf之间的增量。
此命令将输出一个名为的新protobuf二进制文件org3_update.pb :
configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output org3_update.pb
这个新的配置org3_update.pb包含了 Org3 、 Org1 和 Org2的内容。我们没有包含 Org1 和 Org2 的 MSP和修改策略信息,是因为这些数据已经存在于通道的创世区块中了。因此我们只需要两种配置间的增量。
将org3_update.pb 转化成org3_update.json
configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate | jq . > org3_update.json
现在我们有了一个JSON格式的更新文件org3_update.json,我们需要将原来剥离的标题字段增加上。并命名文件为org3_update_in_envelope.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工具,将org3_update_in_envelope.json文件转化成protobuf格式的org3_update_in_envelope.pb文件
configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb
5.签名并提交配置更新
在我们的 CLI 容器中,存在了一个protobuf 格式的org3_update_in_envelope.pb文件。在将配置写入到账本前,我们需要用Admin用户进行签名。我们通道的应用组策略默认是MAJORITY,也就是需要大多数存在的组织管理员来进行签名。由于我们只有Org1 和 Org2 两个组织,因此我们需要他们的共同签名。如果没有他们共同的签名,排序服务会拒绝该交易的发生。
我们先让Org1的管理员进行签名。由于CLI容器是由Org1 MSP信息来引导启动的,所以我们可以直接使用peer channel signconfigtx命令进行签名
peer channel signconfigtx -f org3_update_in_envelope.pb
最后一步是切换CLI容器的身份为Org2 Admin用户,我们通过导出特定的四个环境变量来达到目的。导出Org2的环境变量
export CORE_PEER_LOCALMSPID="Org2MSP"
export 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
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/ crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
最后我们执行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
6.配置领导者选举
新加入的节点使用创世区块来进行配置,不会包含有关在通道配置更新中添加的组织的信息。因此,新的peer 不能使用gossip 服务,因为他们没有办法验证其他peer发送的区块的有效性,直到他们获得将组织添加到channel的配置事务。因此,新加入的peer 必须具有以下配置中的一个,以便他们从orderer服务接收区块
1:静态领导模式:
CORE_PEER_GOSSIP_USELEADERELECTION=false
CORE_PEER_GOSSIP_ORGLEADER=true
===》》对于新添加到通道的peer节点,此配置必须相同
2:动态选举模式:
CORE_PEER_GOSSIP_USELEADERELECTION=true
CORE_PEER_GOSSIP_ORGLEADER=false
注意:由于新添加的组织的peer,将无法形成成员资格视图,因此每个peer将开始宣称自己是leader,此选项与静态配置类似。但是,一旦他们获得了,将组织添加到Channel的配置事务的更新,组织将只有一个活动leader。因此,如果您最终希望组织的peer利用leader选举,建议您利用此选项。
一系列操作成功后生成如下图文件
7.将Org3加入通道
首先,启动Org3的节点和特定的CLI容器。打开一个新的终端,启动 Org3 docker compose。
docker-compose -f docker-compose-org3.yaml up -d
docker-compose-org3.yaml源代码
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
services:
peer0.org3.example.com:
container_name: peer0.org3.example.com
extends:
file: base/peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.org3.example.com
- CORE_PEER_ADDRESS=peer0.org3.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org3.example.com:7051
- CORE_PEER_LOCALMSPID=Org3MSP
volumes:
- /var/run/:/host/var/run/
- ./org3-artifacts/crypto-config/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp:/etc/hyperledger/fabric/msp
- ./org3-artifacts/crypto-config/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls:/etc/hyperledger/fabric/tls
ports:
- 11051:7051
- 11053:7053
peer1.org3.example.com:
container_name: peer1.org3.example.com
extends:
file: base/peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.org3.example.com
- CORE_PEER_ADDRESS=peer1.org3.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org3.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org3.example.com:7051
- CORE_PEER_LOCALMSPID=Org3MSP
volumes:
- /var/run/:/host/var/run/
- ./org3-artifacts/crypto-config/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/msp:/etc/hyperledger/fabric/msp
- ./org3-artifacts/crypto-config/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/tls:/etc/hyperledger/fabric/tls
ports:
- 12051:7051
- 12053:7053
Org3cli:
container_name: Org3cli
image: hyperledger/fabric-tools
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=INFO
#- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=Org3cli
- CORE_PEER_ADDRESS=peer0.org3.example.com:7051
- CORE_PEER_LOCALMSPID=Org3MSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
- ./org3-artifacts/crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./crypto-config/peerOrganizations/org1.example.com:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com
- ./crypto-config/peerOrganizations/org2.example.com:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com
- ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
depends_on:
- peer0.org3.example.com
- peer1.org3.example.com
进入Org3cli 容器:
docker exec -it Org3cli bash
就像我们使用初始CLI容器一样,导出两个关键的环境变量:ORDERER_CA和CHANNEL_NAME:
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 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
检查是否配置正确:
echo $ORDERER_CA && echo $CHANNEL_NAME
现在我们向排序服务询问创世块。由于我们成功的频道更新,排序服务能够验证Org3的有效性。如果Org3的配置没有被更新,则排序服务会拒绝此请求
peer channel fetch 0 mychannel.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
使用peer channel join命令来加入创世区块
peer channel join -b mychannel.block
如果你想加入Org3的第二个节点,就要导出TLS和ADDRESS变量,并且执行peer channel join command命令
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/
crypto/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=peer1.org3.example.com:7051
peer channel join -b mychannel.block
8.升级并调用chaincode
最后一个难题是增加链码的版本并认可Org3的策略。由于要升级链码的版本,所以我们可以放弃之前低版本的链码。所以我们关注升级Org3的链码。
进入Org3 CLI 容器,执行:
peer chaincode install -n mycc -v 2.0 -p github.com/hyperledger/fabric/examples/chaincode/
go/example02/cmd
如果想在Org3组织的第二个节点上安装链码,你需要修改相应的环境变量。这个操作不是必须的。
你只需要在背书节点或者负责通信的主节点上安装链码即可。
现在我们回到 CLI 容器并在Org1和Org2的节点上安装新版本链码(注意:不是Org3cli容器了)。
之前我们在CLI 容器中修改了环境变量,使用的是Org2管理员身份提交的频道更新事务,因此我们再执行下面命令的时候,代表的是peer0.Org2。
如果你不确定当前CLI 具体代表的Org1 还是 Org2 。
你可以在CLI 容器内部输入env | grep CORE_PEER_LOCALMSPID来查看。同样需要查看一下是否指定了ORDERER_CA和CHANNEL_NAME这两个环境变量。
安装链码:
peer chaincode install -n mycc -v 2.0 -p github.com/hyperledger/fabric/examples/chaincode/
go/example02/cmd
切换环境变量,作为peer0.org1身份:
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/
crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/
crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
然后重新执行安装链码命令:
peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/
现在我们准备升级链码。我们并没有对链码的源代码进行修改,只是在mychannel的mycc上增加了Org3的背书策略。支持链码实例化策略的身份,同样也支持链码的升级操作。默认是组织的管理员。
调用链码升级命令
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')"
上面的命令中。v指定新的链码版本,并且链码升级时的背书策略也做了改变-P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')", 增加了Org3的内容。用c参数表示调用的函数和参数。
与实例化链码一样,链码升级同样调用init方法,可以传递参数。
升级调用会将心产生的区块-块6,添加到账本,并允许Org3节点在背书阶段执行交易。
我们进入Org3cli 容器来查询a 的结果。这个过程可能需要一会儿时间,因为会构建一个新的chaincode容器。
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
将会返回90
现在我们调用invoke 将 a向b转移10。
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","30"]}'
最后我们再查询一下a
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
将会返回60(上边是org3cli容器中的问件)
本人e2e网络测试成功。