Fabric网络搭建

4 搭建第一个自己的网络

下面让我们手动搭建一个自己的fabric 网络:

  • 创建一个项目目录: 如 mkdir ~/Demo
  • orderer节点个数为1个
  • 组织个数2个
    • OrgGo
    • OrgCPP
  • OrgGo有两个peer节点, 该组织有3个用户
  • OrgCpp有两个peer节点, 该组织有4个用户

4.1 生成Fabric的证书

编写生成组织节点证书的配置文件,我们将其命名为: crypto-config.yaml。在里边指定组织的名称, 节点个数, 用户个数和访问节点的域名信息。

将如下写好的配置文件放入目录: ~/Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# crypto-config.yaml
OrdererOrgs: # 排序组织
- Name: Orderer # 排序节点组织名称
Domain: wumansgy.com # 排序节点组织的根域名
Specs:
- Hostname: ubuntu # 排序节点主机名, 访问该排序节点的域名: ubuntu.wumansgy.com
# “Spec”的作用是不受下面的Template模板生成规则影响,个性化指定一个域名

PeerOrgs:
- Name: OrgGo # 组织Org1名称
Domain: orggo.wumansgy.com # 组织Org1的域名
EnableNodeOUs: true # Node.js支持,java的sdk里面默认是注释掉的

Template: # 根据上面注释的模板生成2套公私钥+证书,默认生成规则是peer0-9.组织的域名
Count: 2 # 即生成peer0.orggo.wumansgy.com、peer1.orggo.wumansgy.com 两个节点的公私钥和证
Users: # 除了admin用户,额外生成一个普通用户
Count: 3 # 普通用户个数为3
- Name: OrgCPP
Domain: orgcpp.wumansgy.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# 配置文件编写完成, 在Demo目录下执行该命令:
$ cryptogen generate --config=./crypto-config.yaml
orggo.wumansgy.com
orgcpp.wumansgy.com
# 查看Demo目录中的文件
$ tree -L 6
.
├── crypto-config
│   ├── `ordererOrganizations
│   │   └── wumansgy.com
│   │   ├── ca
│   │   │   ├── 4d61535a2dd55ff1641d7331e3037d59c590feb2abc21a9be04de678b28480cb_sk
│   │   │   └── ca.wumansgy.com-cert.pem
│   │   ├── msp
│   │   │   ├── admincerts
│   │   │   │   └── Admin@wumansgy.com-cert.pem
│   │   │   ├── cacerts
│   │   │   │   └── ca.wumansgy.com-cert.pem
│   │   │   └── tlscacerts
│   │   │   └── tlsca.wumansgy.com-cert.pem
│   │   ├── orderers
│   │   │   └── ubuntu.wumansgy.com
│   │   │   ├── msp
│   │   │   └── tls
│   │   ├── tlsca
│   │   │   ├── e2cf6010c4360cdcf89b636789543dc8e12073ba6035fe811f6e68901370f62d_sk
│   │   │   └── tlsca.wumansgy.com-cert.pem
│   │   └── users
│   │   └── Admin@wumansgy.com
│   │   ├── msp
│   │   └── tls
│   └── `peerOrganizations
│   ├── `orgcpp.wumansgy.com
│   │   ├── ca
│   │   │   ├── b1d3411e8616a50f8d88bde7a68259972565541e0937294b67b09e155468c3cd_sk
│   │   │   └── ca.orgcpp.wumansgy.com-cert.pem
│   │   ├── msp
│   │   │   ├── admincerts
│   │   │   │   └── Admin@orgcpp.wumansgy.com-cert.pem
│   │   │   ├── cacerts
│   │   │   │   └── ca.orgcpp.wumansgy.com-cert.pem
│   │   │   ├── config.yaml
│   │   │   └── tlscacerts
│   │   │   └── tlsca.orgcpp.wumansgy.com-cert.pem
│   │   ├── `peers
│   │   │   ├── `peer0.orgcpp.wumansgy.com
│   │   │   │   ├── msp
│   │   │   │   └── tls
│   │   │   └── `peer1.orgcpp.wumansgy.com
│   │   │   ├── msp
│   │   │   └── tls
│   │   ├── tlsca
│   │   │   ├── 1732fcf1ac3ccfab09c6acbe767af2442b0711ea1128c1d6c1ce059b563266c8_sk
│   │   │   └── tlsca.orgcpp.wumansgy.com-cert.pem
│   │   └── users
│   │   ├── Admin@orgcpp.wumansgy.com
│   │   │   ├── msp
│   │   │   └── tls
│   │   ├── User1@orgcpp.wumansgy.com
│   │   │   ├── msp
│   │   │   └── tls
│   │   ├── User2@orgcpp.wumansgy.com
│   │   │   ├── msp
│   │   │   └── tls
│   │   ├── User3@orgcpp.wumansgy.com
│   │   │   ├── msp
│   │   │   └── tls
│   │   └── User4@orgcpp.wumansgy.com
│   │   ├── msp
│   │   └── tls
│   └── `orggo.wumansgy.com
│   ├── ca
│   │   ├── 33dbbd366922252ee8689e0444e8b6ffb3df3389219ad0716ee9708c2c18953d_sk
│   │   └── ca.orggo.wumansgy.com-cert.pem
│   ├── msp
│   │   ├── admincerts
│   │   │   └── Admin@orggo.wumansgy.com-cert.pem
│   │   ├── cacerts
│   │   │   └── ca.orggo.wumansgy.com-cert.pem
│   │   ├── config.yaml
│   │   └── tlscacerts
│   │   └── tlsca.orggo.wumansgy.com-cert.pem
│   ├── `peers
│   │   ├── `peer0.orggo.wumansgy.com
│   │   │   ├── msp
│   │   │   └── tls
│   │   └── `peer1.orggo.wumansgy.com
│   │   ├── msp
│   │   └── tls
│   ├── tlsca
│   │   ├── ab7a23f336678f1d8799a44aaeb8894503abb6177d6ba1740037fda952ff9bdb_sk
│   │   └── tlsca.orggo.wumansgy.com-cert.pem
│   └── users
│   ├── Admin@orggo.wumansgy.com
│   │   ├── msp
│   │   └── tls
│   ├── User1@orggo.wumansgy.com
│   │   ├── msp
│   │   └── tls
│   ├── User2@orggo.wumansgy.com
│   │   ├── msp
│   │   └── tls
│   └── User3@orggo.wumansgy.com
│   ├── msp
│   └── tls
└── crypto-config.yaml

4.2 创始块和通道文件的创建

Fabric是基于区块链的分布式账本, 每个账本都有自己的区块, 账本的区块链中会存储账本的交易数据,但账本的第一个区块是一个例外,该区块不存储交易数据而是存储配置信息,通常账本的第一个区块称为创始块。

我们需要些编写生成创始块文件的配置文件,配置文件名字为configtx.yaml, 该名字不要修改, 写好之后放入Demo目录中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# configtx.yaml
---
################################################################################
#
# Section: Organizations
#
# - This section defines the different organizational identities which will
# be referenced later in the configuration.
#
################################################################################
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: ./crypto-config/ordererOrganizations/wumansgy.com/msp

- &OrgGo
Name: OrgGoMSP
ID: OrgGoMSP
MSPDir: ./crypto-config/peerOrganizations/orggo.wumansgy.com/msp
AnchorPeers:
- Host: peer0.orggo.wumansgy.com
Port: 7051

- &OrgCPP
Name: OrgCppMSP
ID: OrgCppMSP
MSPDir: ./crypto-config/peerOrganizations/orgcpp.wumansgy.com/msp
AnchorPeers:
- Host: peer0.orgcpp.wumansgy.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:
Global: &ChannelCapabilities
V1_1: true

Orderer: &OrdererCapabilities
V1_1: true

Application: &ApplicationCapabilities
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:

################################################################################
#
# SECTION: Orderer
#
# - This section defines the values to encode into a config transaction or
# genesis block for orderer related parameters
#
################################################################################
Orderer: &OrdererDefaults
# Available types are "solo" and "kafka"
OrdererType: solo
Addresses:
- ubuntu.wumansgy.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
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB

Kafka:
# Brokers: A list of Kafka brokers to which the orderer connects
# NOTE: Use IP:port notation
Brokers:
- 127.0.0.1:9092
Organizations:

################################################################################
#
# Profile
#
# - Different configuration profiles may be encoded here to be specified
# as parameters to the configtxgen tool
#
################################################################################
Profiles:

wumansgyOrdererGenesis:
Capabilities:
<<: *ChannelCapabilities
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *OrgGo
- *OrgCPP
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *OrgGo
- *OrgCPP
Capabilities:
<<: *ApplicationCapabilities
1
2
3
4
# 1. 在Demo目录下创建新目录 channel-artifacts, 将生成的创始块和通道文件存储在该目录中
$ mkdir channel-artifacts
# 生成创始块文件
$ configtxgen -profile wumansgyOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

通道(频道)在Fabric中称为channel, 一个channel表示一个账本。fabric和其他区块链平台最大的区别是支持多账本。每个fabric中至少包含一个channel,下边我们将通过命令将通道创建出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建channel
# channel.tx中包含了用于生产channel的信息
$ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
# 生成相关的锚点文件 - 组织1: Go
$ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/OrgGoMSPanchors.tx -channelID mychannel -asOrg OrgGoMSP
# 生成相关的锚点文件 - 组织2: CPP
$ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/OrgCppMSPanchors.tx -channelID mychannel -asOrg OrgCppMSP
# 查看channel-artifacts目录下生成的文件
$ tree channel-artifacts/
channel-artifacts/
├── channel.tx # 通道文件
├── genesis.block # 创始块文件
├── orgCppMSPanchors.tx # Cpp组织锚点文件
└── orgGoMSPanchors.tx # Go组织锚点文件

4.3 启动docker-compose

4.3.1 编写配置文件

编写docker-compose启动时加载的配置文件,默认加载的文件名为:`docker-compose.yml/yaml,可通过命令docker-compose --help查看。我们将该文件放到项目目录~/Demo中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# docker-compose.yml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
# compose 版本号
version: '2'
# 数据卷映射, 本地 -> docker镜像
volumes:
ubuntu.wumansgy.com:
peer0.orggo.wumansgy.com:
peer1.orggo.wumansgy.com:
peer0.orgcpp.wumansgy.com:
peer1.orgcpp.wumansgy.com:

networks: # 指定容器运行的网络, 同一网络中的容器才能相互通信
byfn:

services:
ubuntu.wumansgy.com: # 定义的第1个服务名
extends: # 继承自当前yaml文件或者其它文件中定义的服务
file: base/docker-compose-base.yaml
# 要继承上述file文件中对应的名字叫做 ubuntu.wumansgy.com 的服务
service: ubuntu.wumansgy.com
container_name: ubuntu.wumansgy.com # 容器名称, 可以自定义
networks: # 指定容器启动后运行的网络名
- byfn

peer0.orggo.wumansgy.com: # 定义的第2个服务名
container_name: peer0.orggo.wumansgy.com
extends:
file: base/docker-compose-base.yaml
service: peer0.orggo.wumansgy.com
networks:
- byfn

peer1.orggo.wumansgy.com: # 定义的第3个服务名
container_name: peer1.orggo.wumansgy.com
extends:
file: base/docker-compose-base.yaml
service: peer1.orggo.wumansgy.com
networks:
- byfn

peer0.orgcpp.wumansgy.com: # 定义的第4个服务名
container_name: peer0.orgcpp.wumansgy.com
extends:
file: base/docker-compose-base.yaml
service: peer0.orgcpp.wumansgy.com
networks:
- byfn

peer1.orgcpp.wumansgy.com: # 定义的第5个服务名
container_name: peer1.orgcpp.wumansgy.com
extends:
file: base/docker-compose-base.yaml
service: peer1.orgcpp.wumansgy.com
networks:
- byfn

cli: # 定义的第6个服务名
container_name: cli
image: hyperledger/fabric-tools:latest # 指定服务的镜像名称或镜像 ID
tty: true
stdin_open: true
environment: # 环境变量设置
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
#- CORE_LOGGING_LEVEL=INFO
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.orggo.wumansgy.com:7051
- CORE_PEER_LOCALMSPID=OrgGoMSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.wumansgy.com/peers/peer0.orggo.wumansgy.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.wumansgy.com/peers/peer0.orggo.wumansgy.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.wumansgy.com/peers/peer0.orggo.wumansgy.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.wumansgy.com/users/Admin@orggo.wumansgy.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/chaincode
- ./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: # 指定了容器的启动顺序, 下边5个服务全部启动之后, 启动cli服务
- ubuntu.wumansgy.com # 定义的服务器名1
- peer0.orggo.wumansgy.com # 定义的服务器名2
- peer1.orggo.wumansgy.com # 定义的服务器名3
- peer0.orgcpp.wumansgy.com # 定义的服务器名4
- peer1.orgcpp.wumansgy.com # 定义的服务器名5
networks:
- byfn

接下来就上面 docker-compose.yaml 文件中依赖的文件docker-compose-base.yaml,根据上面的指定可以知道该文件是放到base目录中,也就是说需要在Demo目录中创建子目录base:mkdir base

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# ~/Demo/base/docker-compose-base.yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
services:
ubuntu.wumansgy.com: # 排序节点服务名称
container_name: ubuntu.wumansgy.com
image: hyperledger/fabric-orderer:latest
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
- orderer.example.com:/var/hyperledger/production/orderer
ports:
- 7050:7050

peer0.orggo.wumansgy.com:
container_name: peer0.orggo.wumansgy.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.orggo.wumansgy.com
- CORE_PEER_ADDRESS=peer0.orggo.wumansgy.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.orggo.wumansgy.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.orggo.wumansgy.com:7051
- CORE_PEER_LOCALMSPID=OrgGoMSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/orggo.example.com/peers/peer0.orggo.wumansgy.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/orggo.example.com/peers/peer0.orggo.wumansgy.com/tls:/etc/hyperledger/fabric/tls
- peer0.orggo.wumansgy.com:/var/hyperledger/production
ports:
- 7051:7051
- 7053:7053

peer1.orggo.wumansgy.com:
container_name: peer1.orggo.wumansgy.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.orggo.wumansgy.com
- CORE_PEER_ADDRESS=peer1.orggo.wumansgy.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.orggo.wumansgy.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.orggo.wumansgy.com:7051
- CORE_PEER_LOCALMSPID=OrgGoMSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/orggo.wumansgy.com/peers/peer1.orggo.wumansgy.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/orggo.wumansgy.com/peers/peer1.orggo.wumansgy.com/tls:/etc/hyperledger/fabric/tls
- peer1.orggo.wumansgy.com:/var/hyperledger/production

ports:
- 8051:7051
- 8053:7053

peer0.orgcpp.wumansgy.com:
container_name: peer0.orgcpp.wumansgy.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.orgcpp.wumansgy.com
- CORE_PEER_ADDRESS=peer0.orgcpp.wumansgy.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.orgcpp.wumansgy.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.orgcpp.wumansgy.com:7051
- CORE_PEER_LOCALMSPID=OrgCppMSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/orgcpp.wumansgy.com/peers/peer0.orgcpp.wumansgy.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/orgcpp.wumansgy.com/peers/peer0.orgcpp.wumansgy.com/tls:/etc/hyperledger/fabric/tls
- peer0.orgcpp.wumansgy.com:/var/hyperledger/production
ports:
- 9051:7051
- 9053:7053

peer1.orgcpp.wumansgy.com:
container_name: peer1.orgcpp.wumansgy.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.orgcpp.wumansgy.com
- CORE_PEER_ADDRESS=peer1.orgcpp.wumansgy.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.orgcpp.wumansgy.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.orgcpp.wumansgy.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/orgcpp.example.com/peers/peer1.orgcpp.wumansgy.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/orgcpp.example.com/peers/peer1.orgcpp.wumansgy.com/tls:/etc/hyperledger/fabric/tls
- peer1.orgcpp.wumansgy.com:/var/hyperledger/production
ports:
- 10051:7051
- 10053:7053

在上面的docker-compose-base.yaml文件中又引用了文件peer-base.yaml,接下来我们对该文件进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# ~/Demo/base/peer-base.yaml
version: '2'
services:
peer-base:
image: hyperledger/fabric-peer:latest
environment:
- 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=Demo_byfn
- CORE_LOGGING_LEVEL=INFO
#- CORE_LOGGING_LEVEL=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
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start

4.3.2 通过docker-compose启动容器

docker-compose的配置文件编写完成之后, 我们就可以通过配置文件中的配置将所有节点的容器全部启动起来.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 启动容器
# 在 ~/Demo目录下启动docker-compose, 该目录下有编写好的docker-compose.yaml文件
# 命令启动之后, 会自动加载该文件, 也可以通过-f指定要加载的yaml文件
$ docker-compose up -d
Creating network "demo_byfn" with the default driver
Creating volume "demo_peer1.orggo.wumansgy.com" with default driver
Creating volume "demo_ubuntu.wumansgy.com" with default driver
Creating volume "demo_peer0.orgcpp.wumansgy.com" with default driver
Creating volume "demo_peer0.orggo.wumansgy.com" with default driver
Creating volume "demo_peer1.orgcpp.wumansgy.com" with default driver
Creating peer0.orgcpp.wumansgy.com ... done
Creating peer1.orgcpp.wumansgy.com ... done
Creating peer1.orggo.wumansgy.com ... done
Creating peer0.orggo.wumansgy.com ... done
Creating ubuntu.wumansgy.com ... done
Creating cli ... done
# 查看已启动的容器
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------
cli /bin/bash Up
peer0.orgcpp.wumansgy.com peer node start Up 0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp
peer0.orggo.wumansgy.com peer node start Up 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp
peer1.orgcpp.wumansgy.com peer node start Up 0.0.0.0:10051->7051/tcp,0.0.0.0:10053->7053/tcp
peer1.orggo.wumansgy.com peer node start Up 0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp
ubuntu.wumansgy.com orderer Up 0.0.0.0:7050->7050/tcp

4.4 channel管理

4.4.1 操作步骤

这个动作需要在cli容器中运行

  • 创建channel

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 进入cli容器
    $ docker exec -it cli bash
    $ peer channel create -o ubuntu.wumansgy.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA
    # 参数说明:
    - ubuntu.wumansgy.com: 连接的orderer的地址,hostname:port
    - $CHANNEL_NAME: channel的名称,如果没有指定,默认为mychannel, 通道创建成功之后会在磁盘生成
    一个文件, 名字为$CHANNEL_NAME.block(通道名.block)
    - $CORE_PEER_TLS_ENABLED: 和orderer通信时是否启用tls
    - $ORDERER_CA: 使用tls时,所使用的orderer的证书

    该命令执行过程:

    • 发送消息,创建了channel,名字为$CHANNEL_NAME
    • 获取创始区块,并且用protobuf进行序列化,本地生成了一个文件$CHANNEL_NAME.block
  • 将peer节点添加到channel中

    1
    2
    3
    $ peer channel join -b $CHANNEL_NAME.block
    # 参数说明:
    $CHANNEL_NAME.block, 创建出的通道文件的名字
  • 将每个组织的锚节点(anchor peer)更新到orderer

    1
    2
    3
    4
    5
    6
    $ peer channel update -o ubuntu.wumansgy.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA
    # 参数说明:
    - ubuntu.wumansgy.com: 连接的orderer的地址,hostname:port
    - ${CORE_PEER_LOCALMSPID}anchors.tx: 组织的锚节点文件, 是通过configtxgen指令生成的
    - $CORE_PEER_TLS_ENABLED: 和orderer通信时是否启用tls
    - $ORDERER_CA: 使用tls时,所使用的orderer的证书

4.4.2 脚本编写

上述操作需要对多个节点进行操作,因此我们可以写一个脚本文件, 对这些操作进行统一处理,方便使用者进行操作。为了对编写的脚本统一管理,可以将其放入一个目录中。

我们可以在~/Demo目录下创建新的子目录scripts, 将所有的脚本文件放到里边。编写的脚本如下:

会被调用多次的操作, 我们将其放到一个单独的脚本文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 该脚本文件我们命名为 utils.sh
# ~/Demo/utils.sh
# 定义一些变量, 下边的代码中会使用
# orderer 节点的证书
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/wumansgy.com/orderers/ubuntu.wumansgy.com/msp/tlscacerts/tlsca.wumansgy.com-cert.pem
# Go组织peer0节点证书
PEER0_ORGGO_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.wumansgy.com/peers/peer0.orggo.wumansgy.com/tls/ca.crt
# CPP组织peer0节点证书
PEER0_ORGCPP_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.wumansgy.com/peers/peer0.orgcpp.wumansgy.com/tls/ca.crt

# 根据传递进行来的参数读取各个组织中各节点信息
# 第一次参数表示节点编号, 第二个参数表示组织编号
setGlobals() {
PEER=$1
ORG=$2
if [ $ORG -eq 1 ]; then
CORE_PEER_LOCALMSPID="OrgGoMSP" # Go组织的ID, 在configtx.yaml中设置的
# 客户端cli想要连接哪个节点, 就必须要设置该节点的证书路径
CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORGGO_CA # cli可以连接Go组织的peer0节点
# Go组织的管理员证书
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
peerOrganizations/orggo.wumansgy.com/users/Admin@orggo.wumansgy.com/msp
if [ $PEER -eq 0 ]; then
CORE_PEER_ADDRESS=peer0.orggo.wumansgy.com:7051 # go组织peer0地址
else
CORE_PEER_ADDRESS=peer1.orggo.wumansgy.com:7051 # go组织peer1地址
fi
elif [ $ORG -eq 2 ]; then
CORE_PEER_LOCALMSPID="OrgCppMSP" # CPP组织ID
CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORGCPP_CA # cli可以连接CPP组织的peer0节点
# CPP组织的管理员证书
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
peerOrganizations/orgcpp.wumansgy.com/users/Admin@orgcpp.wumansgy.com/msp
if [ $PEER -eq 0 ]; then
CORE_PEER_ADDRESS=peer0.orgcpp.wumansgy.com:7051 # cpp组织peer0地址
else
CORE_PEER_ADDRESS=peer1.orgcpp.wumansgy.com:7051 # cpp组织peer0地址
fi
else
echo "================== ERROR !!! ORG Unknown =================="
fi
if [ "$VERBOSE" == "true" ]; then
env | grep CORE
fi
}

# 该函数对命令执行的结果进行验证, 如果验证失败, 直接退出, 不再执行后续操作流程
verifyResult() {
if [ $1 -ne 0 ]; then
echo "!!!!!!!!!!!!!!! "$2" !!!!!!!!!!!!!!!!"
echo "========= ERROR !!! FAILED ==========="
echo
exit 1
fi
}

创建通道操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 该脚本文件我们命名为createChannel.sh
# ~/Demo/createChannel.sh
# 定义一些变量, 下边的代码中会使用
CHANNEL_NAME="$1" # 脚本文件执行时接收的第1个参数
DELAY="$2" # 脚本文件执行时接收的第2个参数
LANGUAGE="$3" # 脚本文件执行时接收的第3个参数
: ${CHANNEL_NAME:="mychannel"} # 通道名,如果值为空, 变量CHANNEL_NAME值设置为mychannel
: ${DELAY:="3"} # 延时时长,如果值为空, 变量DELAY值设置为3, 操作失败重试时使用
: ${LANGUAGE:="golang"} # 链码语言,如果值为空, 变量LANGUAGE值设置为golang
LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` # 语言转换为大写,再转换为小写
COUNTER=1 # 计数器
MAX_RETRY=5 # 操作失败,重试的次数
# 链码文件路径
CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" # go链码
if [ "$LANGUAGE" = "node" ]; then # node.js链码
CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/node/"
fi
echo "Channel name : "$CHANNEL_NAME # 打印通道的名字

# ====================================================
# 创建通道
# ====================================================
# 引用 utils.sh 脚本, 该文件也被创建在scripts目录中
. scripts/utils.sh
createChannel() {
setGlobals 0 1
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
set -x
# 创建通道, 不使用tls加密, 结果重定向到文件log.txt中
peer channel create -o ubuntu.wumansgy.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx >&log.txt
res=$? # 保存 peer channel create 命令的返回值
set +x
else
set -x
# 创建通道, 使用tls加密, 结果重定向到文件log.txt中
peer channel create -o ubuntu.wumansgy.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA >&log.txt
res=$? # 保存 peer channel create 命令的返回值
set +x
fi
cat log.txt # 将log文件内容输出到终端
verifyResult $res "Channel creation failed" # 验证操作是否成功
echo "===================== Channel '$CHANNEL_NAME' created ===================== "
echo
}
# 调用创建通道的函数
createChannel

将节点添加到通道中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 该脚本文件我们命名为joinChannel.sh
# ~/Demo/joinChannel.sh
# 定义一些变量, 下边的代码中会使用
# ====================================================
# 加入通道
# ====================================================
# 引用 utils.sh, createChannel.sh 脚本, 该文件也被创建在scripts目录中
. scripts/utils.sh
. scripts/createChannel.sh
joinChannel () {
for org in 1 2; do
for peer in 0 1; do
joinChannelWithRetry $peer $org
echo "======== peer${peer}.org${org} joined channel '$CHANNEL_NAME' ======== "
sleep $DELAY
echo
done
done
}
joinChannelWithRetry() {
PEER=$1
ORG=$2
setGlobals $PEER $ORG

set -x
peer channel join -b $CHANNEL_NAME.block >&log.txt
res=$?
set +x
cat log.txt
if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then
COUNTER=$(expr $COUNTER + 1)
echo "peer${PEER}.org${ORG} failed to join the channel, Retry after $DELAY seconds"
sleep $DELAY
joinChannelWithRetry $PEER $ORG
else
COUNTER=1
fi
verifyResult $res "After $MAX_RETRY attempts, peer${PEER}.org${ORG} has failed to join channel '$CHANNEL_NAME' "
}
# 函数调用
joinChannel

将每个组织的锚节点(anchor peer)更新到orderer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 该脚本文件我们命名为updateChannel.sh
# ~/Demo/updateChannel.sh
# 引用 utils.sh, createChannel.sh 脚本, 该文件也被创建在scripts目录中
. scripts/utils.sh
. scripts/createChannel.sh
updateAnchorPeers() {
PEER=$1
ORG=$2
setGlobals $PEER $ORG
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
set -x
# 更新锚节点不使用tls加密, 得到的结果保存到log.txt中
peer channel update -o ubuntu.wumansgy.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx >&log.txt
res=$?
set +x
else
set -x
# 更新锚节点使用tls加密, 得到的结果保存到log.txt中
peer channel update -o ubuntu.wumansgy.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA >&log.txt
res=$?
set +x
fi
cat log.txt
verifyResult $res "Anchor peer update failed"
echo " Anchor peers updated for org '$CORE_PEER_LOCALMSPID' on channel '$CHANNEL_NAME' "
sleep $DELAY # 休眠
echo
}
# 函数调用
echo "Updating anchor peers for orggo..."
updateAnchorPeers 0 1
echo "Updating anchor peers for orgcpp..."
updateAnchorPeers 0 2

4.5 chaincode安装和实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 该脚本文件我们命名为installChainCode.sh
# ~/Demo/installChainCode.sh
# 引用 utils.sh, createChannel.sh 脚本, 该文件也被创建在scripts目录中
. scripts/utils.sh
. scripts/createChannel.sh
# 安装链码
installChaincode()
{
PEER=$1
ORG=$2
setGlobals $PEER $ORG
VERSION=${3:-1.0}
set -x
peer chaincode install -n mycc -v ${VERSION} -l ${LANGUAGE} -p ${CC_SRC_PATH} >&log.txt
res=$?
set +x
cat log.txt
verifyResult $res "Chaincode installation on peer${PEER}.org${ORG} has failed"
echo "===================== Chaincode is installed on peer${PEER}.org${ORG} ===================== "
echo
}

# 链码初始化
instantiateChaincode()
{
PEER=$1
ORG=$2
setGlobals $PEER $ORG
VERSION=${3:-1.0}

# while 'peer chaincode' command can get the orderer endpoint from the peer
# (if join was successful), let's supply it directly as we know it using
# the "-o" option
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
set -x
peer chaincode instantiate -o ubuntu.wumansgy.com:7050 -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v ${VERSION} -c '{"Args":["init","a","100","b","200"]}' -P "AND ('OrgGoMSP.peer','OrgCppMSP.peer')" >&log.txt
res=$?
set +x
else
set -x
peer chaincode instantiate -o ubuntu.wumansgy.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('OrgGoMSP.peer','OrgCppMSP.peer')" >&log.txt
res=$?
set +x
fi
cat log.txt
verifyResult $res "Chaincode instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' failed"
echo " Chaincode is instantiated on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME'"
echo
}

# 函数调用
# go组织的peer0, peer1安装链码
echo "Install chaincode on peer0.orggo..."
#nstallChaincode 0 1
echo "Install chaincode on peer0.orggo..."
installChaincode 0 2
# cpp组织的peer0, peer1安装链码
# go组织的peer0进行初始化
echo "Instantiating chaincode on peer0.org2..."
instantiateChaincode 0 2
-------------本文结束感谢您的阅读-------------

本文标题:Fabric网络搭建

文章作者:Wuman

发布时间:2019年01月06日 - 20:01

最后更新:2019年01月06日 - 21:01

原始链接:http://yoursite.com/2019/01/06/Fabric网络搭建/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。