一、解析makefile文件
makefike文件原文:
SHELL := /bin/bash
HLF_MODE ?= raft
DB_MODE ?= golevel
DEV_MODE ?= non-dev
NETWORK_INIT_WAIT ?= 2
COMPOSE_FILE ?= "docker-compose-2orgs-4peers-raft.yaml"
ifeq ( $( HLF_MODE) ,raft)
NETWORK_INIT_WAIT = 5
else
NETWORK_INIT_WAIT = 30
endif
COMPOSE_FILE = "docker-compose-2orgs-4peers-$( HLF_MODE) .yaml"
LOG_PATH ?= $( HLF_MODE) /logs
ifeq ( $( DB_MODE) ,couchdb)
COMPOSE_FILE = "docker-compose-2orgs-4peers-couchdb.yaml"
endif
ifeq ( $( DEV_MODE) ,dev)
COMPOSE_FILE = "docker-compose-2orgs-4peers-dev.yaml"
endif
all: test
test:
@echo "Run test with $( COMPOSE_FILE) "
@echo "Please make sure u have setup Docker and pulled images by 'make setup download'."
make ready
make stop clean
ready:
make stop
make gen_config_crypto
make gen_config_channel
make start
sleep ${NETWORK_INIT_WAIT}
make channel_test
make update_anchors
make cc_test
make test_qscc
make test_cscc
make test_fetch_blocks
make test_gen_add_org3_tx
make test_channel_update
make test_fetch_blocks
make test_configtxlator
make test_channel_list
make test_channel_getinfo
@echo "Now the fabric network is ready to play"
@echo "* run 'make cli' to enter into the fabric-cli container."
@echo "* run 'make stop' when done."
channel_test: test_channel_create test_channel_join test_channel_list test_channel_getinfo
cc_test: test_cc_install test_cc_queryinstalled test_cc_approveformyorg test_cc_queryapproved test_cc_checkcommitreadiness test_cc_commit test_cc_querycommitted test_cc_invoke_query
restart: stop start
start:
@echo "Start a fabric network with ${COMPOSE_FILE} ..."
@make clean
@echo "Make sure the local hlf_net docker bridge exists"
docker network ls | grep hlf_net > /dev/null || docker network create hlf_net
@docker-compose -f ${COMPOSE_FILE} up -d
stop:
@echo "Stop the fabric network with ${COMPOSE_FILE} ..."
@docker-compose -f ${COMPOSE_FILE} down >& /tmp/docker-compose.log
chaincode_dev: restart chaincode_init test_cc_peer0 stop
test_channel_list:
@echo "List the joined channels"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_list.sh"
test_channel_getinfo:
@echo "Get info of the app channel"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_getinfo.sh"
test_channel_create:
@echo "Create channel on the fabric network"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_create.sh"
test_channel_join:
@echo "Join channel"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_join.sh"
update_anchors:
@echo "Update anchors on the fabric network"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_update_anchors.sh"
test_channel_update:
@echo "Test channel update with adding new org"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_update.sh"
test_configtxlator:
@echo "Testing decoding and encoding with configtxlator"
bash scripts/test_configtxlator.sh ${HLF_MODE}
@echo "Flattening the json files of all blocks"
python3 scripts/json_flatter.py ${HLF_MODE} /channel-artifacts/
test_gen_add_org3_tx:
bash scripts/test_gen_add_org3_tx.sh ${HLF_MODE}
test_cc:
if [ "$( HLF_MODE) " = "dev" ] ; then \
make test_cc_peer0; \
else \
make test_cc_invoke_query; \
fi
test_cc_install:
@echo "Install chaincode to all peers"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_install.sh"
test_cc_queryinstalled:
@echo "Query the installed chaincode"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_queryinstalled.sh"
test_cc_getinstalled:
@echo "Get the installed chaincode package"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_getinstalled.sh"
test_cc_approveformyorg:
@echo "Approve the chaincode by all orgs"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_approveformyorg.sh"
test_cc_queryapproved:
@echo "Query the approved status of chaincode"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_queryapproved.sh"
test_cc_checkcommitreadiness:
@echo "Query the chaincode approval status by all orgs"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_checkcommitreadiness.sh"
test_cc_commit:
@echo "Commit the chaincode by any org"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_commit.sh"
test_cc_querycommitted:
@echo "Query the commit status of chaincode"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_querycommitted.sh"
test_cc_instantiate:
@echo "Instantiate chaincode on the fabric network"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_instantiate.sh"
test_cc_upgrade:
@echo "Upgrade chaincode on the fabric network"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_upgrade.sh"
test_cc_list:
@echo "List chaincode information (installed and instantited)"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_list.sh"
test_cc_invoke_query:
@echo "Invoke and query cc example02 on all peers"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_invoke_query.sh"
test_cscc:
@echo "Test CSCC query"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cscc.sh"
test_qscc:
@echo "Test QSCC query"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_qscc.sh"
test_lscc:
@echo "Test LSCC query"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_lscc.sh"
test_fetch_blocks:
@echo "Test fetching block files"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_fetch_blocks.sh"
test_eventsclient:
@echo "Test fetching event notification"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/start_eventsclient.sh"
test_sidedb:
@echo "Test sideDB"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_sideDB.sh"
temp:
@echo "Test experimental instructions"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_temp.sh"
setup:
bash scripts/env_setup.sh
check:
@echo "Check shell scripts grammar"
[ ` which shellcheck ` ] && shellcheck scripts/*.sh
clean:
@echo "Clean all HLF containers and chaincode images"
@-docker ps -a | awk '{ print $$ 1,$$ 2 }' | grep "hyperledger/fabric" | awk '{ print $$ 1 }' | xargs -r -I {
} docker rm -f {
}
@-docker ps -a | awk '$$ 2 ~ /dev-peer/ { print $$ 1 }' | xargs -r -I {
} docker rm -f {
}
@-docker images | awk '$$ 1 ~ /dev-peer/ { print $$ 3 }' | xargs -r -I {
} docker rmi -f {
}
echo "May clean the config: HLF_MODE=${HLF_MODE} make clean_config_channel"
purge: clean
HLF_MODE = raft make clean_config_channel
make clean_config_crypto
env_clean:
@echo "Clean all images and containers"
bash scripts/env_clean.sh
cli:
docker exec -it fabric-cli bash
orderer: orderer0
orderer0:
docker exec -it orderer0.example.com bash
orderer1:
docker exec -it orderer1.example.com bash
peer: peer0
peer0:
docker exec -it peer0.org1.example.com bash
peer1:
docker exec -it peer1.org1.example.com bash
ps:
docker ps -a
logs:
docker-compose -f ${COMPOSE_FILE} logs -f --tail 200
logs_check: logs_save logs_view
logs_save:
@echo "All tests done, saving logs locally"
[ -d $( LOG_PATH) ] || mkdir -p $( LOG_PATH)
docker logs peer0.org1.example.com >& $( LOG_PATH) /dev_peer0.log
docker logs orderer0.example.com >& $( LOG_PATH) /dev_orderer.log
docker-compose -f ${COMPOSE_FILE} logs >& $( LOG_PATH) /dev_all.log
logs_view:
less $( LOG_PATH) /dev_peer.log
elk:
nc localhost 5000 < $( LOG_PATH) /dev_all.log
gen_config_crypto:
bash scripts/gen_crypto_artifacts.sh
gen_config_channel:
bash scripts/gen_channel_artifacts.sh ${HLF_MODE}
clean_config_channel:
rm -rf ${HLF_MODE} /channel-artifacts/*
clean_config_crypto:
echo "Warning: Cleaning credentials will affect artifacts in raft mode"
rm -rf crypto-config/*
rm -rf org3/crypto-config/*
download:
@echo "Download Docker images"
bash scripts/download_images.sh
chaincode_init:
@echo "Install and instantiate cc example02 on the fabric dev network"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/init_chaincode_dev.sh"
第一部分:SHELL:=/bin/bash
命令解析:引入shell执行环境,可以在makefile中使用shell命令,如echo
第二部分:使用?=
形式赋值,若make时没有传入值,则使用?=
后定义的值,如make时传入值,如:HLF_MODE=a make
,则使用传入的值
HLF_MODE ?= raft
DB_MODE ?= golevel
DEV_MODE ?= non-dev
NETWORK_INIT_WAIT ?= 2
COMPOSE_FILE ?= "docker-compose-2orgs-4peers-raft.yaml"
第四部分:打印两句话,之后使用make执行ready,stop以及clean这三部分
test:
@echo "Run test with $( COMPOSE_FILE) "
@echo "Please make sure u have setup Docker and pulled images by 'make setup download'."
make ready
make stop clean
二、makefile中setup部分
makefile中setup原文
setup:
bash scripts/env_setup.sh
解析:执行scripts/env_setup.sh文件
scripts/env_setup.sh原文
#!/usr/bin/env bash
install_docker ( ) {
echo "Install Docker..."
wget -qO- https://get.docker.com/ | sh
sudo service docker stop
echo "Docker Installation Done"
}
install_docker_compose ( ) {
echo "Install Docker-Compose..."
command -v "curl" > /dev/null 2 >&1 || sudo apt-get update && apt-get install curl -y
curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-$( uname -s) -$( uname -m) > /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
echo "Docker-Compose Installation Done"
}
command -v "docker" > /dev/null 2 >&1 && echo "Docker already installed" || install_docker
command -v "docker-compose" > /dev/null 2 >&1 && echo "Docker-Compose already installed" || install_docker_compose
command -v "jq" > /dev/null 2 >&1 && echo "jq already installed" || sudo apt-get install jq
echo "Create default docker network for usage"
docker network create hlf_net
scripts/env_setup.sh解析: -a)首先执行命令:command -v "docker" >/dev/null 2>&1 && echo "Docker already installed" || install_docker
,此命令从||
分为两部分,意义:若安装了docker,则打印Docker already installed
,否则执行函数install_docker函数 -b)然后执行命令:command -v "docker-compose" >/dev/null 2>&1 && echo "Docker-Compose already installed" || install_docker_compose
,意义:若已安装docker-compose,则打印Docker-Compose already installed,否则执行install_docker_compose函数 -c)再执行命令:command -v "jq" >/dev/null 2>&1 && echo "jq already installed" || sudo apt-get install jq
,意义:若已安装jq,则打印jq already installed
,否则执行命令sudo apt-get install jq
安装jq -d)之后执行命令:echo "Create default docker network for usage"
,打印一句话 -e)最后执行命令:docker network create hlf_net
,使用docker network创建一个名为hlf_net的docker网络。(可以使用命令docker network ls
可以看到创建后的网络)
三、makefile中ready部分
makefile中ready原文
ready:
make stop
make gen_config_crypto
make gen_config_channel
make start
sleep ${NETWORK_INIT_WAIT}
make channel_test
make update_anchors
make cc_test
make test_qscc
make test_cscc
make test_fetch_blocks
make test_gen_add_org3_tx
make test_channel_update
make test_fetch_blocks
make test_configtxlator
make test_channel_list
make test_channel_getinfo
@echo "Now the fabric network is ready to play"
@echo "* run 'make cli' to enter into the fabric-cli container."
@echo "* run 'make stop' when done."
解析:执行stop,gen_config_crypto,gen_config_channel,start部分后,暂停${NETWORK_INIT_WAIT}秒,由于这里使用的是raft,所以暂停5s后,再执行下面的部分
四、makefile中stop部分
makefile中stop部分原文
stop:
@echo "Stop the fabric network with ${COMPOSE_FILE} ..."
@docker-compose -f ${COMPOSE_FILE} down >& /tmp/docker-compose.log
解析: -a)执行命令:echo "Stop the fabric network with ${COMPOSE_FILE}..."
,这里的COMPOSE_FILE=docker-compose-2orgs-4peers-raft.yaml,所以打印:Stop the fabric network with docker-compose-2orgs-4peers-raft.yaml
-b)执行命令:docker-compose -f ${COMPOSE_FILE} down
关闭以文件docker-compose-2orgs-4peers-raft.yaml启动的docker-compose容器组,并将日志信息打印在/tmp/docker-compose.log
日志文件里
五、makefile中gen_config_crypto部分
makefile中gen_config_crypto部分原文
gen_config_crypto:
bash scripts/gen_crypto_artifacts.sh
makefile中gen_config_crypto部分解析:执行scripts/gen_crypto_artifacts.sh文件
scripts/gen_crypto_artifacts.sh文件原文
#! /bin/bash
if [ -f ./func.sh ] ; then
source ./func.sh
elif [ -f scripts/func.sh ] ; then
source scripts/func.sh
else
echo "Cannot find the func.sh files, pls check"
exit 1
fi
echo_b "Clean existing container $GEN_CONTAINER "
[ "$( docker ps -a | grep $GEN_CONTAINER) " ] && docker rm -f $GEN_CONTAINER
[ ! -d ${CRYPTO_CONFIG} ] && mkdir -p ${CRYPTO_CONFIG}
[ ! -d org3/${CRYPTO_CONFIG} ] && mkdir -p org3/${CRYPTO_CONFIG}
echo_b "Make sure crypto-config dir exists already"
if [ -d ${CRYPTO_CONFIG} -a ! -z "$( ls -A ${
CRYPTO_CONFIG} ) " ] ; then
echo_b "${CRYPTO_CONFIG} exists, ignore."
exit 0
fi
echo_g "Generating ${CRYPTO_CONFIG} ..."
docker run \
--rm -it \
--name ${GEN_CONTAINER} \
-e "CONFIGTX_LOGGING_LEVEL=DEBUG" \
-v $PWD /${CRYPTO_CONFIG} :/tmp/${CRYPTO_CONFIG} \
-v $PWD /crypto-config.yaml:/tmp/crypto-config.yaml \
-v $PWD /org3:/tmp/org3 \
-v $PWD /scripts/cryptogen_cryptoArtifacts.sh:/scripts/cryptogen_cryptoArtifacts.sh \
${GEN_IMG} sh -c 'sleep 1; bash /scripts/cryptogen_cryptoArtifacts.sh'
[ $? -ne 0 ] && exit 1
echo_b "Copy org3's crypto config outside"
cp -r org3/${CRYPTO_CONFIG} /* ${CRYPTO_CONFIG} /
echo_g "Generate crypto configs with $0 done"
en_crypto_artifacts.sh解析:
-a)第一部分:查找func.sh文件位置,找到就引入func.sh文件,并执行,其中func.sh又引入了variables.sh文件
if [ -f ./func.sh ] ; then
source ./func.sh
elif [ -f scripts/func.sh ] ; then
source scripts/func.sh
else
echo "Cannot find the func.sh files, pls check"
exit 1
fi
-b)第二部分:echo_b是func.sh文件中的打印方法,以特定颜色打印` Clean existing container $GEN_CONTAINER` 这一句话,之后删除名为$GEN_CONTAINER 的容器,其中$GEN_CONTAINER 为variables.sh文件的引入量,GEN_CONTAINER= generator
echo_b "Clean existing container $GEN_CONTAINER "
[ "$( docker ps -a | grep $GEN_CONTAINER) " ] && docker rm -f $GEN_CONTAINER
-c)第三部分:判断${CRYPTO_CONFIG} 以及org3/${CRYPTO_CONFIG} 是否为一个目录,不是则将其目录创建。${CRYPTO_CONFIG} 为variables.sh文件的引入量,CRYPTO_CONFIG= crypto-config。
[ ! -d ${CRYPTO_CONFIG} ] && mkdir -p ${CRYPTO_CONFIG}
[ ! -d org3/${CRYPTO_CONFIG} ] && mkdir -p org3/${CRYPTO_CONFIG}
-d)第四部分:以-a将判断条件分为两部分,-a是与判断,这两部分都为true才为true。前半部分判断{
CRYPTO_CONFIG} 是否为一个目录,后半部分使用$( ls -A ${
CRYPTO_CONFIG} ) 获取目录里面的文件数量,再用-a判断目录里是否有文件,综合:判断${CRYPTO_CONFIG} 是否为一个目录且目录里是否有文件,存在且有文件则执行if里的语句,打印` ${
CRYPTO_CONFIG} exists, ignore.` 且执行exit 0 跳出文件,后面的语句都不执行
echo_b "Make sure crypto-config dir exists already"
if [ -d ${CRYPTO_CONFIG} -a ! -z "$( ls -A ${
CRYPTO_CONFIG} ) " ] ; then
echo_b "${CRYPTO_CONFIG} exists, ignore."
exit 0
fi
-e)第五部分:以特定颜色打印` Generating ${
CRYPTO_CONFIG} ` ,并启动docker,启动方式:--rm -it启动后删除;容器名:generator;环境变量:CONFIGTX_LOGGING_LEVEL= DEBUG;使用镜像:yeasy/hyperledger-fabric:2.3.3;容器启动后执行命令:bash /scripts/cryptogen_cryptoArtifacts.sh,执行这个文件
echo_g "Generating ${CRYPTO_CONFIG} ..."
docker run \
--rm -it \
--name ${GEN_CONTAINER} \
-e "CONFIGTX_LOGGING_LEVEL=DEBUG" \
-v $PWD /${CRYPTO_CONFIG} :/tmp/${CRYPTO_CONFIG} \
-v $PWD /crypto-config.yaml:/tmp/crypto-config.yaml \
-v $PWD /org3:/tmp/org3 \
-v $PWD /scripts/cryptogen_cryptoArtifacts.sh:/scripts/cryptogen_cryptoArtifacts.sh \
${GEN_IMG} sh -c 'sleep 1; bash /scripts/cryptogen_cryptoArtifacts.sh'
[ $? -ne 0 ] && exit 1
-f)第六部分:将org3/${CRYPTO_CONFIG} /*下所有文件复制到${CRYPTO_CONFIG} /文件下
echo_b "Copy org3's crypto config outside"
cp -r org3/${CRYPTO_CONFIG} /* ${CRYPTO_CONFIG} /
-g)第七部分:打印这一句话,其中$0 代表本文件名
echo_g "Generate crypto configs with $0 done"
五-1、容器generator解析
容器创建命令,其中GEN_CONTAINER=generator,CRYPTO_CONFIG=crypto-config,GEN_IMG=yeasy/hyperledger-fabric:2.3.3
docker run \
--rm -it \
--name ${GEN_CONTAINER} \
-e "CONFIGTX_LOGGING_LEVEL=DEBUG" \
-v $PWD /${CRYPTO_CONFIG} :/tmp/${CRYPTO_CONFIG} \
-v $PWD /crypto-config.yaml:/tmp/crypto-config.yaml \
-v $PWD /org3:/tmp/org3 \
-v $PWD /scripts/cryptogen_cryptoArtifacts.sh:/scripts/cryptogen_cryptoArtifacts.sh \
${GEN_IMG} sh -c 'sleep 1; bash /scripts/cryptogen_cryptoArtifacts.sh'
更改后,命令:
docker run \
--rm -it \
--name generator \
-e "CONFIGTX_LOGGING_LEVEL=DEBUG" \
-v $PWD /crypto-config:/tmp/crypto-config \
-v $PWD /crypto-config.yaml:/tmp/crypto-config.yaml \
-v $PWD /org3:/tmp/org3 \
-v $PWD /scripts/cryptogen_cryptoArtifacts.sh:/scripts/cryptogen_cryptoArtifacts.sh \
yeasy/hyperledger-fabric:2.3.3 \
sh -c 'sleep 1; bash /scripts/cryptogen_cryptoArtifacts.sh'
/scripts/cryptogen_cryptoArtifacts.sh文件原文
#!/usr/bin/env bash
cd /tmp
CRYPTO_CONFIG = crypto-config
echo "Generating crypto-config for org1 and org2..."
ls -l ${CRYPTO_CONFIG}
cryptogen generate \
--config= crypto-config.yaml \
--output ${CRYPTO_CONFIG}
if [ $? -ne 0 ] ; then
echo "Failed to generate certificates for org1 and org2..."
exit 1
fi
echo "Generating crypto-config for org3..."
cryptogen generate \
--config= org3/crypto-config.yaml \
--output org3/${CRYPTO_CONFIG}
if [ $? -ne 0 ] ; then
echo_r "Failed to generate certificates for org3..."
exit 1
fi
echo "Generated credential files and saved to ${CRYPTO_CONFIG} ."
/scripts/cryptogen_cryptoArtifacts.sh文件解析: -a)使用命令:cd /tmp
进入到tmp目录,因为容器将文件挂载到此目录 -b)使用命令:cryptogen generate --config=crypto-config.yaml --output crypto-config
创建相应组织的证书信息,并将创建的文件放入/tmp/crypto-config
目录下 -c)使用if判断if [ $? -ne 0 ]
判断cryptogen命令施行后的输出结构是否为空,为空则打印创建失败
crypto-config.yaml文件原文
OrdererOrgs:
- Name: Orderer
Domain: example.com
EnableNodeOUs: true
CA:
Country: US
Province: California
Locality: San Francisco
Specs:
- Hostname: orderer0
- Hostname: orderer1
- Hostname: orderer2
- Hostname: orderer3
PeerOrgs:
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
CA:
Country: US
Province: California
Locality: San Francisco
Template:
Count: 2
Users:
Count: 1
- Name: Org2
Domain: org2.example.com
EnableNodeOUs: true
CA:
Country: US
Province: California
Locality: San Francisco
Template:
Count: 2
Users:
Count: 1
- Name: Org3
Domain: org3.example.com
EnableNodeOUs: true
CA:
Country: US
Province: California
Locality: San Francisco
Template:
Count: 2
Users:
Count: 1
crypto-config.yaml文件解析 -a)定义了orderer排序节点,Specs字段定义了有4个排序节点 -b)定义了三个组织:org1,org2,org3,且每个组织里的Users字段都设置为1,表明每个组织里只有一个用户
六、makefile中gen_config_channel部分
makefile中gen_config_channel部分原文
gen_config_channel:
bash scripts/gen_channel_artifacts.sh ${HLF_MODE}
akefile中gen_config_channel部分解析:运行scripts/gen_channel_artifacts.sh文件,且传入参数${HLF_MODE}=raft
scripts/gen_channel_artifacts.sh文件原文
#! /bin/bash
if [ -f ./func.sh ] ; then
source ./func.sh
elif [ -f scripts/func.sh ] ; then
source scripts/func.sh
else
echo "Cannot find the func.sh files, pls check"
exit 1
fi
[ $# -ne 1 ] && echo_r "[Usage] $0 solo|kafka" && exit 1 || MODE = $1
echo_b "Generating channel artifacts with ${GEN_IMG} in mode ${MODE} "
[ ! -d ${MODE} /${CHANNEL_ARTIFACTS} ] && mkdir -p ${MODE} /${CHANNEL_ARTIFACTS}
echo_b "Make sure channel-artifacts dir exists already"
if [ -d ${MODE} /${CHANNEL_ARTIFACTS} -a ! -z "$( ls -A ${
MODE} /${
CHANNEL_ARTIFACTS} ) " ] ; then
echo_b "${CHANNEL_ARTIFACTS} exists, ignore."
exit 0
fi
echo_g "Generating ${CHANNEL_ARTIFACTS} ..."
docker run \
--rm -it \
--name ${GEN_CONTAINER} \
-e "FABRIC_LOGGING_SPEC=common.tools.configtxgen=DEBUG:INFO" \
-v $PWD /${CRYPTO_CONFIG} :/tmp/${CRYPTO_CONFIG} \
-v $PWD /${MODE} /configtx.yaml:/tmp/configtx.yaml \
-v $PWD /${MODE} /${CHANNEL_ARTIFACTS} :/tmp/${CHANNEL_ARTIFACTS} \
-v $PWD /org3:/tmp/org3 \
-v $PWD /scripts/variables.sh:/scripts/variables.sh \
-v $PWD /scripts/configtxgen_channelArtifacts.sh:/scripts/configtxgen_channelArtifacts.sh \
${GEN_IMG} sh -c 'sleep 1; bash /scripts/configtxgen_channelArtifacts.sh'
[ $? -ne 0 ] && exit 1
echo_g "Generate channel artifacts with $0 done"
scripts/gen_channel_artifacts.sh文件解析 -a)引入func.sh文件,func.sh文件又引入了variables.sh文件 -b)将传入参数raft赋值给MODE -c)判断raft/channel-artifacts是否为目录,不存在此目录就创建 -e)判断raft/channel-artifacts目录里是否有文件,有则执行exit 0
退出此shell脚本,后面的容器创建则不执行 -f)创建generator容器
六-1、容器generator解析
创建命令
docker run \
--rm -it \
--name generator \
-e "FABRIC_LOGGING_SPEC=common.tools.configtxgen=DEBUG:INFO" \
-v $PWD /crypto-config:/tmp/crypto-config \
-v $PWD /raft/configtx.yaml:/tmp/configtx.yaml \
-v $PWD /raft/channel-artifacts:/tmp/channel-artifacts \
-v $PWD /org3:/tmp/org3 \
-v $PWD /scripts/variables.sh:/scripts/variables.sh \
-v $PWD /scripts/configtxgen_channelArtifacts.sh:/scripts/configtxgen_channelArtifacts.sh \
yeasy/hyperledger-fabric:2.3.3 \
sh -c 'sleep 1; bash /scripts/configtxgen_channelArtifacts.sh'
/scripts/configtxgen_channelArtifacts.sh文件原文
#!/usr/bin/env bash
if [ -f ./variables.sh ] ; then
source ./variables.sh
elif [ -f /scripts/variables.sh ] ; then
source /scripts/variables.sh
else
echo "Cannot find the variables.sh files, pls check"
exit 1
fi
cd /tmp/${CHANNEL_ARTIFACTS}
echo "Generate genesis block of system channel using configtx.yaml"
[ ! -f ${ORDERER0_GENESIS_BLOCK} ] &&
configtxgen \
-configPath /tmp \
-channelID ${SYS_CHANNEL} \
-profile ${ORDERER_GENESIS_PROFILE} \
-outputBlock ${ORDERER0_GENESIS_BLOCK}
[ ! -f ${ORDERER0_GENESIS_BLOCK} ] && echo "Fail to generate genesis block ${ORDERER0_GENESIS_BLOCK} " && exit 1
cp ${ORDERER0_GENESIS_BLOCK} ${ORDERER1_GENESIS_BLOCK}
cp ${ORDERER0_GENESIS_BLOCK} ${ORDERER2_GENESIS_BLOCK}
echo "Create the new app channel ${APP_CHANNEL} tx using configtx.yaml"
[ ! -f ${APP_CHANNEL_TX} ] &&
configtxgen \
-configPath /tmp \
-profile ${APP_CHANNEL_PROFILE} \
-channelID ${APP_CHANNEL} \
-outputCreateChannelTx ${APP_CHANNEL_TX}
[ ! -f ${APP_CHANNEL_TX} ] && echo "Fail to generate app channel tx file" && exit 1
[ ! -f ${APP_CHANNEL_TX} .json ] &&
configtxgen \
-inspectChannelCreateTx ${APP_CHANNEL_TX} > ${APP_CHANNEL_TX} .json
echo "Create the anchor peer configuration tx for org1 and org2"
[ ! -f ${UPDATE_ANCHOR_ORG1_TX} ] &&
configtxgen \
-configPath /tmp \
-profile ${APP_CHANNEL_PROFILE} \
-channelID ${APP_CHANNEL} \
-asOrg ${ORG1MSP} \
-outputAnchorPeersUpdate ${UPDATE_ANCHOR_ORG1_TX}
[ ! -f ${UPDATE_ANCHOR_ORG1_TX} ] && echo "Fail to generate the anchor update tx for org1" && exit 1
[ ! -f ${UPDATE_ANCHOR_ORG2_TX} ] &&
configtxgen \
-configPath /tmp \
-profile ${APP_CHANNEL_PROFILE} \
-channelID ${APP_CHANNEL} \
-asOrg ${ORG2MSP} \
-outputAnchorPeersUpdate ${UPDATE_ANCHOR_ORG2_TX}
[ ! -f ${UPDATE_ANCHOR_ORG2_TX} ] && echo "Fail to generate the anchor update tx for org1" && exit 1
echo "Output the json for org1, org2 and org3"
declare -a msps = ( "${ORG1MSP} "
"${ORG2MSP} "
"${ORG3MSP} " )
for msp in "${msps[ @] } " ; do
[ ! -f ${msp} .json ] &&
configtxgen \
-configPath /tmp \
-printOrg ${msp} > ${msp} .json
done
/scripts/configtxgen_channelArtifacts.sh文件解析
-a)引入variables.sh文件
if [ -f ./variables.sh ] ; then
source ./variables.sh
elif [ -f /scripts/variables.sh ] ; then
source /scripts/variables.sh
else
echo "Cannot find the variables.sh files, pls check"
exit 1
fi
-b)进入/tmp/channel-artifacts目录
cd /tmp/${CHANNEL_ARTIFACTS}
-c)判断orderer0.genesis.block是否存在,不存在则使用文件/tmp/configtx.yaml以及命令:` configtxgen -configPath /tmp -channelID testchainid -profile TwoOrgsOrdererGenesis -outputBlock orderer0.genesis.block` 进行创建
[ ! -f ${ORDERER0_GENESIS_BLOCK} ] &&
configtxgen \
-configPath /tmp \
-channelID ${SYS_CHANNEL} \
-profile ${ORDERER_GENESIS_PROFILE} \
-outputBlock ${ORDERER0_GENESIS_BLOCK}
[ ! -f ${ORDERER0_GENESIS_BLOCK} ] && echo "Fail to generate genesis block ${ORDERER0_GENESIS_BLOCK} " && exit 1
-d)使用cp命令,利用orderer0.genesis.block,创建orderer1.genesis.block和orderer2.genesis.block
cp ${ORDERER0_GENESIS_BLOCK} ${ORDERER1_GENESIS_BLOCK}
cp ${ORDERER0_GENESIS_BLOCK} ${ORDERER2_GENESIS_BLOCK}
-e)判断businesschannel.tx是否存在,不存在则使用文件/tmp/configtx.yaml以及命令:` configtxgen -configPath /tmp -profile TwoOrgsChannel -channelID businesschannel -outputCreateChannelTx businesschannel.tx` 进行创建
[ ! -f ${APP_CHANNEL_TX} ] && configtxgen -configPath /tmp -profile ${APP_CHANNEL_PROFILE} -channelID ${APP_CHANNEL} -outputCreateChannelTx ${APP_CHANNEL_TX}
-f)判断businesschannel.tx.json是否存在,不存在则使用命令configtxgen -inspectChannelCreateTx businesschannel.tx > businesschannel.tx.json,将businesschannel.tx文件的配置信息以json形式打印在businesschannel.tx.json文件里
[ ! -f ${APP_CHANNEL_TX} .json ] && configtxgen -inspectChannelCreateTx ${APP_CHANNEL_TX} > ${APP_CHANNEL_TX} .json
-g)判断org1的锚节点文件是否存在,若不存在则使用命令创建
[ ! -f ${UPDATE_ANCHOR_ORG1_TX} ] && configtxgen -configPath /tmp -profile ${APP_CHANNEL_PROFILE} -channelID ${APP_CHANNEL} -asOrg ${ORG1MSP} -outputAnchorPeersUpdate ${UPDATE_ANCHOR_ORG1_TX}
-h)判断org2的秒节点文件是否存在,若不存在则使用命令创建
[ ! -f ${UPDATE_ANCHOR_ORG2_TX} ] && configtxgen -configPath /tmp -profile ${APP_CHANNEL_PROFILE} -channelID ${APP_CHANNEL} -asOrg ${ORG2MSP} -outputAnchorPeersUpdate ${UPDATE_ANCHOR_ORG2_TX}
七、makefile中start部分
makefile中start部分原文
start:
@echo "Start a fabric network with ${COMPOSE_FILE} ..."
@make clean
@echo "Make sure the local hlf_net docker bridge exists"
docker network ls | grep hlf_net > /dev/null || docker network create hlf_net
@docker-compose -f ${COMPOSE_FILE} up -d
makefile中start部分解析 -a)打印Start a fabric network with ${COMPOSE_FILE}...
,其中COMPOSE_FILE=docker-compose-2orgs-4peers-raft.yaml -b)执行clean部分 -c)打印Make sure the local hlf_net docker bridge exists
-d)判断docker网络是否有hlf_net,没有则创建hlf_net的docker网络 -e)使用文件docker-compose-2orgs-4peers-raft.yaml启动docker-compose
八、makefile中channel_test部分
makefile中channel_test部分原文
channel_test: test_channel_create test_channel_join test_channel_list test_channel_getinfo
makefile中channel_test部分解析:执行test_channel_create,test_channel_join,test_channel_list,test_channel_getinfo四部分
八-1、makefile中test_channel_create部分
makefile中test_channel_create部分原文
test_channel_create:
@echo "Create channel on the fabric network"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_create.sh"
解析 -a)打印Create channel on the fabric network
-b)使用cli容器执行命令:cd /tmp; bash scripts/test_channel_create.sh
,进入到/tmp目录下,执行test_channel_create.sh文件
test_channel_create.sh文件原文
#!/bin/bash
if [ -f ./func.sh ] ; then
source ./func.sh
elif [ -f scripts/func.sh ] ; then
source scripts/func.sh
fi
echo_b "=== Creating channel ${APP_CHANNEL} with ${APP_CHANNEL_TX} ... ==="
channelCreate "${APP_CHANNEL} " "${APP_CHANNEL_TX} " 1 0 ${ORDERER0_URL} ${ORDERER0_TLS_ROOTCERT}
echo_g "=== Created channel ${APP_CHANNEL} with ${APP_CHANNEL_TX} ==="
echo
test_channel_create.sh文件解析,使用channelCreate
函数,来源func.sh,传入参数:businesschannel,businesschannel.tx,1,0,orderer0.example.com:7050,/etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/ca.crt
最终执行
peer channel create \
-c ${channel} \
-o ${orderer_url} \
-f ${CHANNEL_ARTIFACTS} /${channel_tx} \
--timeout "${TIMEOUT} s" \
--tls \
--cafile ${orderer_tls_rootcert}
参数填充,最终执行
peer channel create -c businesschannel -o orderer0.example.com:7050 -f channel-artifacts/businesschannel.tx --timeout "90s" --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/ca.crt
九、makefile中test_channel_list部分
原文
test_channel_list:
@echo "List the joined channels"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_list.sh"
解析:进入cli容器,执行/tmp目录下的scripts/test_channel_list.sh文件
scripts/test_channel_list.sh文件原文
#!/bin/bash
if [ -f ./func.sh ] ; then
source ./func.sh
elif [ -f scripts/func.sh ] ; then
source scripts/func.sh
fi
echo_b "=== Listing joined channels... ==="
for org in "${ORGS[ @] } " ; do
for peer in "${PEERS[ @] } " ; do
channelList $org $peer
done
done
echo_g "=== Done listing joined channels ==="
echo
scripts/test_channel_list.sh文件解析,for循环中,第一层遍历变量ORGS中的值,其中ORGS=(1 2);第二层遍历PEER中的值,其中PEERS=(0 1),遍历后执行func.sh中的channelList函数
channelList函数原文
channelList ( ) {
local org = $1
local peer = $2
echo "=== List the channels that org${org} /peer${peer} joined === "
setEnvs $org $peer
peer channel list >& log.txt
rc = $?
[ $rc -ne 0 ] && cat log.txt
if [ $rc -ne 0 ] ; then
echo "=== Failed to list the channels that org${org} /peer${peer} joined === "
else
echo "=== Done to list the channels that org${org} /peer${peer} joined === "
fi
}
通过函数setEnvs设置cli使用的证书,之后使用peer channel list
,依据环境变量中设置的证书去向peer节点查询相应节点加入的channel情况
十、makefile中test_channel_getinfo部分
makefile中test_channel_getinfo原文
test_channel_getinfo:
@echo "Get info of the app channel"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_getinfo.sh"
解析:进入cli容器,执行/tmp目录下的test_channel_getinfo.sh文件
test_channel_getinfo.sh文件原文
#!/bin/bash
if [ -f ./func.sh ] ; then
source ./func.sh
elif [ -f scripts/func.sh ] ; then
source scripts/func.sh
fi
echo_b "=== Getting info of channel ${APP_CHANNEL} ... ==="
for org in "${ORGS[ @] } " ; do
for peer in "${PEERS[ @] } " ; do
channelGetInfo ${APP_CHANNEL} $org $peer
done
done
echo_g "=== Get info of channel ${APP_CHANNEL} Complete ==="
echo
test_channel_getinfo.sh文件解析:第一层遍历ORGS=(1 2),第二层遍历PEERS=(0 1),执行func.sh里的channelGetInfo
channelGetInfo函数,根据遍历的数字,通过函数setEnvs设置环境变量使用的证书,再使用命令peer channel getinfo -c businesschannel
查询channel信息
十一、makefile中update_anchors部分
makefile中update_anchors原文
update_anchors:
@echo "Update anchors on the fabric network"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_update_anchors.sh"
makefile中update_anchors解析:进入cli容器,执行test_update_anchors.sh文件
test_update_anchors.sh文件原文
#!/bin/bash
if [ -f ./func.sh ] ; then
source ./func.sh
elif [ -f scripts/func.sh ] ; then
source scripts/func.sh
fi
echo_b "=== Updating anchor peers to peer0 for org1... ==="
channelUpdate ${APP_CHANNEL} 1 0 ${ORDERER0_URL} ${ORDERER0_TLS_ROOTCERT} Org1MSPanchors.tx
echo_b "=== Updating anchor peers to peer0 for org2... ==="
channelUpdate ${APP_CHANNEL} 2 0 ${ORDERER0_URL} ${ORDERER0_TLS_ROOTCERT} Org2MSPanchors.tx
echo_b "=== Updated anchor peers ==="
echo
test_update_anchors.sh文件解析:使用func.sh文件的channelUpdate,传入参数,最终执行peer channel update
命令
十二、makefile中cc_test部分
makefile中cc_test原文
cc_test: test_cc_install test_cc_queryinstalled test_cc_approveformyorg test_cc_queryapproved test_cc_checkcommitreadiness test_cc_commit test_cc_querycommitted test_cc_invoke_query
十三、makefile中test_cc_install部分
makefile中test_cc_install原文
test_cc_install:
@echo "Install chaincode to all peers"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_install.sh"
makefile中test_cc_install解析:进入cli容器,执行test_cc_install.sh文件
test_cc_install.sh文件原文
#!/bin/bash
if [ -f ./func.sh ] ; then
source ./func.sh
elif [ -f scripts/func.sh ] ; then
source scripts/func.sh
fi
CC_NAME = ${CC_NAME:- $CC_02_NAME}
CC_PATH = ${CC_PATH:- $CC_02_PATH}
echo_b "=== Installing chaincode ${CC_NAME} on all 4 peers... ==="
for org in "${ORGS[ @] } " ; do
for peer in "${PEERS[ @] } " ; do
t = "\${ORG${org} _PEER${peer} _URL}" && peer_url = $( eval echo $t)
t = "\${ORG${org} _PEER${peer} _TLS_ROOTCERT}" && peer_tls_rootcert = $( eval echo $t)
chaincodeInstall $org $peer "${peer_url} " "${peer_tls_rootcert} " ${CC_NAME} ${CC_INIT_VERSION} ${GOPATH} /src/${CC_PATH}
done
done
echo_g "=== Install chaincode done ==="
echo
test_cc_install.sh文件解析 -a)设置CC_NAME=exp02;CC_PATH=chaincodes/go/chaincode_example02 -b)遍历组织ORGS=(1 2),节点PEERS=(0 1),设置变量值peer_url,以及peer_tls_rootcert -c)调用func.sh文件里的chaincodeInstall方法,使用命令peer lifecycle chaincode package
以及peer lifecycle chaincode install
将指定链码打包后安装到指定节点
十四、makefile中test_cc_queryinstalled部分
makefile中test_cc_queryinstalled原文
test_cc_queryinstalled:
@echo "Query the installed chaincode"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_queryinstalled.sh"
makefile中test_cc_queryinstalled解析:进入cli容器,执行test_cc_queryinstalled.sh文件
test_cc_queryinstalled.sh文件原文
#!/bin/bash
if [ -f ./func.sh ] ; then
source ./func.sh
elif [ -f scripts/func.sh ] ; then
source scripts/func.sh
fi
echo_b "=== Query Chaincode installed on all organizations ... ==="
for org in "${ORGS[ @] } " ; do
t = "\${ORG${org} _PEER0_URL}" && peer_url = $( eval echo $t)
t = "\${ORG${org} _PEER0_TLS_ROOTCERT}" && peer_tls_rootcert = $( eval echo $t)
chaincodeQueryInstalled "$org " 0 ${peer_url} ${peer_tls_rootcert}
done
echo_g "=== Query Chaincode installed status done ==="
echo
test_cc_queryinstalled.sh文件解析:遍历组织ORGS=(1 2),设置变量值peer_url和peer_tls_rootcert,再执行func.sh文件中的chaincodeQueryInstalled方法,使用命令peer lifecycle chaincode queryinstalled
查询链码安装情况
十五、makefile中test_cc_approveformyorg部分
makefile中test_cc_approveformyorg原文
test_cc_approveformyorg:
@echo "Approve the chaincode by all orgs"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_approveformyorg.sh"
makefile中test_cc_approveformyorg解析:进入cli客户机,执行test_cc_approveformyorg.sh文件