生成证书文件
官方文档
- 新建一个项目文件夹
twonodes
- 导出模板文件
crypto-config.yaml到twonodes中
1
|
cryptogen showtemplate > crypto-config.yaml
|
- 根据需要修改模板文件
- 生成证书文件
1
|
cryptogen generate --config=crypto-config.yaml
|
- 执行该命令可以看到新生成文件夹
crypto-config
生成创始块和通道文件
官方文档
- 从
/fabric-samples/test-network/configtx中获取configyx.yaml模板
- 修改
configyx.yaml模板最后的Profiles配置为官方文档中看到的v2.2版本格式(LTS)
- 修改
configyx.yaml中Organizations的所有MSP路径为项目具体路径(相对路径)
crypto-config/ordererOrganizations/example.com/msp
crypto-config/peerOrganizations/org1.example.com/msp
crypto-config/peerOrganizations/org2.example.com/msp
- 修改
configyx.yaml中Orderer的所有证书路径为项目具体路径(相对路径)
crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
- 生成创始块文件
genesis.block到./channel-artifacts/genesis.block路径下,指定channelID为fabric-channel
1
|
configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block -channelID fabric-channel
|
- 生成通道文件
channel.tx,指定channelID为mychannel
1
|
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
|
生成节点
官方文档
hyperledger/fabric-peer - Docker Image | Docker Hub
- 从
/fabric-samples/test-network/configtx中获取docker-compose.yaml模板,将docker-compose-test-net改名为docker-compose.yaml
- 编写
docker-compose.yaml文件,用来管理容器

- 修改
Orderer节点的挂载路径为当前项目路径

- 修改
Org1、Org2的peer节点


- 将一个用户改为两个用户,一个客户端对应一个
peer节点
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
version: '2.4'
volumes:
orderer.example.com:
peer0.org1.example.com:
peer0.org2.example.com:
networks:
test:
name: twonodes_test
services:
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer:2.2
environment:
- FABRIC_LOGGING_SPEC=DEBUG
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_LISTENPORT=7050
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_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]
# - ORDERER_GENERAL_BOOTSTRAPMETHOD=none
- ORDERER_CHANNELPARTICIPATION_ENABLED=true
- ORDERER_ADMIN_TLS_ENABLED=true
- ORDERER_ADMIN_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_ADMIN_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_ADMIN_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
- ORDERER_ADMIN_TLS_CLIENTROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
- ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:7053
# - ORDERER_OPERATIONS_LISTENADDRESS=orderer.example.com:9443
# - ORDERER_METRICS_PROVIDER=prometheus
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
- 7053:7053
networks:
- test
peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer:2.2
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=twonodes_test
- FABRIC_LOGGING_SPEC=DEBUG
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
# Peer specific variabes
- CORE_PEER_ID=peer0.org1.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
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./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
- peer0.org1.example.com:/var/hyperledger/production
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 7051:7051
depends_on:
- orderer.example.com
#- couchdb.org1.example.com
networks:
- test
peer0.org2.example.com:
container_name: peer0.org2.example.com
image: hyperledger/fabric-peer:2.2
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=twonodes_test
- FABRIC_LOGGING_SPEC=DEBUG
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
# Peer specific variabes
- CORE_PEER_ID=peer0.org2.example.com
- CORE_PEER_ADDRESS=peer0.org2.example.com:9051
- CORE_PEER_LISTENADDRESS=0.0.0.0:9051
- CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:9052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:9052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:9051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:9051
- CORE_PEER_LOCALMSPID=Org2MSP
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ./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
- peer0.org2.example.com:/var/hyperledger/production
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 9051:9051
networks:
- test
cli1:
container_name: cli1
image: hyperledger/fabric-tools:latest
labels:
service: hyperledger-fabric
tty: true
stdin_open: true
environment: # 环境变量相关设置
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=cli1
- 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
#- FABRIC_LOGGING_SPEC=DEBUG
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
# 挂载目录,默认就行
- /var/run/:/host/var/run/
# 链码存放路径(go或者node.js写的链代码)
- ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
# 存放证书的路径
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
# 生成的创世块和管道以及更新的锚节点文件存放的路径(tx和block后缀的文件)
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
# 注意:./channel-artifacts这种是指路径,需要本地有这个路径,或者改成自己的路径
depends_on:
- peer0.org1.example.com
- peer0.org2.example.com
networks:
- test
cli2:
container_name: cli2
image: hyperledger/fabric-tools:latest
labels:
service: hyperledger-fabric
tty: true
stdin_open: true
environment: # 环境变量相关设置
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=cli2
- CORE_PEER_ADDRESS=peer0.org2.example.com:9051
- CORE_PEER_LOCALMSPID=Org2MSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key
- 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
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
#- FABRIC_LOGGING_SPEC=DEBUG
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
# 挂载目录,默认就行
- /var/run/:/host/var/run/
# 链码存放路径(go或者node.js写的链代码)
- ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
# 存放证书的路径
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
# 生成的创世块和管道以及更新的锚节点文件存放的路径(tx和block后缀的文件)
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
# 注意:./channel-artifacts这种是指路径,需要本地有这个路径,或者改成自己的路径
depends_on:
- peer0.org1.example.com
- peer0.org2.example.com
networks:
- test
|
- 启动容器(节点在容器中,一个容器中启动一个节点)

- 查看所有容器

- 关闭容器

- 清除未使用的数据卷
创建通道
peer channel — hyperledger-fabricdocs master 文档
- 进入
cli1容器
1
|
docker exec -it cli1 bash
|
- 创建通道
mychannel,在当前目录下生成mychannel.block文件
1
|
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem
|

- 退出容器,将
mychannel.block文件从cli1容器中先复制到本地,然后再从本地复制cli2容器中(cli1和cli2都要使用该通道文件加入同一通道)
1
2
|
docker cp cli1:/opt/gopath/src/github.com/hyperledger/fabric/peer/mychannel.block ./
docker cp ./mychannel.block cli2:/opt/gopath/src/github.com/hyperledger/fabric/peer
|
- 新开一个终端,进入
cli2容器中,查看是否复制成功
1
2
|
docker exec -it cli2 bash
ls
|
- 在
/etc/hosts文件中配置用到的所有节点的ip:127.0.0.1,保证节点间可以互相通信

- 进入容器,将
cli1和cli2都加入mychannel通道中
1
|
peer channel join -b mychannel.block
|

安装链码
- 从例程中选择一份链码
sacc.go复制到twonodes/chaincode/go中
- 进入
cli1容器内chaincode对应的挂载路径
1
|
cd /opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
|

- 添加依赖包
1
2
3
|
go env -w GOPROXY=https://goproxy.cn,direct
go mod init
go mod vendor
|

- 回到工作目录
1
|
cd /opt/gopath/src/github.com/hyperledger/fabric/peer
|
- 打包链码
sacc.tar.gz,标签为sacc_1,意思是第一版
1
2
3
|
peer lifecycle chaincode package sacc.tar.gz \
--path github.com/hyperledger/fabric/examples/chaincode/go/ \
--label sacc_1
|

- 退出容器,将打包链码复制到
cli2容器中
1
2
|
docker cp cli1:/opt/gopath/src/github.com/hyperledger/fabric/peer/sacc.tar.gz ./
docker cp sacc.tar.gz cli2:/opt/gopath/src/github.com/hyperledger/fabric/peer
|


- 在
cli1和cli2容器中安装链码
1
|
peer lifecycle chaincode install sacc.tar.gz
|

此处若报错build:2,这是说在vendor中的这个依赖找不到定义,一般情况下都是版本问题,将例程中的vendor文件夹和go.sum、go.mod等拷贝到twonodes/chainnode/go来用
- 组织批准链码,只有每个组织都批准该链码,该链码才能被安装到通道上(
cli1和cli2容器中都要执行一遍,因为这两个客户端分别连接着两个组织中的节点)
1
|
peer lifecycle chaincode approveformyorg --channelID mychannel --name sacc --version 1.0 --init-required --package-id [这里填链码ID,也就是上图中的sacc_1:0b...] --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
|
也可以用命令peer lifecycle chaincode queryinstalled查询--package-id

- 查询是否组织认证链码成功
1
|
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name sacc --version 1.0 --init-required --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json
|

- 提交链码到链上(在一个节点上提交就可以了,会自动同步到全部节点上)
1
|
peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID mychannel --name sacc --version 1.0 --sequence 1 --init-required --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
|

调用链码
peer chaincode — hyperledger-fabricdocs master 文档
- 在
cli1上提交一个键值对a:bb
1
|
peer chaincode invoke -o orderer.example.com:7050 --isInit --ordererTLSHostnameOverride orderer.example.com --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sacc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["a","bb"]}'
|

- 在
cli2上查询键a对应的值bb
1
|
peer chaincode query -C mychannel -n sacc -c '{"Args":["query","a"]}'
|

- 在
cli2上修改键值对为a:cc
1
|
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n sacc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["set","a","cc"]}'
|

- 在
cli1上查询键a对应的值cc
1
|
peer chaincode query -C mychannel -n sacc -c '{"Args":["query","a"]}'
|
