[Fabric] First-NetWork(byfn.sh文件分析)
Posted 长泽雅美你老婆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Fabric] First-NetWork(byfn.sh文件分析)相关的知识,希望对你有一定的参考价值。
浏览顺序:
直接看最下面的输出日志信息。
文章目录
一、前言
这个主要写的是脚本里面的一些方法主要是做什么的,其实不看也好,只要看日志信息,就足够了,我这里主要想了解一下运行过程,熟悉一下脚本文件的编写。
有的地方直接用的翻译出来的结果,我吃的也不是很透。
希望可以帮助到一些启动网络时,看不懂报错记录的同学。
日志记录写的没有特别详细,删除了一些东西。可以看自己的日志文件
我看的是fabric 1.4.6的版本。地址就不贴了。
因为我用的笔记块内不能放太多,这里直接全部替换成中文的,使用全文翻译也可以。
二、介绍
启动first-network的重要的脚本文件
end-to-end网络。这个记一下,别的贴子大部分这样写的 。
这个测试案例提供了 两个order
节点,每个order
下面有两个peer
节点 ,而且是单机节点模式
这里面使用了两个重要的工具 cryptogen
和 configtxgen
。这两个就是搭建网络是解压出来的工具类文件bin目录下的东西。
cryptogen
:用来产生加密证书的和秘钥的,用于传输加密和身份验证,生成的文件再crypto-config中。configtxgen
: 创建通道必要的工具 、
这两个工具都有自己依赖得yaml
文件。
里面执行了两个sh 脚本文件,ccp-generate.sh
(byfn.sh同目录),scripts.sh
(scripts目录下的文件)
scripts.sh文件详解
另外写了贴子的,详情看主页。
三、详细部分
1. 配置环境变量
#!/bin/bash
#PWD 的地址就是你在的这个 /first-network目录
# 配置环境变量,让子shell也可以访问到
export PATH=$PWD/../bin:$PWD:$PATH
export FABRIC_CFG_PATH=$PWD
export VERBOSE=false
2. 帮助信息
# 这就是帮助信息,起始好多都有help命令的,只是大家不注意罢了。 ./byfn.sh -help
function printHelp()
echo "Usage: "
echo " byfn.sh <mode> [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>] [-l <language>] [-o <consensus-type>] [-i <imagetag>] [-a] [-n] [-v]"
# 就是后面可以加 up down restart generate upgrade
echo " <mode> - one of 'up', 'down', 'restart', 'generate' or 'upgrade'"
# 使用docker-compose up 启动网络
echo " - 'up' - bring up the network with docker-compose up"
# 使用docker-compose down 停止网络
echo " - 'down' - clear the network with docker-compose down"
# 重启网络
echo " - 'restart' - restart the network"
# 生成所需的证书和创世块
echo " - 'generate' - generate required certificates and genesis block"
# 升级fabric网络版本
echo " - 'upgrade' - upgrade the network from version 1.3.x to 1.4.0"
# -c 后面加channel name 通道名,默认为 mychannel
echo " -c <channel name> - channel name to use (defaults to \\"mychannel\\")"
# 下面这俩我也没整太明白,
# -t 设置cli链接超时时间(s为单位,默认为10s)
echo " -t <timeout> - CLI timeout duration in seconds (defaults to 10)"
# -d 设置延迟(s为单位,默认为3s)
echo " -d <delay> - delay duration in seconds (defaults to 3)"
# -f 指定docker-compose.yaml文件(默认为docker-compose-cli.yaml)
# 等我跑起来,这个贴子也出了。
echo " -f <docker-compose-file> - specify which docker-compose file use (defaults to docker-compose-cli.yaml)"
# -s 指定数据库类型,默认是goleveldb 可以指定为couchdb
echo " -s <dbtype> - the database backend to use: goleveldb (default) or couchdb"
# -l 指定链码默认的语言,目前不就是 go node.js java
echo " -l <language> - the chaincode language: golang (default) or node"
# -o 指定共识类型(consensus-共识),order服务的模式:单机,kafka集群,etcdraft(是用于共享配置和服务发现的分布式,一致性的KV存储系统。)
echo " -o <consensus-type> - the consensus-type of the ordering service: solo (default), kafka, or etcdraft"
# -i 启动网络的镜像用的配置,默认是最新的镜像
echo " -i <imagetag> - the tag to be used to launch the network (defaults to \\"latest\\")"
# -a 启动ca 证书办法机构,默认啥都不启动
echo " -a - launch certificate authorities (no certificate authorities are launched by default)"
# -n 不部署链码。默认是abstore链码
echo " -n - do not deploy chaincode (abstore chaincode is deployed by default)"
# -v 详细模式(我也没试呢,试了写出来)
echo " -v - verbose mode"
# -h 就是-help
echo " byfn.sh -h (print this message)"
echo
#下面就是官方说的正常人会执行的启动命令
# 1. 先生成需要的证书和创世区块
# 2. 然后开启网络
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 node"
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"
3. 是否执行脚本
# 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
4. 删除容器
# 删除容器,默认全部删除的,也可以自己指定
function clearContainers()
#可以传参,awk https://www.cnblogs.com/cap-rq/p/11411415.html
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
5. 删除镜像
# 删除作为此设置的一部分生成的镜像
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
6. 版本是否冲突
# Versions of fabric known not to work with this release of first-network
# 不可以配置这个版本使用的fabric的版本
BLACKLISTED_VERSIONS="^1\\.0\\. ^1\\.1\\.0-preview ^1\\.1\\.0-alpha"
# 判断configtxlator的版本和docker镜像的版本是否有冲突
# 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.
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
# 这里我也不太懂,希望大佬指点
#本地的版本
LOCAL_VERSION=$(configtxlator version | sed -ne 's/ Version: //p')
# docker镜像的版本
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
7. 启动网络
# 生成所需的证书、创世块并启动网络。
function networkup()
checkPrereqs
# generate artifacts if they don't exist
# crypto-config不是一个目录
if [ ! -d "crypto-config" ]; then
# 使用cryptogen工具生成证书
generateCerts
# 生成私钥
replacePrivateKey
# 生成通道文件
generateChannelArtifacts
fi
# compose 的文件们
COMPOSE_FILES="-f $COMPOSE_FILE"
# 认证机构
if [ "$CERTIFICATE_AUTHORITIES" == "true" ]; then
# -f 检查后面的是不是普通文件
COMPOSE_FILES="$COMPOSE_FILES -f $COMPOSE_FILE_CA"
# ca1 的 私钥 _sk 结尾的文件
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 [ "$CONSENSUS_TYPE" == "kafka" ]; then
COMPOSE_FILES="$COMPOSE_FILES -f $COMPOSE_FILE_KAFKA"
elif [ "$CONSENSUS_TYPE" == "etcdraft" ]; then
COMPOSE_FILES="$COMPOSE_FILES -f $COMPOSE_FILE_RAFT2"
fi
# 设置数据库类型
if [ "$IF_COUCHDB" == "couchdb" ]; then
COMPOSE_FILES="$COMPOSE_FILES -f $COMPOSE_FILE_COUCH"
fi
# docker 镜像版本 docker-compose 启动
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
# 设置休眠时间,让集群有足够的时间启动
if [ "$CONSENSUS_TYPE" == "kafka" ]; then
sleep 1
echo "Sleeping 10s to allow $CONSENSUS_TYPE cluster to complete booting"
sleep 9
fi
if [ "$CONSENSUS_TYPE" == "etcdraft" ]; then
sleep 1
echo "Sleeping 15s to allow $CONSENSUS_TYPE cluster to complete booting"
sleep 14
fi
# cli 执行 script.sh脚本 后面是接入的参数,后面会整理这个脚本执行的内容的
docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE $NO_CHAINCODE
if [ $? -ne 0 ]; then
echo "ERROR !!!! Test failed"
exit 1
fi
8. 升级网网络
#将版本 1.3.x 的网络组件升级到 1.4.x
# 停止orderer和peer,备份orderer和peer的账本,清理链码容器和镜像,
# 并使用最新标版本重新启动order节点和peer节点
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
# 这个网络似乎不是从fabric-samples >= v1.3.x 开始的
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"
# 判断是否需要认证
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 [ "$CONSENSUS_TYPE" == "kafka" ]; then
COMPOSE_FILES="$COMPOSE_FILES -f $COMPOSE_FILE_KAFKA"
elif [ "$CONSENSUS_TYPE" == "etcdraft" ]; then
COMPOSE_FILES="$COMPOSE_FILES -f $COMPOSE_FILE_RAFT2"
fi
# 判断数据库类型
if [ "$IF_COUCHDB" == "couchdb" ]; then
COMPOSE_FILES="$COMPOSE_FILES -f $COMPOSE_FILE_COUCH"
fi
# 移除Cli容器
docker-compose $COMPOSE_FILES stop cli
docker-compose $COMPOSE_FILES up -d --no-deps cli
# 升级orderer和Peer
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"
# 停止容器,备份账本
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
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
docker-compose $COMPOSE_FILES up -d --no-deps $PEER
done
# cli容器中 运行升级脚本
docker exec cli sh -c "SYS_CHANNEL=$CH_NAME && scripts/upgrade_to_v14.sh $CHANNEL_NAME $CLI_DELAY $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
9. 停止网络
# 停止网络
function networkDown()
# 除了 org1 和 org2 之外,还停止 org3 容器,以防我们正在运行示例以添加 org3
# 停止 kafka 和 zookeeper 容器,以防我们使用 kafka 共识类型运行
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_KAFKA -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
# 停止网络,删除挂载,删除所有的账本备份
docker run -v $PWD:/tmp/first-network --rm hyperledger/fabric-tools:$IMAGETAG rm -Rf /tmp/first-network/ledgers-backup
# 调用上面的清除容器
clearContainers
# 调用上面的清除镜像
removeUnwantedImages
# 删除 orderer 块和其他通道配置交易和证书
rm -rf channel-artifacts/*.block channel-artifacts/*.tx crypto-config ./org3-artifacts/crypto-config/ channel-artifacts/org3.json
# 删除为示例定制的 docker-compose yaml 文件 就是下面这个
rm -f docker-compose-e2e.yaml
fi
10. 替换私钥
# 使用 docker-compose-e2e-template.yaml,
# 将常量替换为由 cryptogen 工具生成的私钥文件名,
# 并输出特定于此配置的 docker-compose.yaml
#替换私钥
function replacePrivateKey()
# MacOSX 上的 sed 不支持带有空扩展名的 -i 标志。
# 我们将使用 't' 作为我们备份的扩展名,并在函数结束时将其删除
ARCH=$(uname -s | grep Darwin)
if [ "$ARCH" == "Darwin" ]; then
OPTS="-it"
else
OPTS="-i"
fi
# 拷贝文件模板
cp docker-compose-e2e-template.yaml docker-compose-e2e.yaml
# 接下来的步骤将使用两个 CA 的私钥文件名的实际值替换模板的内容
# 当前目录
CURRENT_DIR=$PWD
cd crypto-config/peerOrganizations/org1.example.com/ca/
PRIV_KEY=$(ls *_sk)
cd "$CURRENT_DIR"
sed $OPTS "s/CA1_PRIVATE_KEY/$PRIV_KEY/g" docker-compose-e2e.yaml
cd crypto-config/peerOrganizations/org2.example.com/ca/
PRIV_KEY=$(ls *_sk)
cd "$CURRENT_DIR"
sed $OPTS "s/CA2_PRIVATE_KEY/$PRIV_KEY/g" docker-compose-e2e.yaml
# 如果是MacOSX,删除docker-compose文件的临时备份
if [ "$ARCH" == "Darwin" ]; then
rm docker-compose-e2e.yamlt
fi
11. 生成组织证书
# 使用 cryptogen 工具生成组织证书
function generateCerts()
# 查找crytogen工具
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"
# 执行另一个脚本,文件目录里可以看到的,里面放了一写组织的信息 pem文件的位置,启动节点占用的端口
./ccp-generate.sh
12. 调用configtxgen工具
# 生成通道工具配置文件,order 块 锚节点配置
# 主要使用configtxgen
# 然后将这些文件输出到“channel-artifacts”文件夹中。
function generateChannelArtifacts()
which configtxgen
if [ "$?" -ne 0 ]; then
echo "configtxgen tool not found. exiting"
exit 1
fi
# 生成order 创世块
echo "##########################################################"
echo "######### Generating Orderer Genesis block ##############"
echo "##########################################################"
# 注意:由于某些未知原因(至少现在),块文件不能命名为 orderer.genesis.block 否则排序器将无法启动!
echo "CONSENSUS_TYPE="$CONSENSUS_TYPE
set -x
# 根据公式类型 -profile 定了了公式类型,这是 configtx.yaml里面配置的
if [ "$CONSENSUS_TYPE" == "solo" ]; then
configtxgen -profile TwoOrgsOrdererGenesis -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
elif [ "$CONSENSUS_TYPE" == "kafka" ]; then
configtxgen -profile SampleDevModeKafka -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
elif [ "$CONSENSUS_TYPE" == "etcdraft" ]; then
configtxgen -profile SampleMultiNodeEtcdRaft -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
else
set +x
# 无法识别共识类型
echo "unrecognized CONSESUS_TYPE='$CONSENSUS_TYPE'. exiting"
exit 1
fi
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate orderer genesis block..."
exit 1
fi
# 生成通道配置文件 channel.tx
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 "##################################以上是关于[Fabric] First-NetWork(byfn.sh文件分析)的主要内容,如果未能解决你的问题,请参考以下文章
[Fabric]-First-Network(script.sh文件详解)
[Fabric] First-NetWork(byfn.sh文件分析)
Hyperledger Fabric first-network的初始化启动流程(二)
[Fabric]-First-Network (crypto-config.yaml详解)