本文介绍如何搭建自己的测试环境的Fabric,该环境仅用于测试和学习相关组件的基础知识,在生产环境中,如何搭建环境,请参阅官方文档。
本机环境:Mac
1. 一键式部署Fabric
在fabirc代码中,在scripts目录下提供了一个脚本bootstrap.sh,该脚本可自动拉取fabric-samples代码,并拉取部署fabric的相关镜像,注意,如果你要安装指定版本的fabric,而不是最新版本的,请从版本对应的分支上下载对应的bootstrap.sh脚本。
本文采用的是2.2.4版本
将该脚本放在指定的文件目录下,该目录作为后续操作的主目录,然后给bootstrap.sh增加可执行权限
mkdir hyfa
cd hyfa
touch bootstrap.sh
将源码中的特定版本的bootstrap.sh内容copy到上面的文件中
chmod +x bootstrap.sh
./bootstrap.sh
安装过程的输出
Clone hyperledger/fabric-samples repo
===> Cloning hyperledger/fabric-samples repo and checkout v2.2.4
Cloning into 'fabric-samples'...
remote: Enumerating objects: 8350, done.
remote: Counting objects: 100% (625/625), done.
remote: Compressing objects: 100% (397/397), done.
remote: Total 8350 (delta 302), reused 450 (delta 217), pack-reused 7725
Receiving objects: 100% (8350/8350), 4.92 MiB | 2.70 MiB/s, done.
Resolving deltas: 100% (4336/4336), done.
error: pathspec 'v2.2.4' did not match any file(s) known to git
Pull Hyperledger Fabric binaries
===> Downloading version 2.2.4 platform specific fabric binaries
===> Downloading: https://github.com/hyperledger/fabric/releases/download/v2.2.4/hyperledger-fabric-darwin-amd64-2.2.4.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 681 100 681 0 0 1025 0 --:--:-- --:--:-- --:--:-- 1025
100 53.3M 100 53.3M 0 0 2697k 0 0:00:20 0:00:20 --:--:-- 3955k
==> Done.
===> Downloading version 1.5.2 platform specific fabric-ca-client binary
===> Downloading: https://github.com/hyperledger/fabric-ca/releases/download/v1.5.2/hyperledger-fabric-ca-darwin-amd64-1.5.2.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 653 100 653 0 0 1108 0 --:--:-- --:--:-- --:--:-- 1106
100 25.6M 100 25.6M 0 0 1885k 0 0:00:13 0:00:13 --:--:-- 2923k
==> Done.
Pull Hyperledger Fabric docker images
FABRIC_IMAGES: peer orderer ccenv tools nodeenv baseos javaenv
===> Pulling fabric Images
====> hyperledger/fabric-peer:2.2.4
2.2.4: Pulling from hyperledger/fabric-peer
a0d0a0d46f8b: Already exists
39f5dde72e6c: Pull complete
c60458617bd9: Pull complete
f03acaa6cd97: Pull complete
83c51587c9f2: Pull complete
ae7d6a041376: Pull complete
Digest: sha256:340025eb11f6537d71efd2820f2a643eb6f48708b0954b0f1592c87e8ce868d2
Status: Downloaded newer image for hyperledger/fabric-peer:2.2.4
docker.io/hyperledger/fabric-peer:2.2.4
====> hyperledger/fabric-orderer:2.2.4
2.2.4: Pulling from hyperledger/fabric-orderer
a0d0a0d46f8b: Already exists
39f5dde72e6c: Already exists
2fd7f2d0154d: Pull complete
f6fd9cda1337: Pull complete
7d80072c1a36: Pull complete
8bb955f8010f: Pull complete
f743c8ee18d0: Pull complete
Digest: sha256:12331afb762b431b520aec8b3e1fd7b83d5a1b3700deddb86e93a44c3fc2a9d7
Status: Downloaded newer image for hyperledger/fabric-orderer:2.2.4
docker.io/hyperledger/fabric-orderer:2.2.4
====> hyperledger/fabric-ccenv:2.2.4
2.2.4: Pulling from hyperledger/fabric-ccenv
a0d0a0d46f8b: Already exists
31adcdaf11c8: Pull complete
b8b176561691: Pull complete
ffa5077b735b: Pull complete
2e51fde7a4ad: Pull complete
88ec7036a0f0: Pull complete
300acd46ee50: Pull complete
921211ec1e72: Pull complete
665fbc77bd34: Pull complete
Digest: sha256:4ec70e9e41084635db80cc38357dfd6dcaa6fe7b40d84f16ab6366439358bab4
Status: Downloaded newer image for hyperledger/fabric-ccenv:2.2.4
docker.io/hyperledger/fabric-ccenv:2.2.4
====> hyperledger/fabric-tools:2.2.4
2.2.4: Pulling from hyperledger/fabric-tools
a0d0a0d46f8b: Already exists
31adcdaf11c8: Already exists
b8b176561691: Already exists
ffa5077b735b: Already exists
2e51fde7a4ad: Already exists
ca55bf76b621: Pull complete
fcc465d926d3: Pull complete
025eefba8376: Pull complete
Digest: sha256:a5f691808466e90942af3f5f72d697cdaa4e545acfc1f645a553986423ef7ea5
Status: Downloaded newer image for hyperledger/fabric-tools:2.2.4
docker.io/hyperledger/fabric-tools:2.2.4
====> hyperledger/fabric-nodeenv:2.2.4
Error response from daemon: manifest for hyperledger/fabric-nodeenv:2.2.4 not found: manifest unknown: manifest unknown
Error response from daemon: No such image: hyperledger/fabric-nodeenv:2.2.4
Error response from daemon: No such image: hyperledger/fabric-nodeenv:2.2.4
====> hyperledger/fabric-baseos:2.2.4
2.2.4: Pulling from hyperledger/fabric-baseos
a0d0a0d46f8b: Already exists
39f5dde72e6c: Already exists
bdbe3e81e212: Pull complete
Digest: sha256:d668bbd0f544eba72e98202236c2ed91b4001f4876be6d90f25e4f6b9b4e421c
Status: Downloaded newer image for hyperledger/fabric-baseos:2.2.4
docker.io/hyperledger/fabric-baseos:2.2.4
====> hyperledger/fabric-javaenv:2.2.4
Error response from daemon: manifest for hyperledger/fabric-javaenv:2.2.4 not found: manifest unknown: manifest unknown
Error response from daemon: No such image: hyperledger/fabric-javaenv:2.2.4
Error response from daemon: No such image: hyperledger/fabric-javaenv:2.2.4
===> Pulling fabric ca Image
====> hyperledger/fabric-ca:1.5.2
1.5.2: Pulling from hyperledger/fabric-ca
a0d0a0d46f8b: Already exists
ac8258c0aeb1: Pull complete
6c802cf1fa97: Pull complete
Digest: sha256:faa3b743d9ed391c30f518a7cc1168160bf335f3bf60ba6aaaf1aa49c1ed023e
Status: Downloaded newer image for hyperledger/fabric-ca:1.5.2
docker.io/hyperledger/fabric-ca:1.5.2
===> List out hyperledger docker images
hyperledger/fabric-ca 1.5 4ea287b75c63 2 months ago 69.8MB
hyperledger/fabric-ca 1.5.2 4ea287b75c63 2 months ago 69.8MB
hyperledger/fabric-ca latest 4ea287b75c63 2 months ago 69.8MB
hyperledger/fabric-tools 2.2 d32b30082179 2 months ago 429MB
hyperledger/fabric-tools 2.2.4 d32b30082179 2 months ago 429MB
hyperledger/fabric-tools latest d32b30082179 2 months ago 429MB
hyperledger/fabric-peer 2.2 4a3aed7a742c 2 months ago 51.8MB
hyperledger/fabric-peer 2.2.4 4a3aed7a742c 2 months ago 51.8MB
hyperledger/fabric-peer latest 4a3aed7a742c 2 months ago 51.8MB
hyperledger/fabric-orderer 2.2 abf523e91319 2 months ago 35.2MB
hyperledger/fabric-orderer 2.2.4 abf523e91319 2 months ago 35.2MB
hyperledger/fabric-orderer latest abf523e91319 2 months ago 35.2MB
hyperledger/fabric-ccenv 2.2 96b8a8b006b4 2 months ago 502MB
hyperledger/fabric-ccenv 2.2.4 96b8a8b006b4 2 months ago 502MB
hyperledger/fabric-ccenv latest 96b8a8b006b4 2 months ago 502MB
hyperledger/fabric-baseos 2.2 fb6d7b238996 2 months ago 6.87MB
hyperledger/fabric-baseos 2.2.4 fb6d7b238996 2 months ago 6.87MB
hyperledger/fabric-baseos latest fb6d7b238996 2 months ago 6.87MB
将fabric-samples中的可执行程序的路径添加到全局下:
export PATH=/Users/xxx/workspace/hyfa/fabric-samples/bin:$PATH
2.测试环境搭建
cd fabric-samples/test-network
该目录下有一个network.sh脚本,可以拉起一个测试环境,具体如何使用可以参考./network.sh --help
执行./network.sh up ,脚本将帮我们自动拉起一个测试环境
➜ test-network git:(master) ./network.sh up
Starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb' with crypto from 'cryptogen'
LOCAL_VERSION=2.2.4
DOCKER_IMAGE_VERSION=2.2.4
/Users/xxx/workspace/hyfa/fabric-samples/test-network/../bin/cryptogen
Generating certificates using cryptogen tool
Creating Org1 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
org1.example.com
+ res=0
Creating Org2 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output=organizations
org2.example.com
+ res=0
Creating Orderer Org Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output=organizations
+ res=0
Generating CCP files for Org1 and Org2
Creating network "fabric_test" with the default driver
Creating volume "docker_orderer.example.com" with default driver
Creating volume "docker_peer0.org1.example.com" with default driver
Creating volume "docker_peer0.org2.example.com" with default driver
Creating orderer.example.com ... done
Creating peer0.org2.example.com ... done
Creating peer0.org1.example.com ... done
Creating cli ... done
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d5108ab67ee hyperledger/fabric-tools:latest "/bin/bash" 4 seconds ago Up Less than a second cli
8c806f79310e hyperledger/fabric-peer:latest "peer node start" 13 seconds ago Up 3 seconds 0.0.0.0:7051->7051/tcp, :::7051->7051/tcp, 0.0.0.0:17051->17051/tcp, :::17051->17051/tcp peer0.org1.example.com
1cc1a2786582 hyperledger/fabric-peer:latest "peer node start" 13 seconds ago Up 5 seconds 0.0.0.0:9051->9051/tcp, :::9051->9051/tcp, 7051/tcp, 0.0.0.0:19051->19051/tcp, :::19051->19051/tcp peer0.org2.example.com
48136ece4636 hyperledger/fabric-orderer:latest "orderer" 13 seconds ago Up 1 second 0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:7053->7053/tcp, :::7053->7053/tcp, 0.0.0.0:17050->17050/tcp, :::17050->17050/tcp orderer.example.com
c2d41f77ba29 kong:latest "/docker-entrypoint.…" 3 days ago Exited (255) 2 hours ago 0.0.0.0:5555->5555/tcp, :::5555->5555/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:8002->8002/tcp, :::8002->8002/tcp, 127.0.0.1:8001->8001/tcp, 0.0.0.0:8443->8443/tcp, :::8443->8443/tcp, 127.0.0.1:8444->8444/tcp kong
dc9708005ac9 postgres:9.6 "docker-entrypoint.s…" 3 days ago Exited (255) 2 hours ago 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp kong-database
746673ca35ef kong-ee "/docker-entrypoint.…" 3 days ago Exited (1) 3 days ago kong-ee
ed95aaac394e kicbase/stable:v0.0.27 "/usr/local/bin/entr…" 3 weeks ago Exited (255) 7 days ago 127.0.0.1:55004->22/tcp, 127.0.0.1:55003->2376/tcp, 127.0.0.1:55002->5000/tcp, 127.0.0.1:55001->8443/tcp, 127.0.0.1:55000->32443/tcp minikube
6294196025b7 redis "docker-entrypoint.s…" 5 weeks ago Exited (255) 7 days ago 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp some-redis
322507528a23 postgres "docker-entrypoint.s…" 5 weeks ago Exited (255) 7 days ago 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp
通过脚本的输出,可以发现,整个测试环境的搭建过程。
该脚本将创建出一个order节点,两个peer节点,一个cli容器,用来和其他节点进行交互操作。
但是不会自动帮我们创建通道,如果需要自动帮我们创建通道,可以查看network.sh的帮助文档,比如,创建通道的命令为./network.sh createChannel
改命令的执行输出如下,
➜ test-network git:(ad8fc2f) ./network.sh createChannel
Creating channel 'mychannel'.
If network is not up, starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb
Generating channel create transaction 'mychannel.tx'
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
2021-11-22 11:23:03.380 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-11-22 11:23:03.397 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /Users/zhaojunwei/workspace/hyfa/fabric-samples/test-network/configtx/configtx.yaml
2021-11-22 11:23:03.397 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2021-11-22 11:23:03.402 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx
+ res=0
Creating channel mychannel
Using organization 1
+ peer channel create -o localhost:7050 -c mychannel --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /Users/zhaojunwei/workspace/hyfa/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=1
+ peer channel create -o localhost:7050 -c mychannel --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /Users/zhaojunwei/workspace/hyfa/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=1
+ peer channel create -o localhost:7050 -c mychannel --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /Users/zhaojunwei/workspace/hyfa/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=1
+ peer channel create -o localhost:7050 -c mychannel --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /Users/zhaojunwei/workspace/hyfa/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=1
2021-11-22 11:23:15.755 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Error: got unexpected status: BAD_REQUEST -- channel creation request not allowed because the orderer system channel is not defined
Channel creation failed
出现这个错误的原因是,自2.3版本开始,fabric支持不用在创建系统通道的前提下,就可以创建应用通道,但是2.1版本还是需要的
解决方案,
./network.sh down
Stopping network
Stopping cli ... done
Stopping peer0.org1.example.com ... done
Stopping peer0.org2.example.com ... done
Stopping orderer.example.com ... done
Removing cli ... done
Removing peer0.org1.example.com ... done
Removing peer0.org2.example.com ... done
Removing orderer.example.com ... done
Removing network fabric_test
Removing volume docker_orderer.example.com
Removing volume docker_peer0.org1.example.com
Removing volume docker_peer0.org2.example.com
Removing network fabric_test
WARNING: Network fabric_test not found.
Removing volume docker_peer0.org3.example.com
WARNING: Volume docker_peer0.org3.example.com not found.
No containers available for deletion
No images available for deletion
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
e685c5c858e3: Pull complete
Digest: sha256:e7157b6d7ebbe2cce5eaa8cfe8aa4fa82d173999b9f90a9ec42e57323546c353
Status: Downloaded newer image for busybox:latest
将fabric-samples分支切换到指定版本,重新执行up操作
➜ test-network git:(ad8fc2f) ./network.sh up createChannel
Creating channel 'mychannel'.
If network is not up, starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb with crypto from 'cryptogen'
Bringing up network
LOCAL_VERSION=2.2.4
DOCKER_IMAGE_VERSION=2.2.4
/Users/xxx/workspace/hyfa/fabric-samples/test-network/../bin/cryptogen
Generating certificates using cryptogen tool
Creating Org1 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
org1.example.com
+ res=0
Creating Org2 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output=organizations
org2.example.com
+ res=0
Creating Orderer Org Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output=organizations
+ res=0
Generating CCP files for Org1 and Org2
/Users/xxx/workspace/hyfa/fabric-samples/test-network/../bin/configtxgen
Generating Orderer Genesis block
+ configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block
2021-11-22 11:30:32.362 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-11-22 11:30:32.382 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: etcdraft
2021-11-22 11:30:32.382 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 Orderer.EtcdRaft.Options unset, setting to tick_interval:"500ms" election_tick:10 heartbeat_tick:1 max_inflight_blocks:5 snapshot_interval_size:16777216
2021-11-22 11:30:32.382 CST [common.tools.configtxgen.localconfig] Load -> INFO 004 Loaded configuration: /Users/xxx/workspace/hyfa/fabric-samples/test-network/configtx/configtx.yaml
2021-11-22 11:30:32.384 CST [common.tools.configtxgen] doOutputBlock -> INFO 005 Generating genesis block
2021-11-22 11:30:32.385 CST [common.tools.configtxgen] doOutputBlock -> INFO 006 Writing genesis block
+ res=0
Creating network "fabric_test" with the default driver
Creating volume "docker_orderer.example.com" with default driver
Creating volume "docker_peer0.org1.example.com" with default driver
Creating volume "docker_peer0.org2.example.com" with default driver
Creating peer0.org1.example.com ... done
Creating orderer.example.com ... done
Creating peer0.org2.example.com ... done
Creating cli ... done
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f5b38a37b3c hyperledger/fabric-tools:latest "/bin/bash" 2 seconds ago Up Less than a second cli
ce9abda63afb hyperledger/fabric-peer:latest "peer node start" 13 seconds ago Up 2 seconds 0.0.0.0:9051->9051/tcp, :::9051->9051/tcp, 7051/tcp, 0.0.0.0:19051->19051/tcp, :::19051->19051/tcp peer0.org2.example.com
083818ba1bbf hyperledger/fabric-orderer:latest "orderer" 13 seconds ago Up 3 seconds 0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:17050->17050/tcp, :::17050->17050/tcp orderer.example.com
9a03ab178c35 hyperledger/fabric-peer:latest "peer node start" 13 seconds ago Up 5 seconds 0.0.0.0:7051->7051/tcp, :::7051->7051/tcp, 0.0.0.0:17051->17051/tcp, :::17051->17051/tcp peer0.org1.example.com
c2d41f77ba29 kong:latest "/docker-entrypoint.…" 3 days ago Exited (255) 2 hours ago 0.0.0.0:5555->5555/tcp, :::5555->5555/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:8002->8002/tcp, :::8002->8002/tcp, 127.0.0.1:8001->8001/tcp, 0.0.0.0:8443->8443/tcp, :::8443->8443/tcp, 127.0.0.1:8444->8444/tcp kong
dc9708005ac9 postgres:9.6 "docker-entrypoint.s…" 3 days ago Exited (255) 2 hours ago 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp kong-database
746673ca35ef kong-ee "/docker-entrypoint.…" 3 days ago Exited (1) 3 days ago kong-ee
ed95aaac394e kicbase/stable:v0.0.27 "/usr/local/bin/entr…" 3 weeks ago Exited (255) 7 days ago 127.0.0.1:55004->22/tcp, 127.0.0.1:55003->2376/tcp, 127.0.0.1:55002->5000/tcp, 127.0.0.1:55001->8443/tcp, 127.0.0.1:55000->32443/tcp minikube
6294196025b7 redis "docker-entrypoint.s…" 5 weeks ago Exited (255) 7 days ago 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp some-redis
322507528a23 postgres "docker-entrypoint.s…" 5 weeks ago Exited (255) 7 days ago 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp mypostgresql
Generating channel create transaction 'mychannel.tx'
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
2021-11-22 11:30:50.043 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-11-22 11:30:50.058 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /Users/xxx/workspace/hyfa/fabric-samples/test-network/configtx/configtx.yaml
2021-11-22 11:30:50.058 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2021-11-22 11:30:50.061 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx
+ res=0
Creating channel mychannel
Using organization 1
+ peer channel create -o localhost:7050 -c mychannel --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /Users/zhaojunwei/workspace/hyfa/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=0
2021-11-22 11:30:53.152 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 11:30:53.196 CST [cli.common] readBlock -> INFO 002 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:53.201 CST [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2021-11-22 11:30:53.405 CST [cli.common] readBlock -> INFO 004 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:53.412 CST [channelCmd] InitCmdFactory -> INFO 005 Endorser and orderer connections initialized
2021-11-22 11:30:53.621 CST [cli.common] readBlock -> INFO 006 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:53.628 CST [channelCmd] InitCmdFactory -> INFO 007 Endorser and orderer connections initialized
2021-11-22 11:30:53.831 CST [cli.common] readBlock -> INFO 008 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:53.837 CST [channelCmd] InitCmdFactory -> INFO 009 Endorser and orderer connections initialized
2021-11-22 11:30:54.046 CST [cli.common] readBlock -> INFO 00a Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:54.052 CST [channelCmd] InitCmdFactory -> INFO 00b Endorser and orderer connections initialized
2021-11-22 11:30:54.264 CST [cli.common] readBlock -> INFO 00c Received block: 0
Channel 'mychannel' created
Joining org1 peer to the channel...
Using organization 1
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2021-11-22 11:30:57.334 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 11:30:57.365 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
Joining org2 peer to the channel...
Using organization 2
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2021-11-22 11:31:00.430 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 11:31:00.457 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
Setting anchor peer for org1...
Using organization 1
Fetching channel config for channel mychannel
Using organization 1
Fetching the most recent configuration block for the channel
+ peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-22 03:31:00.830 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:00.834 UTC [cli.common] readBlock -> INFO 002 Received block: 0
2021-11-22 03:31:00.834 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2021-11-22 03:31:00.837 UTC [cli.common] readBlock -> INFO 004 Received block: 0
Decoding config block to JSON and isolating config to Org1MSPconfig.json
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
+ jq '.channel_group.groups.Application.groups.Org1MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org1.example.com","port": 7051}]},"version": "0"}}' Org1MSPconfig.json
Generating anchor peer update transaction for Org1 on channel mychannel
+ configtxlator proto_encode --input Org1MSPconfig.json --type common.Config
+ configtxlator proto_encode --input Org1MSPmodified_config.json --type common.Config
+ configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb
+ configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate
+ jq .
++ cat config_update.json
+ echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org1.example.com",' '"port":' 7051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2021-11-22 03:31:01.035 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:01.055 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org1MSP' on channel 'mychannel'
Setting anchor peer for org2...
Using organization 2
Fetching channel config for channel mychannel
Using organization 2
Fetching the most recent configuration block for the channel
+ peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-22 03:31:01.408 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:01.411 UTC [cli.common] readBlock -> INFO 002 Received block: 1
2021-11-22 03:31:01.411 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 1
2021-11-22 03:31:01.415 UTC [cli.common] readBlock -> INFO 004 Received block: 1
Decoding config block to JSON and isolating config to Org2MSPconfig.json
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
Generating anchor peer update transaction for Org2 on channel mychannel
+ jq '.channel_group.groups.Application.groups.Org2MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org2.example.com","port": 9051}]},"version": "0"}}' Org2MSPconfig.json
+ configtxlator proto_encode --input Org2MSPconfig.json --type common.Config
+ configtxlator proto_encode --input Org2MSPmodified_config.json --type common.Config
+ configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb
+ configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate
+ jq .
++ cat config_update.json
+ echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org2.example.com",' '"port":' 9051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2021-11-22 03:31:01.609 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:01.627 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org2MSP' on channel 'mychannel'
Channel 'mychannel' joined
➜ test-network git:(ad8fc2f)
至此,你就可以部署智能合约了。以上就是搭建测试环境的具体流程,我们可以从日志输出中来学习一下大致的启动流程
1. cryptogen
在所有的工作开始之前,需要只要该工具生产证书,是一种用于生成Fabric key材料的实用程序。提供了一种预先配置网络以进行测试目的的手段。通常不会用于生产网络的操作。
在每个组织,order节点,Peer节点操作之前都需要进行产生证书的操作
Generating certificates using cryptogen tool
Creating Org1 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
org1.example.com
+ res=0
Creating Org2 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output=organizations
org2.example.com
+ res=0
Creating Orderer Org Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output=organizations
可以通过生产的文件来学习一下,cryptogen具体做了什么事情,首先,通过提供的配置文件,我们看看具体配置了什么,以组织为例
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
# ---------------------------------------------------------------------------
# Org1
# ---------------------------------------------------------------------------
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
# ---------------------------------------------------------------------------
# "Specs"
# ---------------------------------------------------------------------------
# Uncomment this section to enable the explicit definition of hosts in your
# configuration. Most users will want to use Template, below
#
# Specs is an array of Spec entries. Each Spec entry consists of two fields:
# - Hostname: (Required) The desired hostname, sans the domain.
# - CommonName: (Optional) Specifies the template or explicit override for
# the CN. By default, this is the template:
#
# "{{.Hostname}}.{{.Domain}}"
#
# which obtains its values from the Spec.Hostname and
# Org.Domain, respectively.
# ---------------------------------------------------------------------------
# - Hostname: foo # implicitly "foo.org1.example.com"
# CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above
# - Hostname: bar
# - Hostname: baz
# ---------------------------------------------------------------------------
# "Template"
# ---------------------------------------------------------------------------
# Allows for the definition of 1 or more hosts that are created sequentially
# from a template. By default, this looks like "peer%d" from 0 to Count-1.
# You may override the number of nodes (Count), the starting index (Start)
# or the template used to construct the name (Hostname).
#
# Note: Template and Specs are not mutually exclusive. You may define both
# sections and the aggregate nodes will be created for you. Take care with
# name collisions
# ---------------------------------------------------------------------------
Template:
Count: 1
SANS:
- localhost
# Start: 5
# Hostname: {{.Prefix}}{{.Index}} # default
# ---------------------------------------------------------------------------
# "Users"
# ---------------------------------------------------------------------------
# Count: The number of user accounts _in addition_ to Admin
# ---------------------------------------------------------------------------
Users:
Count: 1
命令执行输出在organizations目录下,我们一起看看到底生产了什么
➜ organizations git:(ad8fc2f) tree peerOrganizations
peerOrganizations
├── org1.example.com
│ ├── ca
│ │ ├── ca.org1.example.com-cert.pem
│ │ └── priv_sk
│ ├── connection-org1.json
│ ├── connection-org1.yaml
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ │ └── ca.org1.example.com-cert.pem
│ │ ├── config.yaml
│ │ └── tlscacerts
│ │ └── tlsca.org1.example.com-cert.pem
│ ├── peers
│ │ └── peer0.org1.example.com
│ │ ├── msp
│ │ │ ├── admincerts
│ │ │ ├── cacerts
│ │ │ │ └── ca.org1.example.com-cert.pem
│ │ │ ├── config.yaml
│ │ │ ├── keystore
│ │ │ │ └── priv_sk
│ │ │ ├── signcerts
│ │ │ │ └── peer0.org1.example.com-cert.pem
│ │ │ └── tlscacerts
│ │ │ └── tlsca.org1.example.com-cert.pem
│ │ └── tls
│ │ ├── ca.crt
│ │ ├── server.crt
│ │ └── server.key
│ ├── tlsca
│ │ ├── priv_sk
│ │ └── tlsca.org1.example.com-cert.pem
│ └── users
│ ├── Admin@org1.example.com
│ │ ├── msp
│ │ │ ├── admincerts
│ │ │ ├── cacerts
│ │ │ │ └── ca.org1.example.com-cert.pem
│ │ │ ├── config.yaml
│ │ │ ├── keystore
│ │ │ │ └── priv_sk
│ │ │ ├── signcerts
│ │ │ │ └── Admin@org1.example.com-cert.pem
│ │ │ └── tlscacerts
│ │ │ └── tlsca.org1.example.com-cert.pem
│ │ └── tls
│ │ ├── ca.crt
│ │ ├── client.crt
│ │ └── client.key
│ └── User1@org1.example.com
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ │ └── ca.org1.example.com-cert.pem
│ │ ├── config.yaml
│ │ ├── keystore
│ │ │ └── priv_sk
│ │ ├── signcerts
│ │ │ └── User1@org1.example.com-cert.pem
│ │ └── tlscacerts
│ │ └── tlsca.org1.example.com-cert.pem
│ └── tls
│ ├── ca.crt
│ ├── client.crt
│ └── client.key
└── org2.example.com
├── ca
│ ├── ca.org2.example.com-cert.pem
│ └── priv_sk
├── connection-org2.json
├── connection-org2.yaml
├── msp
│ ├── admincerts
│ ├── cacerts
│ │ └── ca.org2.example.com-cert.pem
│ ├── config.yaml
│ └── tlscacerts
│ └── tlsca.org2.example.com-cert.pem
├── peers
│ └── peer0.org2.example.com
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ │ └── ca.org2.example.com-cert.pem
│ │ ├── config.yaml
│ │ ├── keystore
│ │ │ └── priv_sk
│ │ ├── signcerts
│ │ │ └── peer0.org2.example.com-cert.pem
│ │ └── tlscacerts
│ │ └── tlsca.org2.example.com-cert.pem
│ └── tls
│ ├── ca.crt
│ ├── server.crt
│ └── server.key
├── tlsca
│ ├── priv_sk
│ └── tlsca.org2.example.com-cert.pem
└── users
├── Admin@org2.example.com
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ │ └── ca.org2.example.com-cert.pem
│ │ ├── config.yaml
│ │ ├── keystore
│ │ │ └── priv_sk
│ │ ├── signcerts
│ │ │ └── Admin@org2.example.com-cert.pem
│ │ └── tlscacerts
│ │ └── tlsca.org2.example.com-cert.pem
│ └── tls
│ ├── ca.crt
│ ├── client.crt
│ └── client.key
└── User1@org2.example.com
├── msp
│ ├── admincerts
│ ├── cacerts
│ │ └── ca.org2.example.com-cert.pem
│ ├── config.yaml
│ ├── keystore
│ │ └── priv_sk
│ ├── signcerts
│ │ └── User1@org2.example.com-cert.pem
│ └── tlscacerts
│ └── tlsca.org2.example.com-cert.pem
└── tls
├── ca.crt
├── client.crt
└── client.key
\
66 directories, 66 files
仅仅看org1,测试网络使用Fabric CA客户端使用每个组织的CA注册节点和用户身份。然后,这脚本使用enroll命令为每个标识生成msp文件夹。 MSP文件目录包含每个标识的证书和私钥,并建立标识身份和组织关系。
2. configtxgen
接下来通过configtxgen命令允许用户创建和检查频道配置相关工件。
Generating CCP files for Org1 and Org2
/Users/xxx/workspace/hyfa/fabric-samples/test-network/../bin/configtxgen
Generating Orderer Genesis block
+ configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block
该命令提供的参数有,profile,配置信息的来源,在configtx.yaml的profile部分, channelID用于设置通道的名称,在创建系统通道时,不要改该配置项,outputBlock配置创世区块的输出地址,最后输出一个创世区块
之后就是创建网络,创建卷,启动容器,
3. createChannel
如果你在network.sh up时,增加了启动通道的子命令createChannel,就像我上面操作的那样,那么接下来就开始创建通道先关的内容了
Generating channel create transaction 'mychannel.tx'
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
2021-11-22 11:30:50.043 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-11-22 11:30:50.058 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /Users/xxx/workspace/hyfa/fabric-samples/test-network/configtx/configtx.yaml
2021-11-22 11:30:50.058 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2021-11-22 11:30:50.061 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx
+ res=0
Creating channel mychannel
Using organization 1
+ peer channel create -o localhost:7050 -c mychannel --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /Users/xxx/workspace/hyfa/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=0
2021-11-22 11:30:53.152 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 11:30:53.196 CST [cli.common] readBlock -> INFO 002 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:53.201 CST [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2021-11-22 11:30:53.405 CST [cli.common] readBlock -> INFO 004 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:53.412 CST [channelCmd] InitCmdFactory -> INFO 005 Endorser and orderer connections initialized
2021-11-22 11:30:53.621 CST [cli.common] readBlock -> INFO 006 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:53.628 CST [channelCmd] InitCmdFactory -> INFO 007 Endorser and orderer connections initialized
2021-11-22 11:30:53.831 CST [cli.common] readBlock -> INFO 008 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:53.837 CST [channelCmd] InitCmdFactory -> INFO 009 Endorser and orderer connections initialized
2021-11-22 11:30:54.046 CST [cli.common] readBlock -> INFO 00a Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-22 11:30:54.052 CST [channelCmd] InitCmdFactory -> INFO 00b Endorser and orderer connections initialized
2021-11-22 11:30:54.264 CST [cli.common] readBlock -> INFO 00c Received block: 0
Channel 'mychannel' created
Joining org1 peer to the channel...
Using organization 1
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2021-11-22 11:30:57.334 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 11:30:57.365 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
Joining org2 peer to the channel...
Using organization 2
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2021-11-22 11:31:00.430 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 11:31:00.457 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
Setting anchor peer for org1...
Using organization 1
Fetching channel config for channel mychannel
Using organization 1
Fetching the most recent configuration block for the channel
+ peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-22 03:31:00.830 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:00.834 UTC [cli.common] readBlock -> INFO 002 Received block: 0
2021-11-22 03:31:00.834 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2021-11-22 03:31:00.837 UTC [cli.common] readBlock -> INFO 004 Received block: 0
Decoding config block to JSON and isolating config to Org1MSPconfig.json
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
+ jq '.channel_group.groups.Application.groups.Org1MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org1.example.com","port": 7051}]},"version": "0"}}' Org1MSPconfig.json
Generating anchor peer update transaction for Org1 on channel mychannel
+ configtxlator proto_encode --input Org1MSPconfig.json --type common.Config
+ configtxlator proto_encode --input Org1MSPmodified_config.json --type common.Config
+ configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb
+ configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate
+ jq .
++ cat config_update.json
+ echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org1.example.com",' '"port":' 7051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2021-11-22 03:31:01.035 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:01.055 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org1MSP' on channel 'mychannel'
Setting anchor peer for org2...
Using organization 2
Fetching channel config for channel mychannel
Using organization 2
Fetching the most recent configuration block for the channel
+ peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-22 03:31:01.408 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:01.411 UTC [cli.common] readBlock -> INFO 002 Received block: 1
2021-11-22 03:31:01.411 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 1
2021-11-22 03:31:01.415 UTC [cli.common] readBlock -> INFO 004 Received block: 1
Decoding config block to JSON and isolating config to Org2MSPconfig.json
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
Generating anchor peer update transaction for Org2 on channel mychannel
+ jq '.channel_group.groups.Application.groups.Org2MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org2.example.com","port": 9051}]},"version": "0"}}' Org2MSPconfig.json
+ configtxlator proto_encode --input Org2MSPconfig.json --type common.Config
+ configtxlator proto_encode --input Org2MSPmodified_config.json --type common.Config
+ configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb
+ configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate
+ jq .
++ cat config_update.json
+ echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org2.example.com",' '"port":' 9051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2021-11-22 03:31:01.609 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:01.627 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org2MSP' on channel 'mychannel'
Channel 'mychannel' joined
➜ test-network git:(ad8fc2f)
这里有几点非常重要,我大致说一下
- 在创建通道前,需要创建通道交易的提案
createChannelTx() {
set -x
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/${CHANNEL_NAME}.tx -channelID $CHANNEL_NAME
res=$?
{ set +x; } 2>/dev/null
verifyResult $res "Failed to generate channel configuration transaction..."
}
该命令从configtx.yaml配置的Profile部分读取TwoOrgsChannel内容,然后讲创建的channeltx输出到./channel-artifacts/${CHANNEL_NAME}.tx里面,channelID来指定通道名,这个可以自己定义
生成的channel_name.tx内容,由于有不可读字符,所以就不展示了。
该步骤执行成功后,才会进行下一步操作
- 创建通道
这里有一个非常重要的点,根据下面的日志可以看到,在执行peer channel create的时候,需要首先切换到组织,然后才能执行创建通道的命令,这也就说明了,如果我们在没有创建组织的时候,是不能创建通道的。
Creating channel mychannel
Using organization 1
+ peer channel create -o localhost:7050 -c mychannel --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /Users/xxx/workspace/hyfa/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
通道创建成功后,会生产一个通道区块。
- 加入通道
这里在进行peer channel join 操作之前,也是需要执行切换组织的操作, 要把哪个组织加入通道就切换到哪个组织,
Joining org1 peer to the channel...
Using organization 1
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2021-11-22 11:30:57.334 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 11:30:57.365 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
插入一段,关于上面所说,如何切换组织,其实是个比较繁琐的过程,这里官方有个脚本
# Set environment variables for the peer org
setGlobals() {
local USING_ORG=""
if [ -z "$OVERRIDE_ORG" ]; then
USING_ORG=$1
else
USING_ORG="${OVERRIDE_ORG}"
fi
infoln "Using organization ${USING_ORG}"
if [ $USING_ORG -eq 1 ]; then
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
elif [ $USING_ORG -eq 2 ]; then
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
elif [ $USING_ORG -eq 3 ]; then
export CORE_PEER_LOCALMSPID="Org3MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG3_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
export CORE_PEER_ADDRESS=localhost:11051
else
errorln "ORG Unknown"
fi
if [ "$VERBOSE" == "true" ]; then
env | grep CORE
fi
}
- 设置锚节点
在组织加入到通道后,每个组织需要提供一个组织内的节点,作为对外通信的锚节点,具体过程如下
Setting anchor peer for org1...
Using organization 1
Fetching channel config for channel mychannel
Using organization 1
Fetching the most recent configuration block for the channel
+ peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-22 03:31:00.830 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:00.834 UTC [cli.common] readBlock -> INFO 002 Received block: 0
2021-11-22 03:31:00.834 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2021-11-22 03:31:00.837 UTC [cli.common] readBlock -> INFO 004 Received block: 0
Decoding config block to JSON and isolating config to Org1MSPconfig.json
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
+ jq '.channel_group.groups.Application.groups.Org1MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org1.example.com","port": 7051}]},"version": "0"}}' Org1MSPconfig.json
Generating anchor peer update transaction for Org1 on channel mychannel
+ configtxlator proto_encode --input Org1MSPconfig.json --type common.Config
+ configtxlator proto_encode --input Org1MSPmodified_config.json --type common.Config
+ configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb
+ configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate
+ jq .
++ cat config_update.json
+ echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org1.example.com",' '"port":' 7051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2021-11-22 03:31:01.035 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-22 03:31:01.055 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org1MSP' on channel 'mychannel'