前提条件

启动上一步的自定义network网络

1
./network-myself.sh up

拷贝配置文件

以下文件是配置文件及相关脚本文件:

1
2
3
4
5
6
mkdir configtx  #创建配置文件目录
cp ../test-network/configtx/configtx.yaml ./configtx/ #拷贝测试网络中的配置文件,用于创建通道创世区块使用
cp ../test-network/scripts/setAnchorPeer.sh ./scripts/ #拷贝测试网络中的配置文件,用于创建通道时设置锚节点使用
cp ../test-network/scripts/envVar.sh ./scripts/
cp ../test-network/scripts/configUpdate.sh ./scripts/
cp ../test-network/scripts/utils.sh ./scripts/

configtx.yaml文件指定新通道的通道配置,configtxgen工具使用configtx.yaml文件中定义的通道配置来创建通道配置,并将其写入protobuf格式,然后由Fabric读取。同时也会为系统通道创建完整的创世块。

setAnchorPeer.sh 设置锚节点脚本,在设置节点时使用。

envVar.sh、configUpdate.sh、utils.sh被setAnchorPeer.sh调用,因些一起拷贝过来。

创建目录channel-artifacts

1
mkdir channel-artifacts

设置环境变量

设置排序节点的公钥、私钥、证书位置,设置peer节点证书位置

1
2
3
4
5
6
7
8
9
export CORE_PEER_TLS_ENABLED=true
export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export PEER0_ORG1_CA=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export PEER0_ORG2_CA=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export PEER0_ORG3_CA=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
export FABRIC_CFG_PATH=${PWD}/configtx #configtx.yaml文件所在的目录
export BLOCKFILE="./channel-artifacts/mychannel.block"

FABRIC_CFG_PATH:configtx.yaml文件所在的目录

BLOCKFILE:区块链文件位置

生成通道创世区块mychannel.block文件

使用configtxgen工具通过配置文件./configtx/configtx.yaml来创建Orderer系统通道的创世块

1
configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/mychannel.block -channelID mychannel

设置环境变量org1 并重置FABRIC_CFG_PATH

1
2
3
4
5
export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

创建通道

osnamdin channel命令与排序节点进行通信时需要使用TLS证书与私钥,在Fabric v2.3版本中创建通道时,直接创建应用通道,不再创建由排序服务管理的系统通道了。

1
osnadmin channel join --channelID mychannel --config-block ./channel-artifacts/mychannel.block -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY" 

将组织中peer节点加入通道

设置环境变量为org1

此处调用envVar.sh脚本中的函数及参数 setGlobals 1,得到以下脚本

1
2
3
4
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

将节点加入通道

1
peer channel join -b $BLOCKFILE

将org2的peer节点加入通道

设置环境变量为org2

此处调用envVar.sh脚本中的函数及参数 setGlobals 2,得到以下脚本

1
2
3
4
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

将节点加入通道

1
peer channel join -b $BLOCKFILE

设置锚节点

组织的peer节点加入通道后,应至少选择一个peer节点成为锚节点。当前有2个组织,每个组织只有一个peer节点,因此为这2个peer节点设定锚节点。

设置org1中的锚节点

docker exec命令中使用setAnchorPeer.sh脚本返回的信息作为参数部分

1
docker exec cli ./scripts/setAnchorPeer.sh 1 mychannel

设置org2中的锚节点

1
docker exec cli ./scripts/setAnchorPeer.sh 2 mychannel

生成创建通道脚本

前提条件

保留本文步骤1中前提条件中生成的文件,当前目录存在的文件如所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost test-network-myself]# tree 
.
├── channel-artifacts
│ └── mychannel.block
├── configtx
│ └── configtx.yaml #本次新增文件:创建通道创世块使用
├── crypto-config.yaml
├── docker
│ └── docker-compose-test-net.yaml
├── network-myself.sh #本次将做修改的文件:增加创建通道功能
├── organizations
│ ├── ccp-generate.sh
│ ├── ccp-template.json
│ └── ccp-template.yaml
├── scripts
│ ├── configUpdate.sh #本次新增文件:被创建锚节点调用的脚本文件
│ ├── envVar.sh #本次新增文件:设置环境变量、切换组织函数、验证执行命令结果函数等
│ ├── setAnchorPeer.sh #本次新增文件:创建锚节点脚本文件
│ └── utils.sh 本次新增文件: 打印输出信息脚本文件
└── system-genesis-block

编辑脚本文件network-myself.sh

此脚本为简化版本,没有过多的验证,即认为每个命令都会正常执行。

修改network-myself.sh内容为以下:

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
#!/bin/bash


#开启自己的测试网络
function networkUpMyself() {
# 关闭自己的测试网络
networkDownMyself

set -x
# 生成组织及证书
cryptogen generate --config=./crypto-config.yaml --output="organizations"

# 执行ccp-generate.sh脚本,生成通用连通配置文件
./organizations/ccp-generate.sh

# 启动网络
export DOCKER_SOCK=/var/run/docker.sock
docker-compose -f $COMPOSE_FILE_BASE up -d

set +x
}


#关闭自己的测试网络
function networkDownMyself() {

set -x

#停止和删除容器、网络、卷、镜像
export DOCKER_SOCK=/var/run/docker.sock
docker-compose -f $COMPOSE_FILE_BASE down --volumes --remove-orphans

#删除节点目录
rm -rf ./organizations/*Organizations

#删除block
rm -rf ./system-genesis-block/*.block

set +x
}


# 创建通道
function createChannelMyself() {
# 通过是否存在目录organizations/peerOrganizations,判断是否启动了网络,若没有此目录,则启动网络
if [ ! -d "organizations/peerOrganizations" ]; then
networkUpMyself
fi

# 设置环境变量,设置排序节点的公钥、私钥、证书位置,设置peer节点证书位置
export CORE_PEER_TLS_ENABLED=true
export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export PEER0_ORG1_CA=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export PEER0_ORG2_CA=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export PEER0_ORG3_CA=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
# configtx.yaml文件所在的目录
export FABRIC_CFG_PATH=${PWD}/configtx
# 区块链文件位置
export BLOCKFILE="./channel-artifacts/mychannel.block"

# 生成创世区块mychannel.block文件,根据配置文件./configtx/configtx.yaml来创建Orderer系统通道的创世块
configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/mychannel.block -channelID mychannel

# 重置环境变量
export FABRIC_CFG_PATH=$PWD/../config/

# 设置环境变量为org1,调用envVar.sh脚本中的函数及参数 setGlobals 1
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

sleep 3

# 创建通道
osnadmin channel join --channelID mychannel --config-block ./channel-artifacts/mychannel.block -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"

# 设置环境变量为org1,调用envVar.sh脚本中的函数及参数 setGlobals 1
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

sleep 3

# 将org1的节点加入通道
peer channel join -b $BLOCKFILE

# 设置环境变量为org2,调用envVar.sh脚本中的函数及参数 setGlobals 2
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

sleep 3

# 将org2节点加入通道
peer channel join -b $BLOCKFILE

# 设置组织org1的锚节点,docker exec命令中使用setAnchorPeer.sh脚本返回的信息作为参数部分
docker exec cli ./scripts/setAnchorPeer.sh 1 mychannel

# 设置组织org2的锚节点,docker exec命令中使用setAnchorPeer.sh脚本返回的信息作为参数部分
docker exec cli ./scripts/setAnchorPeer.sh 2 mychannel


}

# docker-compose yaml文件地址
COMPOSE_FILE_BASE=docker/docker-compose-test-net.yaml

#参数命令
MODE=$1


if [ "${MODE}" == "up" ]; then
echo "开启自己的测试网络"
networkUpMyself
elif [ "${MODE}" == "down" ]; then
echo "关闭自己的测试网络"
networkDownMyself
elif [ "${MODE}" == "createChannel" ]; then
echo "创建通道"
createChannelMyself
else
echo "up 开启自己的测试网络"
echo "down 关闭自己的测试网络"
echo "createChannel 创建通道"
exit 1
fi

脚本中增加了创建通道函数createChannelMyself

测试 - 创建通道

1
./network-myself.sh createChannel