Hyperledger Fabric动态配置Raft节点

最近看官方文档发现新的共识算法etcdRaft允许动态添加或删除排序节点,所以也花了一天时间操作了以下,写篇文章把整个过程记录一下。

初始网络本文设置了4个Orderer节点,1个Peer节点(用于更新配置文件以及测试用),然后动态添加第五个Orderer节点。

本文分成两个部分:

  1. 第一部分是手动通过Fabric-CA生成每一个节点的证书文件
  2. 第二部分是更新Fabric网络配置添加新的Orderer节点。

本文基于Fabric v2.0.0-beta版本。版本号只要高于1.4.1就行

1 搭建定制化的Fabric网络

前提条件是成功跑起来Fabric的示例网络,可以看这里->Hyperledger Fabric环境搭建

首先在$GOPATH下(本文路径地址为$GOPATH/src/github.com/hyperledger/fab)建立如下几个文件夹用于之后的操作:

.  # 这里是根目录fab
├── ca # 用于生成CA证书的ca配置文件的文件夹
│   ├── org1
│   │   └── fabric-ca-server-config.yaml
│   └── server
│   └── fabric-ca-server-config.yaml
├── channel-artifacts #用于保存创世区块以及通道配置文件
├── configtx.yaml #配置文件:用于生成创世区块以及通道配置文件
├── crypto-config #存储生成的证书文件
├── docker # Fabric网络节点通过Docker启动,用于启动节点的Docker文件
│   ├── base.yaml
│   ├── docker-compose-addOrderer5.yaml
│   ├── docker-compose-ca.yaml
│   ├── docker-compose-orderers.yaml
│   └── docker-compose-peer.yaml
└── store #存储区块等信息

以下所有操作默认都在根目录文件夹内!

1.1CA配置文件

直接在这里贴出来:org1/fabric-ca-server-config.yaml:


version: 1.2.0 # Server's listening port (default: 7054)
port: 7054 # Enables debug logging (default: false)
debug: false crlsizelimit: 512000 tls:
# Enable TLS (default: false)
enabled: true
certfile:
keyfile:
clientauth:
type: noclientcert
certfiles: ca:
# Name of this CA
name: Org1CA
keyfile:
certfile:
chainfile: crl:
expiry: 24h registry: maxenrollments: -1 identities:
- name: admin
pass: adminpw
type: client
affiliation: ""
attrs:
hf.Registrar.Roles: "*"
hf.Registrar.DelegateRoles: "*"
hf.Revoker: true
hf.IntermediateCA: true
hf.GenCRL: true
hf.Registrar.Attributes: "*"
hf.AffiliationMgr: true db:
type: sqlite3
datasource: fabric-ca-server.db
tls:
enabled: false
certfiles:
client:
certfile:
keyfile: ldap: enabled: false
url: ldap://<adminDN>:<adminPassword>@<host>:<port>/<base>
tls:
certfiles:
client:
certfile:
keyfile:
attribute:
names: ['uid','member']
converters:
- name:
value:
maps:
groups:
- name:
value: affiliations:
org1:
- department1
- department2
org2:
- department1 signing:
default:
usage:
- digital signature
expiry: 8760h
profiles:
ca:
usage:
- cert sign
- crl sign
expiry: 43800h
caconstraint:
isca: true
maxpathlen: 0
tls:
usage:
- signing
- key encipherment
- server auth
- client auth
- key agreement
expiry: 8760h csr:
cn: ca.org1.example.com
names:
- C: US
ST: "North Carolina"
L: "Durham"
O: org1.example.com
OU:
hosts:
- localhost
- org1.example.com
ca:
expiry: 131400h
pathlength: 1 bccsp:
default: SW
sw:
hash: SHA2
security: 256
filekeystore:
keystore: msp/keystore cacount: cafiles: intermediate:
parentserver:
url:
caname: enrollment:
hosts:
profile:
label: tls:
certfiles:
client:
certfile:
keyfile:

以及server/fabric-ca-server-config.yaml::

# Version of config file
version: 1.2.0
# Server's listening port (default: 7054)
port: 7054
# Enables debug logging (default: false)
debug: false
# Size limit of an acceptable CRL in bytes (default: 512000)
crlsizelimit: 512000
tls:
# Enable TLS (default: false)
enabled: true
# TLS for the server's listening port
certfile:
keyfile:
clientauth:
type: noclientcert
certfiles: ca:
# Name of this CA
name: OrdererCA
keyfile:
certfile:
chainfile: crl:
expiry: 24h registry:
maxenrollments: -1 identities:
- name: admin
pass: adminpw
type: client
affiliation: ""
attrs:
hf.Registrar.Roles: "*"
hf.Registrar.DelegateRoles: "*"
hf.Revoker: true
hf.IntermediateCA: true
hf.GenCRL: true
hf.Registrar.Attributes: "*"
hf.AffiliationMgr: true db:
type: sqlite3
datasource: fabric-ca-server.db
tls:
enabled: false
certfiles:
client:
certfile:
keyfile: ldap:
enabled: false
url: ldap://<adminDN>:<adminPassword>@<host>:<port>/<base>
tls:
certfiles:
client:
certfile:
keyfile:
attribute:
names: ['uid','member']
converters:
- name:
value:
maps:
groups:
- name:
value: affiliations:
org1:
- department1
- department2
org2:
- department1 signing:
default:
usage:
- digital signature
expiry: 8760h
profiles:
ca:
usage:
- cert sign
- crl sign
expiry: 43800h
caconstraint:
isca: true
maxpathlen: 0
tls:
usage:
- signing
- key encipherment
- server auth
- client auth
- key agreement
expiry: 8760h csr:
cn: ca.example.com
names:
- C: US
ST: "New York"
L: "New York"
O: example.com
OU:
hosts:
- localhost
- example.com
ca:
expiry: 131400h
pathlength: 1 bccsp:
default: SW
sw:
hash: SHA2
security: 256
filekeystore:
keystore: msp/keystore cacount:
cafiles: intermediate:
parentserver:
url:
caname: enrollment:
hosts:
profile:
label: tls:
certfiles:
client:
certfile:
keyfile:

docker-compose-ca.yaml文件:

version: '2'

services:
ca:
image: hyperledger/fabric-ca:1.4.4
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca-orderer
- FABRIC_CA_SERVER_TLS_ENABLED=true
- FABRIC_CA_SERVER_PORT=9054
ports:
- "9054:9054"
command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
volumes:
- ../ca/server:/etc/hyperledger/fabric-ca-server
container_name: ca_orderer ca0:
image: hyperledger/fabric-ca:1.4.4
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca-org1
- FABRIC_CA_SERVER_TLS_ENABLED=true
- FABRIC_CA_SERVER_PORT=7054
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
volumes:
- ../ca/org1:/etc/hyperledger/fabric-ca-server
container_name: ca_org1

将以上三个文件保存到指定的路径,然后使用以下命令启动CA服务器:

docker-compose -f docker/docker-compose-ca.yaml up -d

服务器会自动读取上面的两个配置文件,并初始化CA服务器。

当然,服务器配置文件将自动生成在ca/server/子文件夹内,其中最主要使用到的是tls-cert.pem文件。

1.2 注册Orderer节点

首先配置环境变量并登陆管理员账号:

#创建存储Order节点证书的子文件夹。
mkdir -p crypto-config/orderOrganization/example.com
export FABRIC_CA_CLIENT_HOME=${PWD}/crypto-config/orderOrganization/example.com
fabric-ca-client enroll -u https://admin:adminpw@localhost:9054 --caname ca-orderer --tls.certfiles ${PWD}/ca/server/tls-cert.pem

生成节点类型分类配置文件(不知道这个文件应该称作什么,暂且使用这个名字称呼好了):

  echo 'NodeOUs:
Enable: true
ClientOUIdentifier:
Certificate: cacerts/localhost-9054-ca-orderer.pem
OrganizationalUnitIdentifier: client
PeerOUIdentifier:
Certificate: cacerts/localhost-9054-ca-orderer.pem
OrganizationalUnitIdentifier: peer
AdminOUIdentifier:
Certificate: cacerts/localhost-9054-ca-orderer.pem
OrganizationalUnitIdentifier: admin
OrdererOUIdentifier:
Certificate: cacerts/localhost-9054-ca-orderer.pem
OrganizationalUnitIdentifier: orderer' > ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml

之后注册网络中初始的4个Orderer节点:

fabric-ca-client register -u https://admin:adminpw@localhost:9054 --caname ca-orderer --id.name orderer1 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client register -u https://admin:adminpw@localhost:9054 --caname ca-orderer --id.name orderer2 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client register -u https://admin:adminpw@localhost:9054 --caname ca-orderer --id.name orderer3 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client register -u https://admin:adminpw@localhost:9054 --caname ca-orderer --id.name orderer4 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem

注册Admin节点:

fabric-ca-client register -u https://admin:adminpw@localhost:9054 --caname ca-orderer --id.name ordererAdmin --id.secret ordererAdminpw --id.type admin --id.attrs '"hf.Registrar.Roles=admin"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem

1.3 获取Orderer证书文件

为刚刚创建的几个用户创建各自的文件夹用于存储证书文件:

mkdir -p crypto-config/orderOrganization/example.com/orderers
mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer1.example.com
mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer2.example.com
mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer3.example.com
mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer4.example.com

接下来获取每一个Orderer节点的MSP证书文件:

fabric-ca-client enroll -u https://orderer1:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp --csr.hosts orderer1.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer2:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp --csr.hosts orderer2.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer3:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp --csr.hosts orderer3.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer4:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp --csr.hosts orderer4.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem

还有每一个节点的TLS证书:

fabric-ca-client enroll -u https://orderer1:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls --enrollment.profile tls --csr.hosts orderer1.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer2:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls --enrollment.profile tls --csr.hosts orderer2.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer3:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls --enrollment.profile tls --csr.hosts orderer3.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
fabric-ca-client enroll -u https://orderer4:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls --enrollment.profile tls --csr.hosts orderer4.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem

将之前生成的节点类型分类配置文件拷贝到每一个节点的MSP文件夹:

cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp/config.yaml
cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp/config.yaml
cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp/config.yaml
cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp/config.yaml

然后为每一个节点的TLS证书以及秘钥文件修改名字,方便之后的使用:

cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.key cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/server.key cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/server.key cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/server.key

然后在MSP文件夹内创建tlscacerts文件夹,并将TLS文件拷贝过去:

mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp/tlscacerts
mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp/tlscacerts
mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp/tlscacerts
mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp/tlscacerts cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

复制TLS根证书:

mkdir -p ${PWD}/crypto-config/orderOrganization/example.com/msp/tlscacerts
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/msp/tlscacerts/tlsca.example.com-cert.pem

最后是Admin节点的证书文件:

#首先也是创建文件夹
mkdir -p crypto-config/orderOrganization/example.com/users
mkdir -p crypto-config/orderOrganization/example.com/users/Admin@example.com
#获取证书文件
fabric-ca-client enroll -u https://ordererAdmin:ordererAdminpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/users/Admin@example.com/msp --tls.certfiles ${PWD}/ca/server/tls-cert.pem
cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/users/Admin@example.com/msp/config.yaml

到这里Orderer节点证书已经生成完毕(可以根据实际需要修改Orderer节点数量,最少不能低于3个),接下来是网络中唯一的peer节点的配置文件生成:

1.4 注册Peer节点

和上面步骤相同,首先创建子文件夹用于存储证书文件:

mkdir -p crypto-config/peerOrganizations/org1.example.com/

配置环境变量并登陆管理员身份:

export FABRIC_CA_CLIENT_HOME=${PWD}/crypto-config/peerOrganizations/org1.example.com/
fabric-ca-client enroll -u https://admin:adminpw@localhost:7054 --caname ca-org1 --tls.certfiles ${PWD}/ca/org1/tls-cert.pem

生成节点类型分类配置文件:

echo 'NodeOUs:
Enable: true
ClientOUIdentifier:
Certificate: cacerts/localhost-7054-ca-org1.pem
OrganizationalUnitIdentifier: client
PeerOUIdentifier:
Certificate: cacerts/localhost-7054-ca-org1.pem
OrganizationalUnitIdentifier: peer
AdminOUIdentifier:
Certificate: cacerts/localhost-7054-ca-org1.pem
OrganizationalUnitIdentifier: admin
OrdererOUIdentifier:
Certificate: cacerts/localhost-7054-ca-org1.pem
OrganizationalUnitIdentifier: orderer' > ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/config.yaml

虽然网络中只有一个peer节点,但是我们需要注册三个用户:peer0,user1,org1admin,其中第一个是必需的,第二个是用于测试的,第三个为Admin用户,安装和实例化链码需要Admin用户的证书:

fabric-ca-client register -u https://admin:adminpw@localhost:7054 --caname ca-org1 --id.name peer0 --id.secret peer0pw --id.type peer --id.attrs '"hf.Registrar.Roles=peer"' --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
fabric-ca-client register -u https://admin:adminpw@localhost:7054 --caname ca-org1 --id.name user1 --id.secret user1pw --id.type client --id.attrs '"hf.Registrar.Roles=client"' --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
fabric-ca-client register -u https://admin:adminpw@localhost:7054 --caname ca-org1 --id.name org1admin --id.secret org1adminpw --id.type admin --id.attrs '"hf.Registrar.Roles=admin"' --tls.certfiles ${PWD}/ca/org1/tls-cert.pem

1.5 获取Peer节点证书文件

节点注册完毕,获取他们的证书文件:

创建子文件夹:

mkdir -p crypto-config/peerOrganizations/org1.example.com/peers
mkdir -p crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.co

获取证书文件:

#MSP文件
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp --csr.hosts peer0.org1.example.com --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
#TLS证书
fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls --enrollment.profile tls --csr.hosts peer0.org1.example.com --csr.hosts localhost --tls.certfiles ${PWD}/ca/org1/tls-cert.pem

拷贝节点分类配置文件:

cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/config.yaml

修改证书以及秘钥文件,方便之后使用:

cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/signcerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/keystore/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key

将TLS相关证书复制一份:

mkdir ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/tlscacerts
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/tlscacerts/ca.crt mkdir ${PWD}/crypto-config/peerOrganizations/org1.example.com/tlsca
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem mkdir ${PWD}/crypto-config/peerOrganizations/org1.example.com/ca
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/cacerts/* ${PWD}/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem

获取userAdmin用户证书文件:

#创建子文件夹
mkdir -p crypto-config/peerOrganizations/org1.example.com/users
mkdir -p crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com
mkdir -p crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com
#获取证书文件
fabric-ca-client enroll -u https://user1:user1pw@localhost:7054 --caname ca-org1 -M ${PWD}/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
fabric-ca-client enroll -u https://org1admin:org1adminpw@localhost:7054 --caname ca-org1 -M ${PWD}/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp --tls.certfiles ${PWD}/ca/org1/tls-cert.pem
cp ${PWD}/crypto-config/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/config.yaml

1.6 启动网络之前的准备

到这里我们已经生成了所有需要的证书文件,接下来是生成用于启动网络的创世区块,生成创世区块需要一个文件configtx.yaml,直接复制过来:


Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: ./crypto-config/orderOrganization/example.com/msp #这里路径需要对应!!!
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')" - &Org1 #如果需要更多组织节点,可以按照该模板在下面添加
Name: Org1MSP
ID: Org1MSP
MSPDir: ./crypto-config/peerOrganizations/org1.example.com/msp #这里路径需要对应!!!
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')"
AnchorPeers:
Port: 7051 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:
- orderer1.example.com:7050
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:
# 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:
<<: *ChannelCapabilities Profiles: TwoOrgsChannel: #用于生成通道配置文件
Consortium: SampleConsortium
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
Capabilities:
<<: *ApplicationCapabilities SampleMultiNodeEtcdRaft: #用于生成系统通道创世区块
<<: *ChannelDefaults
Capabilities:
<<: *ChannelCapabilities
Orderer:
<<: *OrdererDefaults
OrdererType: etcdraft #指定使用etcdraft共识算法
EtcdRaft:
Consenters:
- Host: orderer1.example.com
Port: 7050
ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
- Host: orderer2.example.com
Port: 8050
ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/server.crt
ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/server.crt
- Host: orderer3.example.com
Port: 9050
ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/server.crt
ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/server.crt
- Host: orderer4.example.com
Port: 10050
ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/server.crt
ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/server.crt
# - Host: orderer5.example.com
# Port: 11050
# ClientTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
# ServerTLSCert: ./crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/server.crt
Addresses:
- orderer1.example.com:7050
- orderer2.example.com:8050
- orderer3.example.com:9050
- orderer4.example.com:10050
# - orderer5.example.com:11050 Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Application:
<<: *ApplicationDefaults
Organizations:
- <<: *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1

将该文件保存到指定位置,接下来生成创世区块:

export FABRIC_CFG_PATH=$PWD
configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
# 生成通道配置文件
export CHANNEL_NAME=mychannel
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID $CHANNEL_NAME

1.7 启动网络

首先写包含所有节点的Docker文件,这里直接贴出来:

version: '2'

services:
orderer-base:
image: hyperledger/fabric-orderer:2.0.0-beta
environment:
- FABRIC_LOGGING_SPEC=INFO
# - FABRIC_LOGGING_SPEC=DEBUG
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_BOOTSTRAPMETHOD=file
- ORDERER_GENERAL_BOOTSTRAPFILE=/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]
- 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

然后是Orderer节点的Docker文件:

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
# version: '2' volumes:
orderer1.example.com:
orderer2.example.com:
orderer3.example.com:
orderer4.example.com: networks:
byfn: services: orderer1.example.com:
extends:
file: base.yaml
service: orderer-base
environment:
- ORDERER_GENERAL_LISTENPORT=7050
container_name: orderer1.example.com
networks:
- byfn
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ../crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/msp:/var/hyperledger/orderer/msp
- ../crypto-config/orderOrganization/example.com/orderers/orderer1.example.com/tls/:/var/hyperledger/orderer/tls
- ../store/o1:/var/hyperledger/production/orderer
ports:
- 7050:7050 orderer2.example.com:
extends:
file: base.yaml
service: orderer-base
environment:
- ORDERER_GENERAL_LISTENPORT=8050
container_name: orderer2.example.com
networks:
- byfn
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ../crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/msp:/var/hyperledger/orderer/msp
- ../crypto-config/orderOrganization/example.com/orderers/orderer2.example.com/tls/:/var/hyperledger/orderer/tls
- ../store/o2:/var/hyperledger/production/orderer
ports:
- 8050:8050 orderer3.example.com:
extends:
file: base.yaml
service: orderer-base
environment:
- ORDERER_GENERAL_LISTENPORT=9050
container_name: orderer3.example.com
networks:
- byfn
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ../crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/msp:/var/hyperledger/orderer/msp
- ../crypto-config/orderOrganization/example.com/orderers/orderer3.example.com/tls/:/var/hyperledger/orderer/tls
- ../store/o3:/var/hyperledger/production/orderer
ports:
- 9050:9050 orderer4.example.com:
extends:
file: base.yaml
service: orderer-base
environment:
- ORDERER_GENERAL_LISTENPORT=10050
container_name: orderer4.example.com
networks:
- byfn
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ../crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/msp:/var/hyperledger/orderer/msp
- ../crypto-config/orderOrganization/example.com/orderers/orderer4.example.com/tls/:/var/hyperledger/orderer/tls
- ../store/o4:/var/hyperledger/production/orderer
ports:
- 10050:10050

最后一个是peer节点的Docker文件:

version: '2'

volumes:
peer0.org1.example.com: networks:
byfn: services: peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer:2.0.0-beta
environment:
#Generic peer variables
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- 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.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984
# The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
# provide the credentials for ledger to connect to CouchDB. The username and password must
# match the username and password set for the associated CouchDB.
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
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
- ../store/p1:/var/hyperledger/production
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
depends_on:
- couchdb0
ports:
- 7051:7051
networks:
- byfn couchdb0:
container_name: couchdb0
image: couchdb:2.3
# Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
# for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
environment:
- COUCHDB_USER=
- COUCHDB_PASSWORD=
# Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
# for example map it to utilize Fauxton User Interface in dev environments.
ports:
- "5984:5984"
networks:
- byfn cli:
container_name: cli
image: hyperledger/fabric-tools:2.0.0-beta
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# - FABRIC_LOGGING_SPEC=DEBUG
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- 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
volumes:
- /var/run/:/host/var/run/
- ./../../chaincode/:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode
- ../crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ../channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- peer0.org1.example.com
networks:
- byfn

将以上文件保存到指定位置后,使用以下命令直接启动:

docker-compose -f docker/docker-compose-orderers.yaml -f docker/docker-compose-peer.yaml up -d

启动完成后可以查看每个节点的日志确认节点成功运行:

docker logs orderer1.example.com
...
docker logs peer0.org1.example.com

如果没有错误的话就可以进行第二部分了,如果出现错误则要回去检查是不是哪里漏掉了。

1.8 简单测试

先进行第一部分的测试,看一下创建通道,加入通道是否成功:

#进入CLI容器
docker exec -it cli bash
#配置环境变量
export CHANNEL_NAME=mychannel
export ORDERER_CA=${PWD}/crypto/orderOrganization/example.com/orderers/orderer1.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export PEER0_ORG1_CA=${PWD}/crypto/peerOrganization/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

创建通道:

peer channel create -o orderer1.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/mychannel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA --outputBlock ./channel-artifacts/${CHANNEL_NAME}.block

加入通道:

peer channel join -b ./channel-artifacts/$CHANNEL_NAME.block

如果一切顺利的话,网络就成功搭建起来了,至于链码就不再测试了。

直接到第二部分,动态添加一个Orderer节点。

2 动态添加Raft节点

主要步骤如下:

  1. 为该节点生成证书文件
  2. 获取当前网络的配置文件
  3. 将证书文件添加到配置文件中
  4. 更新配置文件
  5. 启动新的Orderer节点

2.1 生成证书文件

2.1.1 注册该节点身份

fabric-ca-client register -u https://admin:adminpw@localhost:9054 --caname ca-orderer --id.name orderer5 --id.secret ordererpw --id.type orderer --id.attrs '"hf.Registrar.Roles=orderer"' --tls.certfiles ${PWD}/ca/server/tls-cert.pem

为该节点创建存储证书的文件夹:

mkdir -p crypto-config/orderOrganization/example.com/orderers/orderer5.example.com

2.1.2 获取该节点证书

#MSP
fabric-ca-client enroll -u https://orderer5:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp --csr.hosts orderer5.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem
#TLS
fabric-ca-client enroll -u https://orderer5:ordererpw@localhost:9054 --caname ca-orderer -M ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls --enrollment.profile tls --csr.hosts orderer5.example.com --tls.certfiles ${PWD}/ca/server/tls-cert.pem

复制节点分类配置文件:

cp ${PWD}/crypto-config/orderOrganization/example.com/msp/config.yaml ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp/config.yaml

修改证书与秘钥文件名称:

cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/ca.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/signcerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/server.crt
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/keystore/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/server.key

创建文件夹并拷贝TLS证书文件:

mkdir ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp/tlscacerts
cp ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/tlscacerts/* ${PWD}/crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

2.2 获取网络配置文件

将节点添加进网络,首先需要将该节点添加到系统通道内,所以先获取系统通道的配置文件:

进入cli容器:

docker exec -it cli bash

配置环境变量,需要使用Orderer节点的身份信息:

export CORE_PEER_LOCALMSPID="OrdererMSP"
export ORDERER_CA=${PWD}/crypto/orderOrganization/example.com/orderers/orderer1.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/crypto/ordererOrganization/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderOrganization/example.com/users/Admin@example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

获取系统通道配置文件:

peer channel fetch config channel-artifacts/config_block.pb -o orderer1.example.com:7050 -c byfn-sys-channel --tls --cafile $ORDERER_CA

解码该配置文件:

configtxlator proto_decode --input channel-artifacts/config_block.pb --type common.Block | jq .data.data[0].payload.data.config > channel-artifacts/config.json

2.3将证书文件添加到配置文件中

退出容器,可以在channel-artifacts文件内找到config.json文件。将该文件复制一份并在channel-artifacts文件夹下保存为update_config.json,使用编辑工具打开,并搜索.example.com字段如下:

字段一部分:

  {
"client_tls_cert": "一连串的字符串",
"host": "orderer1.example.com",
"port": 7050,
"server_tls_cert": "一连串的字符串"
}

以及匹配到的第二部分的字段:

      "OrdererAddresses": {
"mod_policy": "/Channel/Orderer/Admins",
"value": {
"addresses": [
"orderer1.example.com:7050",
"orderer2.example.com:8050",
"orderer3.example.com:9050",
"orderer4.example.com:10050"
]
},
"version": "0"
}

在字段一部分,需要将我们生成的新的节点的证书添加上去,其中证书文件地址为:

crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt

使用BASE64转码:

cat crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt | base64 > cert.txt

update_config.json文件中字段一的部分下面按照字段一的格式添加相同的代码块,并进行修改:

cert.txt文件中的内容复制到字段一的client_tls_cert,server_tls_cert对应部分,并修改host对应部分为orderer5.example.comport11050.

2.4更新配置文件

接下来进入cli容器:

docker exec -it cli bash

对原有的配置文件与更新的配置文件进行编码:

configtxlator proto_encode --input channel-artifacts/config.json --type common.Config > channel-artifacts/config.pb
configtxlator proto_encode --input channel-artifacts/update_config.json --type common.Config > channel-artifacts/config_update.pb

计算出两个文件的差异:

configtxlator compute_update --channel_id byfn-sys-channel --original channel-artifacts/config.pb --updated channel-artifacts/config_update.pb > channel-artifacts/updated.pb

对该文件进行解码,并添加用于更新配置的头部信息:

configtxlator proto_decode --input channel-artifacts/updated.pb --type common.ConfigUpdate > channel-artifacts/updated.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"byfn-sys-channel", "type":2}},"data":{"config_update":'$(cat channel-artifacts/updated.json)'}}}' | jq . > channel-artifacts/updated_envelope.json

编码为Envelope格式的文件:

configtxlator proto_encode --input channel-artifacts/updated_envelope.json --type common.Envelope > channel-artifacts/updated_envelope.pb

对该文件进行签名操作,用于更新配置:

peer channel signconfigtx -f channel-artifacts/updated_envelope.pb

提交更新通道配置交易:

peer channel update -f channel-artifacts/updated_envelope.pb -c byfn-sys-channel -o orderer1.example.com:7050 --tls true --cafile $ORDERER_CA

如果没有错误的话,新的Orderer节点证书已经成功添加到网络配置中,接下来可以启动新的节点了:

2.5 启动新的Orderer节点

写一下新的Orderer节点的Docker文件:


version: '2' volumes:
orderer5.example.com: networks:
byfn: services:
orderer5.example.com:
extends:
file: base.yaml
service: orderer-base
environment:
- ORDERER_GENERAL_LISTENPORT=11050
container_name: orderer5.example.com
networks:
- byfn
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ../crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/msp:/var/hyperledger/orderer/msp
- ../crypto-config/orderOrganization/example.com/orderers/orderer5.example.com/tls/:/var/hyperledger/orderer/tls
- ../store/o5:/var/hyperledger/production/orderer
ports:
- 11050:11050

直接通过命令启动它:

docker-compose -f docker-compose-addOrderer5.yaml up -d

可以查看新节点的日志确认新的节点已经成功加入了网络。

到这里,本文成功把新的Orderer节点添加进了网络,但是只将该节点添加到了系统通道内,对于应用通道mychannel来说,新的节点并没有添加进来,将新的节点添加进mychannel通道和以上步骤相同,只需要将通道名称由系统通道修改为mychannel即可。本文便不再说明了。

而动态删除节点的过程与添加相似,只不过是从配置文件中删除节点证书。

Hyperledger Fabric动态配置Raft节点的更多相关文章

  1. 死磕hyperledger fabric源码|Order节点概述

    死磕hyperledger fabric源码|Order节点概述 文章及代码:https://github.com/blockchainGuide/ 分支:v1.1.0 前言及源码目录 Orderer ...

  2. Hyperledger Fabric 环境配置

    简单说一下 Hyperledger Fabric的配置 1.第一步,安装curl brew install curl 注:没有brew的自行百度(mac) 2. 安装Docker 下载并安装Docke ...

  3. Hyperledger Fabric 动态增加组织到网络中

    本文基于Hyperledger Fabric 1.4版本. 官方文档地址:传送门 动态添加一个组织到Fabric网络中也是一个比较重要的功能.官方文档写的已经很详细了,有能力的尽量还是看官方文档,本文 ...

  4. Hyperledger Fabric channel配置交易

    一个超级账本区块链网络里每个channel的共享配置都是存储在一个配置交易里.每个配置交易通常被简称为configtx. Channel 配置有以下重要属性: 1.有版本标识:配置里的所有元素都有一个 ...

  5. Hyperledger Fabric 通道配置文件和容器环境变量详解

    摘要 Fabric 网络启动的过程中需要进行大量配置,新学时对各个配置的作用一无所知,这导致我曾在网络出问题时先对配置文件的内容进行排列组合后再祈祷它能在某个时刻顺利运行,因此掌握 fabric 各个 ...

  6. HyperLedger Fabric 1.4 生产环境动态添加组织及节点

    网易云课堂视频在线教学,地址:https://study.163.com/course/introduction/1209401942.htm 1.1 操作概述      在“kafka生产环境部署” ...

  7. Hyperledger Fabric节点的动态添加和删除

    前言 在Hyperledger Fabric组织的动态添加和删除中,我们已经完成了在运行着的网络中动态添加和删除组织.本文将在其基础上,详细介绍了如何在 soft 组织上添加新的 peer2 节点,并 ...

  8. hyperledger fabric各类节点及其故障分析 摘自https://www.cnblogs.com/preminem/p/8729781.html

    hyperledger fabric各类节点及其故障分析   1.Client节点 client代表由最终用户操作的实体,它必须连接到某一个peer节点或者orderer节点上与区块链网络通信.客户端 ...

  9. Hyperledger Fabric组织的动态添加和删除

    前言 在Fabric定制联盟链网络工程实践中,我们虚拟了一个工作室的联盟链网络需求,并根据此需求分析了整个网络的架构且已经完成了一个简单 fabric 网络模型.本文将在其基础上,在 mychanne ...

随机推荐

  1. FZU 2234 牧场物语【多线程dp】

     Problem 2234 牧场物语  Problem Description 小茗同学正在玩牧场物语.该游戏的地图可看成一个边长为n的正方形. 小茗同学突然心血来潮要去砍树,然而,斧头在小茗的右下方 ...

  2. 三级分销会员一次查询出来的SQL语句

    SELECT p.id AS partyId, p.parent_id AS parentId, pul.username AS userName, p.city, p.birth_date AS b ...

  3. cume_dist(),允许并列名次、复制名次自动空缺,取并列后较大名次,结果如22355778……

    将score按ID分组排名:cume_dist() over(partition by id order by score desc)*sum(1) over(partition by id) 将sc ...

  4. POLARDB v2.0 技术解读

    点击观看“POLARDB 2.0 升级发布会”:https://yq.aliyun.com/live/1136 回顾POLARDB 1.0 POLARDB 1.0 主要的改进包括采用了计算存储分离的架 ...

  5. 【学生研究课题】CSDN博客数据获取、分析、分享

    题记     这次<对象程序设计>课程设计,一共给定了8个选题(下载WORD版.PDF版),以及自由选题的机会.从大家初步选题结果来看(图1).绝大部分同学选择了"图形用户界面的 ...

  6. oracle函数 decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)

    [功能]根据条件返回相应值 [参数]c1, c2, ...,cn,字符型/数值型/日期型,必须类型相同或null 注:值1……n 不能为条件表达式,这种情况只能用case when then end解 ...

  7. 阿里云DataV专业版发布,为可视化创造更多可能!

    阿里云数据可视化应用工具DataV正式推出专业版,该版本为可视化领域专业团队和从业者量身打造,定位数据可视分析大屏搭建场景,让使用者可以轻松hold住复杂交互设计和实时数据交互查询需求. 什么是Dat ...

  8. PHP怎么调用其他类的方法

    2个PHP,这个PHP中的类调用另一个PHP中的类,如何调用.Java中是import ,php中是什么?还是用其他什么方法? 1.引用类:比如类名为product,则:include('...路径/ ...

  9. Open Source GIS and Freeware GIS Applications

    Open Source GIS and Freeware GIS Applications   An open source application by definition is software ...

  10. 云数据库 MySQL 8.0 重磅发布,更适合企业使用场景的RDS数据库

    点击订阅新品发布会! 新产品.新版本.新技术.新功能.价格调整,评论在下方,下期更新!关注更多内容,了解更多 最新发布 云数据库MySQL 8.0 升级发布会 2019年5月29日15时,阿里云云数据 ...