#!/bin/bash
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
# This script will orchestrate a sample end-to-end execution of the Hyperledger
# Fabric network.
#
# The end-to-end verification provisions a sample Fabric network consisting of
# two organizations, each maintaining two peers, and a Raft ordering service.
#
# This verification makes use of two fundamental tools, which are necessary to
# create a functioning transactional network with digital signature validation
# and access control:
#
# * cryptogen - generates the x509 certificates used to identify and
# authenticate the various components in the network.
# * configtxgen - generates the requisite configuration artifacts for orderer
# bootstrap and channel creation.
#
# Each tool consumes a configuration yaml file, within which we specify the topology
# of our network (cryptogen) and the location of our certificates for various
# configuration operations (configtxgen). Once the tools have been successfully run,
# we are able to launch our network. More detail on the tools and the structure of
# the network will be provided later in this document. For now, let's get going...
# prepending $PWD/../bin to PATH to ensure we are picking up the correct binaries
# this may be commented out to resolve installed version of tools if desired
# 翻译上面:
# 此脚本将编排超分类帐结构网络的端到端执行示例。
# 端到端验证提供了一个由两个组织组成的示例Fabric网络,每个组织维护两个对等点和一个Raft订购服务。
# 此验证使用了两个基本工具,它们是创建具有数字签名验证和访问控制功能的事务性网络所必需的:
# *cryptogen-生成用于识别和验证网络中各种组件的x509证书。
# *configtxgen-生成orderer引导和通道创建所需的配置工件。
# 每个工具都使用一个配置yaml文件,在该文件中,
# 我们为各种配置操作(configtxgen)指定网络的拓扑结构(cryptogen)和证书的位置。一旦工具成功运行,
# 我们能够启动我们的网络。本文档稍后将提供有关工具和网络结构的更多详细信息。现在,让我们开始。。。
# 将$PWD/..bin添加到PATH之前,以确保获取正确的二进制文件。如果需要,可以将其注释掉,以解析安装的工具版本
export PATH=${PWD}/../bin:${PWD}:$PATH
export FABRIC_CFG_PATH=${PWD}
export VERBOSE=false
# Print the usage message
function printHelp() {
echo "Usage: "
echo " byfn.sh [-c ] [-t ] [-d ] [-f ] [-s ] [-l ] [-i ] [-a] [-n] [-v]"
echo " - one of 'up', 'down', 'restart', 'generate' or 'upgrade'"
echo " - 'up' - bring up the network with docker-compose up"
echo " - 'down' - clear the network with docker-compose down"
echo " - 'restart' - restart the network"
echo " - 'generate' - generate required certificates and genesis block"
echo " - 'upgrade' - upgrade the network from version 1.3.x to 1.4.0"
echo " -c - channel name to use (defaults to \"mychannel\")"
echo " -t - CLI timeout duration in seconds (defaults to 10)"
echo " -d - delay duration in seconds (defaults to 3)"
echo " -s - the database backend to use: goleveldb (default) or couchdb"
echo " -l - the programming language of the chaincode to deploy: go (default), javascript, or java"
echo " -i - the tag to be used to launch the network (defaults to \"latest\")"
echo " -a - launch certificate authorities (no certificate authorities are launched by default)"
echo " -n - do not deploy chaincode (abstore chaincode is deployed by default)"
echo " -v - verbose mode"
echo " byfn.sh -h (print this message)"
echo
echo "Typically, one would first generate the required certificates and "
echo "genesis block, then bring up the network. e.g.:"
echo
echo " byfn.sh generate -c mychannel"
echo " byfn.sh up -c mychannel -s couchdb"
echo " byfn.sh up -c mychannel -s couchdb -i 1.4.0"
echo " byfn.sh up -l javascript"
echo " byfn.sh down -c mychannel"
echo " byfn.sh upgrade -c mychannel"
echo
echo "Taking all defaults:"
echo " byfn.sh generate"
echo " byfn.sh up"
echo " byfn.sh down"
}
# Ask user for confirmation to proceed
#请求用户确认以继续
function askProceed() {
read -p "Continue? [Y/n] " ans
case "$ans" in
y | Y | "")
echo "proceeding ..."
;;
n | N)
echo "exiting..."
exit 1
;;
*)
echo "invalid response"
askProceed
;;
esac
}
# Obtain CONTAINER_IDS and remove them
# TODO Might want to make this optional - could clear other containers
#获取容器ID并将其移除
#TODO可能希望将此设置为可选-可以清除其他容器
function clearContainers() {
CONTAINER_IDS=$(docker ps -a | awk '($2 ~ /dev-peer.*/) {print $1}')
if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then
echo "---- No containers available for deletion ----"
else
docker rm -f $CONTAINER_IDS
fi
}
# Delete any images that were generated as a part of this setup
# specifically the following images are often left behind:
# TODO list generated image naming patterns
#删除作为此设置一部分生成的所有镜像
#具体来说,以下镜像经常被遗忘:
#列出生成的镜像命名模式
function removeUnwantedImages() {
DOCKER_IMAGE_IDS=$(docker images | awk '($1 ~ /dev-peer.*/) {print $3}')
if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then
echo "---- No images available for deletion ----"
else
docker rmi -f $DOCKER_IMAGE_IDS
fi
}
# Versions of fabric known not to work with this release of first-network
#已知与此版本的first network不兼容的结构版本
BLACKLISTED_VERSIONS="^1\."
# Do some basic sanity checking to make sure that the appropriate versions of fabric
# binaries/images are available. In the future, additional checking for the presence
# of go or other items could be added.
#执行一些基本的健全性检查,以确保结构二进制文件/镜像的适当版本可用。在将来,可以添加对go或其他项的存在性的额外检查。
function checkPrereqs() {
# Note, we check configtxlator externally because it does not require a config file, and peer in the
# docker image because of FAB-8551 that makes configtxlator return 'development version' in docker
#注意,我们在外部检查configtxlator,因为它不需要配置文件;在docker映像中检查peer,
#因为FAB-8551,mak configtxlator在docker中返回'development version'
LOCAL_VERSION=$(configtxlator version | sed -ne 's/ Version: //p')
DOCKER_IMAGE_VERSION=$(docker run --rm hyperledger/fabric-tools:$IMAGETAG peer version | sed -ne 's/ Version: //p' | head -1)
echo "LOCAL_VERSION=$LOCAL_VERSION"
echo "DOCKER_IMAGE_VERSION=$DOCKER_IMAGE_VERSION"
if [ "$LOCAL_VERSION" != "$DOCKER_IMAGE_VERSION" ]; then
echo "=================== WARNING ==================="
echo " Local fabric binaries and docker images are "
echo " out of sync. This may cause problems. "
echo "==============================================="
fi
for UNSUPPORTED_VERSION in $BLACKLISTED_VERSIONS; do
echo "$LOCAL_VERSION" | grep -q $UNSUPPORTED_VERSION
if [ $? -eq 0 ]; then
echo "ERROR! Local Fabric binary version of $LOCAL_VERSION does not match this newer version of BYFN and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples."
exit 1
fi
echo "$DOCKER_IMAGE_VERSION" | grep -q $UNSUPPORTED_VERSION
if [ $? -eq 0 ]; then
echo "ERROR! Fabric Docker image version of $DOCKER_IMAGE_VERSION does not match this newer version of BYFN and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples."
exit 1
fi
done
}
# Generate the needed certificates, the genesis block and start the network.
#生成所需的证书、genesis(创世区块)块并启动网络。
function networkUp() {
checkPrereqs
# generate artifacts if they don't exist
#生成不存在的工件
if [ ! -d "crypto-config" ]; then
generateCerts
generateChannelArtifacts
fi
COMPOSE_FILES="-f ${COMPOSE_FILE} -f ${COMPOSE_FILE_RAFT2}"
if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}"
export BYFN_CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.example.com/ca && ls *_sk)
export BYFN_CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.example.com/ca && ls *_sk)
fi
if [ "${IF_COUCHDB}" == "couchdb" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}"
fi
IMAGE_TAG=$IMAGETAG docker-compose ${COMPOSE_FILES} up -d 2>&1
docker ps -a
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to start network"
exit 1
fi
echo "Sleeping 15s to allow Raft cluster to complete booting"
sleep 15
if [ "${NO_CHAINCODE}" != "true" ]; then
echo Vendoring Go dependencies ...
pushd ../chaincode/abstore/go
GO111MODULE=on go mod vendor
popd
echo Finished vendoring Go dependencies
fi
# now run the end to end script
#现在运行端到端脚本
docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $CC_SRC_LANGUAGE $CLI_TIMEOUT $VERBOSE $NO_CHAINCODE
if [ $? -ne 0 ]; then
echo "ERROR !!!! Test failed"
exit 1
fi
}
# Upgrade the network components which are at version 1.3.x to 1.4.x
# Stop the orderer and peers, backup the ledger for orderer and peers, cleanup chaincode containers and images
# and relaunch the orderer and peers with latest tag
#将1.3.x版的网络组件升级到1.4.x版
#停止orderer和peers,备份orderer和orderer的账本,清理链码容器和镜像,并使用最新tag重新启动orderer和peers
function upgradeNetwork() {
if [[ "$IMAGETAG" == *"1.4"* ]] || [[ $IMAGETAG == "latest" ]]; then
docker inspect -f '{{.Config.Volumes}}' orderer.example.com | grep -q '/var/hyperledger/production/orderer'
if [ $? -ne 0 ]; then
echo "ERROR !!!! This network does not appear to start with fabric-samples >= v1.3.x?"
exit 1
fi
LEDGERS_BACKUP=./ledgers-backup
# create ledger-backup directory
#创建分类帐备份目录
mkdir -p $LEDGERS_BACKUP
export IMAGE_TAG=$IMAGETAG
COMPOSE_FILES="-f ${COMPOSE_FILE} -f ${COMPOSE_FILE_RAFT2}"
if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}"
export BYFN_CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.example.com/ca && ls *_sk)
export BYFN_CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.example.com/ca && ls *_sk)
fi
if [ "${IF_COUCHDB}" == "couchdb" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}"
fi
# removing the cli container
#删除cli容器
docker-compose $COMPOSE_FILES stop cli
docker-compose $COMPOSE_FILES up -d --no-deps cli
echo "Upgrading orderer"
docker-compose $COMPOSE_FILES stop orderer.example.com
docker cp -a orderer.example.com:/var/hyperledger/production/orderer $LEDGERS_BACKUP/orderer.example.com
docker-compose $COMPOSE_FILES up -d --no-deps orderer.example.com
for PEER in peer0.org1.example.com peer1.org1.example.com peer0.org2.example.com peer1.org2.example.com; do
echo "Upgrading peer $PEER"
# Stop the peer and backup its ledger
#停止peer并备份其分类帐
docker-compose $COMPOSE_FILES stop $PEER
docker cp -a $PEER:/var/hyperledger/production $LEDGERS_BACKUP/$PEER/
# Remove any old containers and images for this peer
#删除此peer的所有旧容器和镜像
CC_CONTAINERS=$(docker ps | grep dev-$PEER | awk '{print $1}')
if [ -n "$CC_CONTAINERS" ]; then
docker rm -f $CC_CONTAINERS
fi
CC_IMAGES=$(docker images | grep dev-$PEER | awk '{print $1}')
if [ -n "$CC_IMAGES" ]; then
docker rmi -f $CC_IMAGES
fi
# Start the peer again 重启peer
docker-compose $COMPOSE_FILES up -d --no-deps $PEER
done
docker exec cli scripts/upgrade_to_v14.sh $CHANNEL_NAME $CLI_DELAY $CC_SRC_LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then
echo "ERROR !!!! Test failed"
exit 1
fi
else
echo "ERROR !!!! Pass the v1.4.x image tag"
fi
}
# Tear down running network
#拆分运行网络
function networkDown() {
# stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3
#除了org1和org2之外,还要停止org3容器,以防我们运行sample来添加org3
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_RAFT2 -f $COMPOSE_FILE_CA -f $COMPOSE_FILE_ORG3 down --volumes --remove-orphans
# Don't remove the generated artifacts -- note, the ledgers are always removed
#不要移除生成的证书——注意,分类账总是被移除的
if [ "$MODE" != "restart" ]; then
# Bring down the network, deleting the volumes
#Delete any ledger backups
#关闭网络,删除卷
#删除任何分类帐备份
docker run -v $PWD:/tmp/first-network --rm hyperledger/fabric-tools:$IMAGETAG rm -Rf /tmp/first-network/ledgers-backup
#Cleanup the chaincode containers 清除连码容器
clearContainers
#Cleanup images 清除镜像
removeUnwantedImages
# remove orderer block and other channel configuration transactions and certs
#删除orderer块和其他通道配置事务和证书
rm -rf channel-artifacts/*.block channel-artifacts/*.tx crypto-config ./org3-artifacts/crypto-config/ channel-artifacts/org3.json
fi
}
# We will use the cryptogen tool to generate the cryptographic material (x509 certs)
# for our various network entities. The certificates are based on a standard PKI
# implementation where validation is achieved by reaching a common trust anchor.
#
# Cryptogen consumes a file - ``crypto-config.yaml`` - that contains the network
# topology and allows us to generate a library of certificates for both the
# Organizations and the components that belong to those Organizations. Each
# Organization is provisioned a unique root certificate (``ca-cert``), that binds
# specific components (peers and orderers) to that Org. Transactions and communications
# within Fabric are signed by an entity's private key (``keystore``), and then verified
# by means of a public key (``signcerts``). You will notice a "count" variable within
# this file. We use this to specify the number of peers per Organization; in our
# case it's two peers per Org. The rest of this template is extremely
# self-explanatory.
#
# After we run the tool, the certs will be parked in a folder titled ``crypto-config``.
# Generates Org certs using cryptogen tool
# 我们将使用cryptogen工具为各种网络实体生成加密材料(x509证书)。这些证书基于一个标准的PKI实现,其中通过达到一个公共信任锚来实现验证。
# Cryptogen使用一个文件-`` crypto-配置.yaml``-包含网络拓扑并允许我们为组织和属于这些组织的组件生成证书库。
#每个组织都有一个唯一的根证书(``ca cert``),它将特定组件(对等方和订购方)绑定到该组织。
#Fabric中的事务和通信由实体的私钥(``keystore`)签名,然后通过公钥(``signcerts`)进行验证。您会注意到这个文件中有一个“count”变量。
#我们使用这个来指定每个组织的对等点数量;在我们的例子中,是每个组织两个对等点。这个模板的其余部分也是这样。
# 在我们运行该工具之后,证书将存在一个名为“crypto config”的文件夹中。
# 使用加密工具生成组织证书
function generateCerts() {
which cryptogen
if [ "$?" -ne 0 ]; then
echo "cryptogen tool not found. exiting"
exit 1
fi
echo
echo "##########################################################"
echo "##### Generate certificates using cryptogen tool #########"
echo "##########################################################"
if [ -d "crypto-config" ]; then
rm -Rf crypto-config
fi
set -x
cryptogen generate --config=./crypto-config.yaml
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate certificates..."
exit 1
fi
echo
echo "Generate CCP files for Org1 and Org2"
./ccp-generate.sh
}
# The `configtxgen tool is used to create four artifacts: orderer **bootstrap
# block**, fabric **channel configuration transaction**, and two **anchor
# peer transactions** - one for each Peer Org.
#
# The orderer block is the genesis block for the ordering service, and the
# channel transaction file is broadcast to the orderer at channel creation
# time. The anchor peer transactions, as the name might suggest, specify each
# Org's anchor peer on this channel.
#
# Configtxgen consumes a file - ``configtx.yaml`` - that contains the definitions
# for the sample network. There are three members - one Orderer Org (``OrdererOrg``)
# and two Peer Orgs (``Org1`` & ``Org2``) each managing and maintaining two peer nodes.
# This file also specifies a consortium - ``SampleConsortium`` - consisting of our
# two Peer Orgs. Pay specific attention to the "Profiles" section at the top of
# this file. You will notice that we have two unique headers. One for the orderer genesis
# block - ``TwoOrgsOrdererGenesis`` - and one for our channel - ``TwoOrgsChannel``.
# These headers are important, as we will pass them in as arguments when we create
# our artifacts. This file also contains two additional specifications that are worth
# noting. Firstly, we specify the anchor peers for each Peer Org
# (``peer0.org1.example.com`` & ``peer0.org2.example.com``). Secondly, we point to
# the location of the MSP directory for each member, in turn allowing us to store the
# root certificates for each Org in the orderer genesis block. This is a critical
# concept. Now any network entity communicating with the ordering service can have
# its digital signature verified.
#
# This function will generate the crypto material and our four configuration
# artifacts, and subsequently output these files into the ``channel-artifacts``
# folder.
#
# If you receive the following warning, it can be safely ignored:
#
# [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP.
#
# You can ignore the logs regarding intermediate certs, we are not using them in
# this crypto implementation.
# Generate orderer genesis block, channel configuration transaction and
# anchor peer update transactions
#configtxgen工具用于创建四个工件:order**bootstrap block**、fabric**channel configuration transaction**,
#以及两个**anchor peer transactions**-每个peer Org一个。
# orderer块是ordering服务的genesis块,通道事务文件在通道创建时广播给orderer。锚节点事务,正如名称所示,指定这个通道上每个组织的锚节点。
# Configtxgen使用文件-``配置.yaml``-包含示例网络的定义。有三个成员—一个Orderer组织(``OrderOrg``)和两个对等组织(``Org1`&``Org2``),
# 每个组织管理和维护两个对等节点。
# 这个文件还指定了一个由我们的两个对等组织组成的联合体``SampleConsortium``。请特别注意此文件顶部的“配置文件”部分。
# 你会注意到我们有两个唯一的标题。
# 一个用于orderer genesis块``TwoOrgsOrdererGenesis``和一个用于我们的频道``TwoOrgsChannel``。
# 这些头文件很重要,因为我们在创建工件时会将它们作为参数传入。此文件还包含两个值得注意的附加规范。
# 首先,我们为每个对等组织(``peer0.org1)指定锚节点。
# example.com网站``&``peer0.org2。example.com网站``). 其次,我们指向每个成员的MSP目录的位置,
# 从而允许我们在order genesis块中存储每个Org的根证书。
# 这是一个重要的概念。现在,任何与订购服务通信的网络实体都可以验证其数字签名。
# 此函数将生成加密材料和四个配置工件,然后将这些文件输出到“channel artifacts”文件夹中。
# 如果收到以下警告,则可以安全地忽略它:
# [bccsp]GetDefault->WARN 001在使用bccsp之前,请调用InitFactories()。回到bootbccp。
# 您可以忽略有关中间证书的日志,我们在此加密实现中不使用它们。
# 生成orderer genesis块、通道配置事务和锚定对等更新事务
function generateChannelArtifacts() {
which configtxgen
if [ "$?" -ne 0 ]; then
echo "configtxgen tool not found. exiting"
exit 1
fi
echo "##########################################################"
echo "######### Generating Orderer Genesis block ##############"
echo "##########################################################"
# Note: For some unknown reason (at least for now) the block file can't be
# named orderer.genesis.block or the orderer will fail to launch!
#注意:由于某些未知原因(至少目前),无法命名块orderer.genesis.block否则orderer将无法启动!
set -x
configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate orderer genesis block..."
exit 1
fi
echo
echo "#################################################################"
echo "### Generating channel configuration transaction 'channel.tx' ###"
echo "#################################################################"
set -x
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate channel configuration transaction..."
exit 1
fi
echo
echo "#################################################################"
echo "####### Generating anchor peer update for Org1MSP ##########"
echo "#################################################################"
set -x
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate anchor peer update for Org1MSP..."
exit 1
fi
echo
echo "#################################################################"
echo "####### Generating anchor peer update for Org2MSP ##########"
echo "#################################################################"
set -x
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate \
./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate anchor peer update for Org2MSP..."
exit 1
fi
echo
}
# timeout duration - the duration the CLI should wait for a response from
# another container before giving up
#超时持续时间-在放弃之前,CLI应等待来自另一个容器的响应的持续时间
CLI_TIMEOUT=10
# default for delay between commands
#命令之间延迟的默认值
CLI_DELAY=3
# channel name defaults to "mychannel"
#频道名称默认为“mychannel”
CHANNEL_NAME="mychannel"
# use this as the default docker-compose yaml definition
#使用这个作为默认的docker compose yaml定义
COMPOSE_FILE=docker-compose-cli.yaml
#数据存储
COMPOSE_FILE_COUCH=docker-compose-couch.yaml
# org3 docker compose file
COMPOSE_FILE_ORG3=docker-compose-org3.yaml
# two additional etcd/raft orderers
#另外两个etcd/raft orderers
COMPOSE_FILE_RAFT2=docker-compose-etcdraft2.yaml
# #证书颁发
COMPOSE_FILE_CA=docker-compose-ca.yaml
#
# use go as the default language for chaincode 默认编译语言go
CC_SRC_LANGUAGE=go
# default image tag
IMAGETAG="latest"
# Parse commandline args 解析命令行参数
if [ "$1" = "-m" ]; then # supports old usage, muscle memory is powerful!
shift
fi
MODE=$1
shift
# Determine whether starting, stopping, restarting, generating or upgrading
#确定是否启动、停止、重新启动、生成或升级
if [ "$MODE" == "up" ]; then
EXPMODE="Starting"
elif [ "$MODE" == "down" ]; then
EXPMODE="Stopping"
elif [ "$MODE" == "restart" ]; then
EXPMODE="Restarting"
elif [ "$MODE" == "generate" ]; then
EXPMODE="Generating certs and genesis block"
elif [ "$MODE" == "upgrade" ]; then
EXPMODE="Upgrading the network"
else
printHelp
exit 1
fi
while getopts "h?c:t:d:s:l:i:anv" opt; do
case "$opt" in
h | \?)
printHelp
exit 0
;;
c)
CHANNEL_NAME=$OPTARG
;;
t)
CLI_TIMEOUT=$OPTARG
;;
d)
CLI_DELAY=$OPTARG
;;
s)
IF_COUCHDB=$OPTARG
;;
l)
CC_SRC_LANGUAGE=$OPTARG
;;
i)
IMAGETAG=$(go env GOARCH)"-"$OPTARG
;;
a)
CERTIFICATE_AUTHORITIES=true
;;
n)
NO_CHAINCODE=true
;;
v)
VERBOSE=true
;;
esac
done
# Announce what was requested
#请求的内容
if [ "${IF_COUCHDB}" == "couchdb" ]; then
echo
echo "${EXPMODE} for channel '${CHANNEL_NAME}' with CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds and using database '${IF_COUCHDB}'"
else
echo "${EXPMODE} for channel '${CHANNEL_NAME}' with CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds"
fi
# ask for confirmation to proceed
askProceed
#Create the network using docker compose
if [ "${MODE}" == "up" ]; then
networkUp
elif [ "${MODE}" == "down" ]; then ## Clear the network
networkDown
elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts
generateCerts
generateChannelArtifacts
elif [ "${MODE}" == "restart" ]; then ## Restart the network
networkDown
networkUp
elif [ "${MODE}" == "upgrade" ]; then ## Upgrade the network from version 1.2.x to 1.3.x
upgradeNetwork
else
printHelp
exit 1
fi