[toc]
環(huán)境
GoSDK安裝
下載 GO SDK
wget https://golang.google.cn/dl/go1.17.3.linux-amd64.tar.gz
tar xfv go1.14.4.linux-amd64.tar.gz -C /usr/local
配置環(huán)境變量
在文件最后添加以下內(nèi)容
vim /etc/profile
export PATH=$PATH:/usr/local/go/bin
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
export GOPROXY="https://goproxy.cn,direct"
export GO111MODULE="auto"
source /etc/profile
查看go-SDK 是否安裝成功
go version
安裝 docker
安裝Docker-CE
卸載舊版本docker
sudo apt-get remove docker docker-engine docker.io
添加HTTPS協(xié)議晨汹,允許apt從HTTPS安裝軟件包
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
安裝GPG證書(shū)
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
寫(xiě)入軟件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
更新并安裝Docker-CE
sudo apt-get -y update && sudo apt-get -y install docker-ce
docker version
將當(dāng)前用戶添加到Docker用戶組
創(chuàng)建docker用戶組
sudo groupadd docker
將當(dāng)前用戶添加到docker用戶組
sudo usermod -aG docker $USER
配置鏡像加速器
針對(duì)Docker客戶端版本大于 1.10.0 的用戶
您可以通過(guò)修改daemon配置文件/etc/docker/daemon.json來(lái)使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://x9u1rybt.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
查看docker版本昧旨,看是否安裝成功
docker version
- 執(zhí)行docker info拗小,如果結(jié)果中含有如下內(nèi)容則說(shuō)明鏡像配置成功
...
Registry Mirrors:
https://obou6wyb.mirror.aliyuncs.com/
https://registry.docker-cn.com/
http://hub-mirror.c.163.com/
Live Restore Enabled: false
...
安裝Docker-Compose
- 查看最新版本版本
https://github.com/docker/compose/releases
sudo curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
或
sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
-下載完后要設(shè)置權(quán)限
sudo chmod +x /usr/local/bin/docker-compose
- 檢查
docker-compose version
fabric源碼
下載源碼
git clone https://gitee.com/mirrors/hyperledger-fabric.git fabric
cd fabric
- 切換到v2.2.0版本
git checkout v2.2.0
下載二進(jìn)制文件(已經(jīng)準(zhǔn)備好)
wget https://github.com/hyperledger/fabric/releases/download/v2.2.0/hyperledger-fabric-linux-amd64-2.2.0.tar.gz
- 解壓
tar -vxzf hyperledger-fabric-linux-amd64-2.2.0.tar.gz -C ./go/
- 檢查
peer version
下載 fabric-sample 源碼
git clone https://gitee.com/Alikx/fabric-samples.git
- 進(jìn)入項(xiàng)目
cd $GOPATH/src/github.com/hyperledger/fabric-samples/test-network
- 切換版本
git checkout v2.2.0
- 移動(dòng)配置文件,先進(jìn)
gopath
的 bin目錄下,之前解二進(jìn)制文件連同配置文件都在這里.
mv config ~/go/src/github.com/hyperledger/fabric-samples
啟動(dòng)網(wǎng)絡(luò)
- 進(jìn)入測(cè)試網(wǎng)絡(luò)
cd $GOPATH/src/github.com/hyperledger/fabric-samples/test-network
- 修改測(cè)試腳本
vim ./network.sh
大概在51行,注釋掉二進(jìn)制文件檢查的那一項(xiàng)
function checkPrereqs() {
## Check if your have cloned the peer binaries and configuration files.
peer version > /dev/null 2>&1
# 注釋下面的部分
# if [[ $? -ne 0 || ! -d "../config" ]]; then
# errorln "Peer binary and configuration files not found.."
# errorln
# errorln "Follow the instructions in the Fabric docs to install the Fabric Binaries:"
# errorln "https://hyperledger-fabric.readthedocs.io/en/latest/install.html"
# exit 1
# fi
# 注釋上面的部分
# use the fabric tools container to see if the samples and binaries match your
# docker images
執(zhí)行腳本
export COMPOSE_PROJECT_NAME=fabric
export IMAGE_TAG=2.2
./network.sh up createChannel
啟動(dòng)日志
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.0
DOCKER_IMAGE_VERSION=2.2.0
/root/go/bin/cryptogen
Generating certificates using cryptogen tool
Creating Org1 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
org1.example.com # 新增peer參考配置文件
+ 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
/root/go/bin/configtxgen
Generating Orderer Genesis block
+ configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block
2021-11-23 03:19:32.312 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-11-23 03:19:32.340 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: etcdraft
2021-11-23 03:19:32.340 UTC [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-23 03:19:32.340 UTC [common.tools.configtxgen.localconfig] Load -> INFO 004 Loaded configuration: /root/go/src/github.com/hyperledger/fabric-samples/test-network/configtx/configtx.yaml
2021-11-23 03:19:32.342 UTC [common.tools.configtxgen] doOutputBlock -> INFO 005 Generating genesis block
2021-11-23 03:19:32.343 UTC [common.tools.configtxgen] doOutputBlock -> INFO 006 Writing genesis block
+ res=0
Creating network "fabric_test" with the default driver
Creating volume "fabric_orderer.example.com" with default driver
Creating volume "fabric_peer0.org1.example.com" with default driver
Creating volume "fabric_peer0.org2.example.com" with default driver
Creating orderer.example.com ... done
Creating peer0.org1.example.com ... done
Creating peer0.org2.example.com ... done
Creating cli ... done
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f19399557a69 hyperledger/fabric-tools:latest "/bin/bash" 2 seconds ago Up Less than a second cli
263f14b81a51 hyperledger/fabric-peer:latest "peer node start" 5 seconds ago Up 2 seconds 7051/tcp, 0.0.0.0:9051->9051/tcp, :::9051->9051/tcp peer0.org2.example.com
5513a783cb6a hyperledger/fabric-peer:latest "peer node start" 5 seconds ago Up 3 seconds 0.0.0.0:7051->7051/tcp, :::7051->7051/tcp peer0.org1.example.com
1eca52dd33b4 hyperledger/fabric-orderer:latest "orderer" 5 seconds ago Up 1 second 0.0.0.0:7050->7050/tcp, :::7050->7050/tcp orderer.example.com
Generating channel create transaction 'mychannel.tx'
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
2021-11-23 03:19:38.507 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-11-23 03:19:38.558 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /root/go/src/github.com/hyperledger/fabric-samples/test-network/configtx/configtx.yaml
2021-11-23 03:19:38.558 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2021-11-23 03:19:38.570 UTC [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 /root/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=0
2021-11-23 03:19:41.846 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:19:41.970 UTC [cli.common] readBlock -> INFO 002 Expect block, but got status: &{NOT_FOUND}
2021-11-23 03:19:41.998 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2021-11-23 03:19:42.203 UTC [cli.common] readBlock -> INFO 004 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-23 03:19:42.210 UTC [channelCmd] InitCmdFactory -> INFO 005 Endorser and orderer connections initialized
2021-11-23 03:19:42.415 UTC [cli.common] readBlock -> INFO 006 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-23 03:19:42.425 UTC [channelCmd] InitCmdFactory -> INFO 007 Endorser and orderer connections initialized
2021-11-23 03:19:42.628 UTC [cli.common] readBlock -> INFO 008 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-23 03:19:42.634 UTC [channelCmd] InitCmdFactory -> INFO 009 Endorser and orderer connections initialized
2021-11-23 03:19:42.838 UTC [cli.common] readBlock -> INFO 00a Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-23 03:19:42.843 UTC [channelCmd] InitCmdFactory -> INFO 00b Endorser and orderer connections initialized
2021-11-23 03:19:43.072 UTC [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-23 03:19:46.169 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:19:46.283 UTC [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-23 03:19:49.373 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:19:49.607 UTC [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-23 03:19:49.852 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:19:49.855 UTC [cli.common] readBlock -> INFO 002 Received block: 0
2021-11-23 03:19:49.855 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2021-11-23 03:19:49.857 UTC [cli.common] readBlock -> INFO 004 Received block: 0
Decoding config block to JSON and isolating config to Org1MSPconfig.json
+ configtxlator proto_decode + jq '.data.data[0].payload.data.config'
--input config_block.pb --type common.Block
Generating anchor peer update transaction for Org1 on channel mychannel
+ 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
+ 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
+ ++ cat config_update.json
jq .
+ 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-23 03:19:50.269 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:19:50.293 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-23 03:19:50.577 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:19:50.581 UTC [cli.common] readBlock -> INFO 002 Received block: 1
2021-11-23 03:19:50.581 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 1
2021-11-23 03:19:50.583 UTC [cli.common] readBlock -> INFO 004 Received block: 1
Decoding config block to JSON and isolating config to Org2MSPconfig.json
+ configtxlator proto_decode --input + jq '.data.data[0].payload.data.config'
config_block.pb --type common.Block
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
+ ++ cat config_update.json
jq .
+ 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-23 03:19:50.927 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:19:50.950 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org2MSP' on channel 'mychannel'
Channel 'mychannel' joined
- 檢查
docker ps --format "table {{.ID}}\t{{.Names}}"
輸出一下內(nèi)容,包含三個(gè)節(jié)點(diǎn):
CONTAINER ID NAMES
e3c7b448125d cli
dfdc10df3d98 peer0.org1.example.com
5c5a432150fe orderer.example.com
36ad49aa080c peer0.org2.example.com
清理網(wǎng)絡(luò)
- 如果使用了日志監(jiān)控
docker stop logspout && docker rm logspout && ./network.sh down
- 沒(méi)有使用日監(jiān)控
./network.sh down
日志監(jiān)控
此步驟不是必需的腻窒,但對(duì)鏈碼進(jìn)行故障診斷非常有用芽世。要監(jiān)控智能合同的日志服赎,管理員可以使用logspout
工具查看一組Docker容器的聚合輸出驻右。該工具將來(lái)自不同Docker容器的輸出流收集到一個(gè)地方闪唆,以便于從單個(gè)窗口查看正在發(fā)生的事情。這可以幫助管理員在安裝智能合同時(shí)調(diào)試問(wèn)題,幫助開(kāi)發(fā)人員在調(diào)用智能合同時(shí)調(diào)試問(wèn)題巧勤。由于一些容器的創(chuàng)建純粹是為了啟動(dòng)智能合同嵌灰,并且只存在很短的時(shí)間,因此從您的網(wǎng)絡(luò)收集所有日志是有幫助的颅悉。
A script to install and configure Logspout, monitordocker.sh
, is already included in the commercial-paper
sample in the Fabric samples. We will use the same script in this tutorial as well. The Logspout tool will continuously stream logs to your terminal, so you will need to use a new terminal window. Open a new terminal and navigate to the test-network
directory.
cd fabric-samples/test-network
You can run the monitordocker.sh
script from any directory. For ease of use, we will copy the monitordocker.sh
script from the commercial-paper
sample to your working directory
cp ../commercial-paper/organization/digibank/configuration/cli/monitordocker.sh .
# if you're not sure where it is
find . -name monitordocker.sh
然后沽瞭,您可以通過(guò)運(yùn)行以下命令啟動(dòng)Logspout:
./monitordocker.sh fabric_test
您應(yīng)該會(huì)看到類似于以下內(nèi)容的輸出:
Starting monitoring on all containers on the network docker_test
f96a6fae3c8cadcb8f3b5ac0f4fb808b45d1d30cc26498451974bd6a1b16a4b7
您一開(kāi)始不會(huì)看到任何日志,但當(dāng)我們部署鏈碼時(shí)剩瓶,這種情況會(huì)發(fā)生變化驹溃。使這個(gè)終端窗口寬,字體小可能會(huì)有幫助延曙。
如果找不到網(wǎng)絡(luò),就使用個(gè)下面命令查看下網(wǎng)絡(luò),實(shí)際上網(wǎng)絡(luò)名字就是上面修改過(guò)的名字.
docker network ls
清理
使用完鏈碼后豌鹤,您也可以使用以下命令刪除Logspout工具。
docker stop logspout && docker rm logspout && ./network.sh down
然后枝缔,您可以通過(guò)從測(cè)試網(wǎng)絡(luò)目錄發(fā)出以下命令來(lái)關(guān)閉test-network
:
./network.sh down
安裝鏈碼
打包鏈碼
- 進(jìn)去go語(yǔ)言鏈碼包
cd fabric-samples/chaincode/fabcar/go
- 下載依賴
GO111MODULE=on
go mod vendor
- 回到工作目錄
cd ../../../test-network
- 設(shè)置管理員1 的環(huán)境的變量
export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
- 管理員1和管理員2 (一個(gè)打包另一個(gè)直接拿來(lái)用就好了)打包鏈碼
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/go/ --lang golang --label fabcar_1
執(zhí)行完該命令會(huì)在當(dāng)前目錄下生成 鏈碼包文件 fabcar.tar.gz
.
安裝鏈碼
在Org1 的peer 上安裝鏈碼
peer lifecycle chaincode install fabcar.tar.gz
2021-11-23 03:32:34.978 UTC [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506\022\010fabcar_1" >
2021-11-23 03:32:34.978 UTC [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
- 查詢已安裝的鏈碼
peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506, Label: fabcar_1
在Org2的 peer 上安裝鏈碼
設(shè)置以下環(huán)境變量作為Org2管理員操作布疙,并瞄準(zhǔn)Org2對(duì)等機(jī)peer0.org2.example.com
。
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
發(fā)出以下命令來(lái)安裝鏈碼:
peer lifecycle chaincode install fabcar.tar.gz
2021-11-23 03:33:56.305 UTC [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506\022\010fabcar_1" >
2021-11-23 03:33:56.305 UTC [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
- 查詢已安裝的鏈碼
peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506, Label: fabcar_1
批準(zhǔn)鏈碼
- 設(shè)置環(huán)境變量
export CC_PACKAGE_ID=fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
- 批準(zhǔn)
peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 日志
2021-11-23 03:37:54.483 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [377e45a0d4663c9afe9857656d31208bd70e9980373cc1a79256de0af7850311] committed with status (VALID) at
- 設(shè)置環(huán)境變量為組織以的管理員
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
- 批準(zhǔn)
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 日志
2021-11-23 03:38:51.638 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [6eddec6e2aaced7aac59d7f8f5b3718104f62be4560d49466f9e120390c85292] committed with status (VALID) at
提交鏈碼
- 檢查批準(zhǔn)情況
peer lifecycle chaincode checkcommitreadiness \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--output json
- 日志
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
- 提交
peer lifecycle chaincode commit \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--peerAddresses localhost:7051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
--peerAddresses localhost:9051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
- 日志
2021-11-23 03:41:47.755 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [1f08b845f0462c415d70799360cc9e72c41e9e768a26a5eef240ed14cd061d0e] committed with status (VALID) at localhost:9051
2021-11-23 03:41:47.806 UTC [chaincodeCmd] ClientWait -> INFO 002 txid [1f08b845f0462c415d70799360cc9e72c41e9e768a26a5eef240ed14cd061d0e] committed with status (VALID) at localhost:7051
- 查詢已提交
peer lifecycle chaincode querycommitted \
--channelID mychannel \
--name fabcar \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 日志
Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
調(diào)用鏈碼
peer chaincode invoke -o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--tls \
--cafile \
${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
-C mychannel \
-n fabcar \
--peerAddresses localhost:7051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
--peerAddresses localhost:9051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
-c '{"function":"initLedger","Args":[]}'
- 日志
2021-11-23 03:43:29.125 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
- 查詢
peer chaincode query \
-C mychannel \
-n fabcar \
-c '{"Args":["queryAllCars"]}'
- 日志
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
升級(jí)鏈碼
創(chuàng)建通道
生成通道交易文件
configtxgen \
-profile TwoOrgsChannel \
-outputCreateChannelTx ./channel-artifacts/channel1.tx \
-channelID channel1 \
-configPath ./configtx/
- 日志
2021-11-23 03:48:12.027 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-11-23 03:48:12.049 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /root/go/src/github.com/hyperledger/fabric-samples/test-network/configtx/configtx.yaml
2021-11-23 03:48:12.049 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2021-11-23 03:48:12.051 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx
創(chuàng)建通道區(qū)塊
peer channel create \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c channel1 \
-f ./channel-artifacts/channel1.tx \
--outputBlock ./channel-artifacts/channel1.block \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 日志
2021-11-23 03:48:52.616 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:48:52.727 UTC [cli.common] readBlock -> INFO 002 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-23 03:48:52.734 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2021-11-23 03:48:52.942 UTC [cli.common] readBlock -> INFO 004 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-23 03:48:52.948 UTC [channelCmd] InitCmdFactory -> INFO 005 Endorser and orderer connections initialized
2021-11-23 03:48:53.159 UTC [cli.common] readBlock -> INFO 006 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-23 03:48:53.163 UTC [channelCmd] InitCmdFactory -> INFO 007 Endorser and orderer connections initialized
2021-11-23 03:48:53.367 UTC [cli.common] readBlock -> INFO 008 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-23 03:48:53.372 UTC [channelCmd] InitCmdFactory -> INFO 009 Endorser and orderer connections initialized
2021-11-23 03:48:53.577 UTC [cli.common] readBlock -> INFO 00a Expect block, but got status: &{SERVICE_UNAVAILABLE}
2021-11-23 03:48:53.583 UTC [channelCmd] InitCmdFactory -> INFO 00b Endorser and orderer connections initialized
2021-11-23 03:48:53.789 UTC [cli.common] readBlock -> INFO 00c Received block: 0
加入通道
組織1 的peer加入通道
由于我們已經(jīng)以O(shè)rg1管理員的身份使用peer
CLI愿卸,因此讓我們將Org1的Peer加入到通道中灵临。由于Org1提交了通道創(chuàng)建交易,因此我們的文件系統(tǒng)上已經(jīng)有了通道創(chuàng)世塊趴荸。使用以下命令將Org1的Peer加入通道儒溉。
peer channel join -b ./channel-artifacts/channel1.block
環(huán)境變量CORE_PEER_ADDRESS
已設(shè)置為以peer0.org1.example.com
為目標(biāo)。命令執(zhí)行成功后將生成peer0.org1.example.com
加入通道的響應(yīng):
2021-11-23 03:50:44.103 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:50:44.234 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
- 查詢已加入的通道
peer channel list
- 日志
2021-11-23 03:51:13.257 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
channel1
mychannel
組織2 的peer加入通道
- 設(shè)置環(huán)境變量
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
- 列出當(dāng)前peer 加入的通道
peer channel list
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer channel list
2021-11-23 05:06:44.010 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
mychannel
- 從排序服務(wù)中獲取通道區(qū)塊數(shù)據(jù)
peer channel fetch 0 \
./channel-artifacts/channel_org2.block \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c channel1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-23 05:06:29.092 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 05:06:29.097 UTC [cli.common] readBlock -> INFO 002 Received block: 0
- 加入通道
peer channel join -b ./channel-artifacts/channel_org2.block
2021-11-23 05:11:20.912 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 05:11:21.071 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
- 查詢結(jié)果
peer channel list
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer channel list
2021-11-23 05:12:03.257 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
channel1
mychannel
向組織中新增peer
- 工作目錄 :
~/go/src/github.com/hyperledger/fabric-samples/test-network
- 組織:
org1
查看當(dāng)前組織中pee的個(gè)數(shù)
tree -L 5
│ └── peerOrganizations
│ ├── org1.example.com
│ │ ├── ca
│ │ │ ├── ca.org1.example.com-cert.pem
│ │ │ └── priv_sk
│ │ ├── connection-org1.json
│ │ ├── connection-org1.yaml
│ │ ├── msp
│ │ │ ├── admincerts
│ │ │ ├── cacerts
│ │ │ ├── config.yaml
│ │ │ └── tlscacerts
│ │ ├── peers
│ │ │ └── peer0.org1.example.com
│ │ ├── tlsca
│ │ │ ├── priv_sk
│ │ │ └── tlsca.org1.example.com-cert.pem
│ │ └── users
│ │ ├── Admin@org1.example.com
│ │ └── User1@org1.example.com
新增peer 證書(shū)文件
編輯證書(shū)配置文件
啟動(dòng)網(wǎng)絡(luò)的步驟中,查看輸出日志
Creating Org1 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
修愛(ài)配置文件 ./organizations/cryptogen/crypto-config-org1.yaml
.
vim ./organizations/cryptogen/crypto-config-org1.yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# ---------------------------------------------------------------------------
# "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: 2 # 此處由1 改為 2
SANS:
- localhost
# Start: 5
# Hostname: {{.Prefix}}{{.Index}} # default
# ---------------------------------------------------------------------------
# "Users"
# ---------------------------------------------------------------------------
# Count: The number of user accounts _in addition_ to Admin
# ---------------------------------------------------------------------------
Users:
Count: 1
- 執(zhí)行網(wǎng)絡(luò)拓展命令
cryptogen extend --config=./organizations/cryptogen/crypto-config-org1.yaml --input=organizations
- 再次查看目錄結(jié)構(gòu)
ls organizations/peerOrganizations/org1.example.com/peers
peer0.org1.example.com peer1.org1.example.com
啟動(dòng)新peer節(jié)點(diǎn)
查看當(dāng)前節(jié)點(diǎn)
docker ps --format "table {{.ID}} \t {{.Names}}"
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# docker ps --format "table {{.ID}} \t {{.Names}}"
CONTAINER ID NAMES
a6b9c523c562 dev-peer0.org2.example.com-fabcar_1-762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
a20f2648b557 dev-peer0.org1.example.com-fabcar_1-762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
f69bca3357cc logspout
f19399557a69 cli
263f14b81a51 peer0.org2.example.com
5513a783cb6a peer0.org1.example.com
1eca52dd33b4 orderer.example.com
新增 docker-compose 配置
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
networks:
fabric_test:
driver: bridge
external: true
services:
peer1.org1.example.com:
container_name: peer1.org1.example.com
tty: true
image: hyperledger/fabric-peer:$IMAGE_TAG
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_PEER_ID=peer1.org1.example.com
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_TLS_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
- CORE_CHAINCODE_LOGGING_LEVEL=INFO
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_ADDRESS=peer1.org1.example.com:7051
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_test
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: peer node start
ports:
- 8051:7051
- 8053:7053
volumes:
- /var/run/:/host/var/run/
- ./organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ./organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls
networks:
- fabric_test
啟動(dòng)節(jié)點(diǎn)
docker-compose -f docker-compose.yaml up -d peer1.org1.example.com
- 查看節(jié)點(diǎn)信息
docker ps --format "table {{.ID}}\t{{.Names}}" --filter name=org1
3cce207d4570 peer1.org1.example.com
5513a783cb6a peer0.org1.example.com
將新節(jié)點(diǎn)加入通道
- 配置環(huán)境變量
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:8051
peer channel fetch 0 \
./channel-artifacts/channel_org1_peer1.block \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 加入通道
mychannel
peer channel join -b ./channel-artifacts/channel_org1_peer1.block
2021-11-23 06:10:44.200 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 06:10:44.324 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
- 查看
peer channel list
2021-11-23 06:11:00.887 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
mychannel
安裝鏈碼
- 安裝鏈碼
peer lifecycle chaincode install fabcar.tar.gz
- 批準(zhǔn)鏈碼
peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 查詢
peer lifecycle chaincode checkcommitreadiness \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--output json
- 調(diào)用鏈碼
peer chaincode query \
-C mychannel \
-n fabcar \
-c '{"Args":["queryAllCars"]}'
參考日志
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer lifecycle chaincode approveformyorg \
> -o localhost:7050 \
> --ordererTLSHostnameOverride orderer.example.com \
> --channelID mychannel \
> --name fabcar \
> --version 1.0 \
> --package-id $CC_PACKAGE_ID \
> --sequence 2 \
> --tls \
> --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-23 07:26:01.492 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [b1d45658ff7f90866adda7ff81199386cd8dff7cd05819c48228c63eecf6b56a] committed with status (VALID) at
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ENABLED=true
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_LOCALMSPID="Org2MSP"
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_ADDRESS=localhost:9051
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer lifecycle chaincode approveformyorg \
> -o localhost:7050 \
> --ordererTLSHostnameOverride orderer.example.com \
> --channelID mychannel \
> --name fabcar \
> --version 1.0 \
> --package-id $CC_PACKAGE_ID \
> --sequence 2 \
> --tls \
> --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-23 07:26:33.901 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [078f3ee511dca0c29f0af021fdf154b3ca05a0ac62f2c7d05c8c77c804cb0f8a] committed with status (VALID) at
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer lifecycle chaincode checkcommitreadiness \
> --channelID mychannel \
> --name fabcar \
> --version 1.0 \
> --sequence 2 \
> --tls \
> --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
> --output json
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ENABLED=true
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_LOCALMSPID="Org1MSP"
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_ADDRESS=localhost:8051
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer chaincode query \
> -C mychannel \
> -n fabcar \
> -c '{"Args":["queryAllCars"]}'
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
向網(wǎng)絡(luò)中新增組織
為 Org3生成證書(shū)文件
在另一個(gè)終端中发钝,addOrg3
從 test-network
.
cd addOrg3
首先顿涣,我們將為 Org3 對(duì)等方以及應(yīng)用程序和管理員用戶創(chuàng)建證書(shū)和密鑰。因?yàn)槲覀冋诟乱粋€(gè)示例通道笼平,所以我們將使用 cryptogen 工具而不是使用證書(shū)頒發(fā)機(jī)構(gòu)园骆。以下命令使用 cryptogen 讀取org3-crypto.yaml
文件并在新org3.example.com
文件夾中生成 Org3 加密材料:
cryptogen generate --config=org3-crypto.yaml --output="../organizations"
您可以在目錄中找到生成的 Org3 加密材料以及 Org1 和 Org2 的證書(shū)和密鑰:test-network/organizations/peerOrganizations
.
一旦我們創(chuàng)建了 Org3 加密材料,我們就可以使用 configtxgen 工具打印出 Org3 組織定義寓调。
我們將通過(guò)告訴工具在當(dāng)前目錄中查找configtx.yaml
它需要攝取的文件來(lái)開(kāi)始命令锌唾。
export FABRIC_CFG_PATH=$PWD
configtxgen -printOrg Org3MSP > ../organizations/peerOrganizations/org3.example.com/org3.json
上面的命令創(chuàng)建了一個(gè) JSON 文件 org3.json
并將其寫(xiě)入下面文件夾。
test-network/organizations/peerOrganizations/org3.example.com/
組織定義包含 Org3 的策略定義夺英、Org3 的 NodeOU 定義以及兩個(gè)以 base64 格式編碼的重要證書(shū):
- CA 根證書(shū)晌涕,用于建立組織間的信任根
- 一個(gè) TLS 根證書(shū),由 gossip 協(xié)議用于標(biāo)識(shí) Org3 以進(jìn)行塊傳播和服務(wù)發(fā)現(xiàn)
我們將通過(guò)將此組織定義附加到通道配置來(lái)將 Org3 添加到通道中痛悯。
調(diào)出 Org3 組件
就是 啟動(dòng) 組織 3 的 peer 節(jié)點(diǎn)
創(chuàng)建 Org3 證書(shū)材料后余黎,我們現(xiàn)在可以啟動(dòng) Org3 對(duì)等體。從addOrg3
目錄中载萌,發(fā)出以下命令:
docker-compose -f docker/docker-compose-org3.yaml up -d
如果命令成功惧财,您將看到 Org3 peer 的創(chuàng)建:
Creating peer0.org3.example.com ... done
此 Docker Compose 文件已配置為跨我們的初始網(wǎng)絡(luò)橋接巡扇,以便 Org3 對(duì)等節(jié)點(diǎn)與測(cè)試網(wǎng)絡(luò)的現(xiàn)有對(duì)等節(jié)點(diǎn)和排序節(jié)點(diǎn)進(jìn)行解析。
獲取配置
讓我們?nèi)カ@取頻道的最新配置塊 – channel1垮衷。
我們必須拉取最新版本的配置的原因是因?yàn)橥ǖ琅渲迷厥前姹净摹?/strong>
出于多種原因厅翔,版本控制很重要。它可以防止重復(fù)或重放配置更改(例如搀突,使用舊 CRL 恢復(fù)到通道配置將代表安全風(fēng)險(xiǎn))刀闷。它還有助于確保并發(fā)性(如果您想從頻道中刪除組織,例如仰迁,在添加新組織后甸昏,版本控制將有助于防止您刪除兩個(gè)組織,而不僅僅是要?jiǎng)h除的組織)徐许。
導(dǎo)航回test-network
目錄施蜜。因?yàn)?Org3 還不是頻道的成員,我們需要以另一個(gè)組織的管理員身份操作來(lái)獲取頻道配置绊寻。因?yàn)?Org1 是頻道的成員花墩,所以 Org1 管理員有權(quán)從排序服務(wù)中獲取頻道配置悬秉。發(fā)出以下命令以作為 Org1 管理員進(jìn)行操作澄步。
# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
我們現(xiàn)在可以發(fā)出命令來(lái)獲取最新的配置塊:
peer channel fetch config channel-artifacts/config_block.pb \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
此命令將二進(jìn)制 protobuf 通道配置塊保存到 config_block.pb
. 請(qǐng)注意,名稱和文件擴(kuò)展名的選擇是任意的和泌。但是村缸,建議遵循標(biāo)識(shí)所表示的對(duì)象類型及其編碼(protobuf 或 JSON)的約定。
peer channel fetch
發(fā)出命令后武氓,日志中會(huì)顯示以下輸出:
2021-11-11 15:32:31.586 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-11 15:32:31.592 CST [cli.common] readBlock -> INFO 002 Received block: 2
2021-11-11 15:32:31.592 CST [channelCmd] fetch -> INFO 003 Retrieving last config block: 2
2021-11-11 15:32:31.595 CST [cli.common] readBlock -> INFO 004 Received block: 2
這告訴我們最近的配置塊channel1
實(shí)際上是塊 2梯皿,而不是創(chuàng)世塊。
默認(rèn)情況下县恕,該 命令返回目標(biāo)通道的最新配置塊东羹,在這種情況下是第三個(gè)塊。
這是因?yàn)闇y(cè)試網(wǎng)絡(luò)腳本為我們的兩個(gè)組織定義了錨點(diǎn)忠烛,并且在兩個(gè)單獨(dú)的通道更新事務(wù)中属提。因此,我們有以下配置序列:
- block 0: genesis block
- block 1: Org1 anchor peer update
- block 2: Org2 anchor peer update
通道配置文件夾下新增塊信息文件
├── channel-artifacts
│ ├── channel1.block
│ ├── channel1.tx
│ └── config_block.pb # 新增
將配置轉(zhuǎn)換為 JSON 并對(duì)其進(jìn)行修剪
通道配置塊存儲(chǔ)在channel-artifacts
文件夾中美尸,以使更新過(guò)程與其他工件分開(kāi)冤议。進(jìn)入 channel-artifacts
文件夾以完成以下步驟:
cd channel-artifacts
- 使用該configtxlator工具將這個(gè)通道配置塊解碼為 JSON 格式(可以被人類讀取和修改)
configtxlator proto_decode \
--input config_block.pb \
--type common.Block \
--output config_block.json
- 去除所有與我們想要進(jìn)行的更改無(wú)關(guān)的標(biāo)題、元數(shù)據(jù)师坎、創(chuàng)建者簽名等
帶有數(shù)組的情況下恕酸,加引號(hào),這個(gè)命令給我們留下了一個(gè)精簡(jiǎn)的 JSON 對(duì)象 config.json
它將作為我們配置更新的基線胯陋。
jq '.data.data[0].payload.data.config' config_block.json > config.json
添加 Org3 加密材
jq 語(yǔ)法參考
選項(xiàng) | 解釋 | 備注 |
---|---|---|
-s | read (slurp) all inputs into an array; apply filter to it | 使用-s 選項(xiàng)蕊温,jq 會(huì)將所有的 JSON 輸入放入一個(gè)數(shù)組中并在這個(gè)數(shù)組上使用 filter袱箱。"-s"選項(xiàng)不但影響到 filter 的寫(xiě)法。如果在 filter 中需要對(duì)數(shù)據(jù)進(jìn)行選擇和映射义矛,其還會(huì)影響最終結(jié)果犯眠。 |
jq -s '.[0] * .[1]' 輸入流1 輸入流2 > test.json
-
.[0]
:由第1個(gè)輸入流產(chǎn)生的數(shù)組數(shù)據(jù) -
.[1]
:由第2個(gè)輸入流產(chǎn)生的數(shù)組數(shù)據(jù) -
*
:參考官方文檔
Multiplication, division, modulo: *, /, and %
These infix operators behave as expected when given two numbers. Division by zero raises an error. x % y computes x modulo y.
Multiplying a string by a number produces the concatenation of that string that many times. "x" * 0 produces null.
Dividing a string by another splits the first using the second as separators.
Multiplying two objects will merge them recursively: this works like addition but if both objects contain a value for the same key, and the values are objects, the two are merged with the same strategy.
增加配置信息
我們將jq再次使用該工具將 Org3 配置定義 org3.json
添加到通道的應(yīng)用程序組字段,并將輸出命名為 modified_config.json
症革。
jq -s \
'.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' \
config.json \
../organizations/peerOrganizations/org3.example.com/org3.json \
> modified_config.json
增量計(jì)算,得到增
現(xiàn)在我們有兩個(gè)感興趣的 JSON 文件 config.json和 modified_config.json. 初始文件僅包含 Org1 和 Org2 材料筐咧,而修改后的文件包含所有三個(gè) Org。
此時(shí)噪矛,只需重新編碼這兩個(gè) JSON 文件并計(jì)算增量即可量蕊。
- 首先,轉(zhuǎn)換
config.json
回一個(gè)名為的protobuf config.pb
configtxlator proto_encode \
--input config.json \
--type common.Config \
--output config.pb
- 接下來(lái)艇挨,編碼
modified_config.json
為modified_config.pb
configtxlator proto_encode \
--input modified_config.json \
--type common.Config \
--output modified_config.pb
- 在用于
configtxlator
計(jì)算這兩個(gè)配置protobufs
之間的增量残炮。此命令將輸出一個(gè)名為的新 protobuf 二進(jìn)制文件org3_update.pb
configtxlator compute_update \
--channel_id channel1 \
--original config.pb \
--updated modified_config.pb \
--output org3_update.pb
這個(gè)新的 proto org3_update.pb
包含 Org3 定義和指向 Org1 和 Org2 材料的高級(jí)指針。
封裝更新信息
在提交頻道更新之前缩滨,我們需要執(zhí)行一些最后的步驟势就。
- 首先,讓我們將此對(duì)象解碼為可編輯的 JSON 格式并調(diào)用它
org3_update.json
configtxlator proto_decode \
--input org3_update.pb \
--type common.ConfigUpdate \
--output org3_update.json
現(xiàn)在脉漏,我們有一個(gè)解碼后的更新文件org3_update.json
.我們需要將它包裝一下苞冯。
這一步將返回我們之前剝離的頭字段。我們將此文件命名為org3_update_in_envelope.json
:
echo '{"payload":{"header":{"channel_header":{"channel_id":"'channel1'", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json
使用我們正確形成的 JSONorg3_update_in_envelope.json
我們將configtxlator最后一次利用該工具并將其轉(zhuǎn)換為 Fabric 所需的完全成熟的 protobuf 格式侧巨。我們將命名我們的最終更新對(duì)象org3_update_in_envelope.pb:
configtxlator proto_encode \
--input org3_update_in_envelope.json \
--type common.Envelope \
--output org3_update_in_envelope.pb
簽署并提交配置更
簽署
現(xiàn)在有一個(gè) protobuf 二進(jìn)制文件 org3_update_in_envelope.pb
. 但是舅锄,在將配置寫(xiě)入分類帳之前,我們需要必需的管理員用戶的簽名司忱。
我們頻道應(yīng)用程序組的修改策略 (mod_policy) 設(shè)置為默認(rèn)值“MAJORITY”皇忿,這意味著我們需要大多數(shù)現(xiàn)有組織管理員對(duì)其進(jìn)行簽名。
因?yàn)槲覀冎挥袃蓚€(gè)組織——Org1 和 Org2——而且兩個(gè)組織中的大多數(shù)是兩個(gè)坦仍,==所以我們需要他們都簽名==鳍烁。
如果沒(méi)有這兩個(gè)簽名,排序服務(wù)將拒絕未能滿足策略的交易繁扎。
- 首先幔荒,讓我們將此更新協(xié)議簽名為 Org1。導(dǎo)航回test-network 目錄:
請(qǐng)記住锻离,我們導(dǎo)出了必要的環(huán)境變量以作為 Org1 管理員進(jìn)行操作铺峭。因此,以下命令會(huì)將更新簽名為 Org1汽纠。peer channel signconfigtx
peer channel signconfigtx -f channel-artifacts/org3_update_in_envelope.pb
最后一步是切換容器的身份以反映 Org2 Admin 用戶卫键。我們通過(guò)導(dǎo)出特定于 Org2 MSP 的四個(gè)環(huán)境變量來(lái)做到這一點(diǎn)。
設(shè)置 Org2 環(huán)境變量:
# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
更新
最后虱朵,我們將發(fā)出peer channel update
命令莉炉。Org2 Admin 的簽名將附加到此調(diào)用中钓账,因此無(wú)需再次手動(dòng)簽署 protobuf。(更新角色會(huì)自動(dòng)簽署并且更新通道配置信息)
peer channel update -f channel-artifacts/org3_update_in_envelope.pb -c channel1 -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
成功的通道更新調(diào)用會(huì)向通道上的所有對(duì)等方返回一個(gè)新塊:塊 3絮宁。
如果您還記得梆暮,塊 0-2 是初始通道配置。Block 3 作為最新的通道配置绍昂,現(xiàn)在在通道上定義了 Org3啦粹。
您可以peer0.org1.example.com
通過(guò)發(fā)出以下命令來(lái)檢查日志:
docker logs -f peer0.org1.example.com
將 Org3的節(jié)點(diǎn)加入頻道
此時(shí),通道配置已更新為包括我們的新組織 Org3窘游,這意味著它的對(duì)等節(jié)點(diǎn)現(xiàn)在可以加入channel1唠椭。
導(dǎo)出以下環(huán)境變量以作為 Org3 管理員進(jìn)行操作:
# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org3MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
export CORE_PEER_ADDRESS=localhost:11051
作為通道更新成功的結(jié)果,排序服務(wù)將驗(yàn)證 Org3 是否可以拉取創(chuàng)世塊并加入通道忍饰。如果 Org3 未成功附加到通道配置贪嫂,則排序服務(wù)將拒絕此請(qǐng)求。
使用命令來(lái)檢索這個(gè)塊:peer channel fetch
peer channel fetch 0 channel-artifacts/channel1.block \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c channel1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-11 17:40:23.213 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-11 17:40:23.220 CST [cli.common] readBlock -> INFO 002 Received block: 0
請(qǐng)注意艾蓝,我們正在傳遞 0
以指示我們想要通道分類帳上的第一個(gè)塊力崇;即創(chuàng)世區(qū)塊。
如果我們簡(jiǎn)單地傳遞命令 peer channel fetch config
赢织,那么我們將收到塊 3——定義了 Org3 的更新配置亮靴。但是,我們不能從下游塊開(kāi)始我們的賬本——我們必須從塊 0 開(kāi)始敌厘。
如果成功台猴,該命令會(huì)將創(chuàng)世塊返回名為channel1.block
. 我們現(xiàn)在可以使用此塊channel1.block
將peer加入通道。
發(fā)出命令peer channel join
并傳入創(chuàng)世塊以將 Org3 peer 加入通道:
peer channel join -b channel-artifacts/channel1.block
2021-11-12 10:59:01.939 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-12 10:59:02.017 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
查詢結(jié)果
在 Org3的環(huán)境下查看該peer peer0.org3.example.com
加入的通道
# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org3MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
export CORE_PEER_ADDRESS=localhost:11051
peer channel list
(base) test-network|5b8c439? ? peer channel list
2021-11-11 17:50:00.527 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
channel1