第四节——解析makefile

一、解析makefile文件

  1. makefike文件原文:
# Makefile to bootup the network, and do testing with channel, chaincode
# Run `make test` will pass all testing cases, and delete the network
# Run `make ready` will create a network, pass testing cases, and stand there for manual test, e.g., make test_channel_list


# support advanced bash grammar
SHELL:=/bin/bash

# mode of the network: raft only for 2.x
HLF_MODE ?= raft

# mode of db: golevel, couchdb
DB_MODE ?= golevel

# mode of dev
DEV_MODE ?= non-dev

NETWORK_INIT_WAIT ?= 2 # time to wait the fabric network finish initialization

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  # Run all testing till ready

	make stop clean

ready: # create/join channel, install/instantiate cc
	make stop

	# make clean_config_channel # Remove existing channel artifacts
	make gen_config_crypto  # Will ignore if local config path exists
	make gen_config_channel  # Will ignore if local config path exists

	make start

	sleep ${NETWORK_INIT_WAIT}

	make channel_test

	make update_anchors

	make cc_test # test_cc_install test_cc_approveformyorg test_cc_checkcommitreadiness test_cc_commit test_cc_querycommitted test_cc_invoke_query

	# make test_lscc # test lscc operations, in v2.0, legacy lscc won't work
	make test_qscc # test qscc operations
	make test_cscc # test cscc operations

	make test_fetch_blocks # fetch block files

	make test_gen_add_org3_tx
	make test_channel_update

	make test_fetch_blocks # fetch block files again
	make test_configtxlator

	make test_channel_list
	make test_channel_getinfo

	# make logs_save

	@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 related operations
channel_test: test_channel_create test_channel_join test_channel_list test_channel_getinfo

# chaincode related operations
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: # bootup the fabric network
	@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  # Start a fabric network

stop: # stop the fabric network
	@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

################## Channel testing operations ################

test_channel_list: # List the channel that peer joined
	@echo "List the joined channels"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_list.sh"

test_channel_getinfo: # Get info of a channel
	@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: # Init the channel
	@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: # Init the channel
	@echo "Join channel"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_join.sh"

update_anchors: # Update the anchor peer
	@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: # send the channel update transaction
	@echo "Test channel update with adding new org"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_update.sh"

################## Configtxlator testing operations ################
test_configtxlator: # Test change config using 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: # Test change config to add new org
	bash scripts/test_gen_add_org3_tx.sh ${HLF_MODE}

################## Chaincode testing operations ################
test_cc: # test chaincode, deprecated
	if [ "$(HLF_MODE)" = "dev" ]; then \
			make test_cc_peer0; \
	else \
			make test_cc_invoke_query; \
	fi

test_cc_install: # Install the chaincode
	@echo "Install chaincode to all peers"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_install.sh"

test_cc_queryinstalled: # Query the installed chaincodes
	@echo "Query the installed chaincode"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_queryinstalled.sh"

test_cc_getinstalled: # Get the installed chaincodes package
	@echo "Get the installed chaincode package"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_getinstalled.sh"

test_cc_approveformyorg: # Approve the chaincode definition
	@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: # Query the approved chaincode definition
	@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: # Query the approval status of chaincode
	@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: # Commit the chaincode definition
	@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: # Query the commit status of the chaincode definition
	@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: # Instantiate the chaincode
	@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: # Upgrade the chaincode
	@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: # List the chaincode
	@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: # test user chaincode on all peers
	@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: # test cscc queries
	@echo "Test CSCC query"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cscc.sh"

test_qscc: # test qscc queries
	@echo "Test QSCC query"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_qscc.sh"

test_lscc: # test lscc quries
	@echo "Test LSCC query"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_lscc.sh"

# FIXME: docker doesn't support wildcard in cp right now
test_fetch_blocks: # test fetching channel blocks fetch
	@echo "Test fetching block files"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_fetch_blocks.sh"

test_eventsclient: # test get event notification in a loop
	@echo "Test fetching event notification"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/start_eventsclient.sh"

test_sidedb: # test sideDB/private data feature
	@echo "Test sideDB"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_sideDB.sh"

temp: # test temp instructions, used for experiment
	@echo "Test experimental instructions"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_temp.sh"

################## Env setup related, no need to see usually ################

setup: # setup the environment
	bash scripts/env_setup.sh # Installing Docker and Docker-Compose

check: # Check shell scripts grammar
	@echo "Check shell scripts grammar"
	[ `which shellcheck` ] && shellcheck scripts/*.sh

clean: # clean up containers and chaincode images
	@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"

# Clean deeply by removing all generated files: container, artifacts, credentials
purge: clean
	HLF_MODE=raft make clean_config_channel
	make clean_config_crypto

env_clean: # clean up Docker environment
	@echo "Clean all images and containers"
	bash scripts/env_clean.sh

cli: # enter the cli container
	docker exec -it fabric-cli bash

orderer: orderer0

orderer0: # enter the orderer0 container
	docker exec -it orderer0.example.com bash

orderer1: # enter the orderer0 container
	docker exec -it orderer1.example.com bash

peer: peer0

peer0: # enter the peer container
	docker exec -it peer0.org1.example.com bash

peer1: # enter the peer container
	docker exec -it peer1.org1.example.com bash

ps: # show existing docker images
	docker ps -a

logs: # show logs
	docker-compose -f ${COMPOSE_FILE} logs -f --tail 200

logs_check: logs_save logs_view

logs_save: # save logs
	@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: # view logs
	less $(LOG_PATH)/dev_peer.log

elk: # insert logs into elk
	# curl -XDELETE http://localhost:9200/logstash-\*
	nc localhost 5000 < $(LOG_PATH)/dev_all.log

gen_config_crypto: # generate crypto config
	bash scripts/gen_crypto_artifacts.sh

gen_config_channel: # generate channel artifacts
	bash scripts/gen_channel_artifacts.sh ${HLF_MODE}

clean_config_channel: # clean channel related artifacts
	rm -rf ${HLF_MODE}/channel-artifacts/*

clean_config_crypto: # clean config artifacts
	echo "Warning: Cleaning credentials will affect artifacts in raft mode"
	rm -rf crypto-config/*
	rm -rf org3/crypto-config/*

download: # download required images
	@echo "Download Docker images"
	bash scripts/download_images.sh

################## chaincode dev mode ################
chaincode_init: # start chaincode in dev mode and do install/instantiate
	@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"

  1. 第一部分:SHELL:=/bin/bash命令解析:引入shell执行环境,可以在makefile中使用shell命令,如echo
  2. 第二部分:使用?=形式赋值,若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"
  1. 第四部分:打印两句话,之后使用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  # Run all testing till ready

	make stop clean

二、makefile中setup部分

  1. makefile中setup原文
setup: # setup the environment
	bash scripts/env_setup.sh # Installing Docker and Docker-Compose
  1. 解析:执行scripts/env_setup.sh文件
  2. scripts/env_setup.sh原文
#!/usr/bin/env bash

# Install docker on Ubuntu/Debian system

install_docker() {
    
    
  echo "Install Docker..."
  wget -qO- https://get.docker.com/ | sh
  sudo service docker stop
  #nohup sudo docker daemon --api-cors-header="*" -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock&
  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

  1. 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部分

  1. makefile中ready原文
ready: # create/join channel, install/instantiate cc
	make stop

	# make clean_config_channel # Remove existing channel artifacts
	make gen_config_crypto  # Will ignore if local config path exists
	make gen_config_channel  # Will ignore if local config path exists

	make start

	sleep ${NETWORK_INIT_WAIT}

	make channel_test

	make update_anchors

	make cc_test # test_cc_install test_cc_approveformyorg test_cc_checkcommitreadiness test_cc_commit test_cc_querycommitted test_cc_invoke_query

	# make test_lscc # test lscc operations, in v2.0, legacy lscc won't work
	make test_qscc # test qscc operations
	make test_cscc # test cscc operations

	make test_fetch_blocks # fetch block files

	make test_gen_add_org3_tx
	make test_channel_update

	make test_fetch_blocks # fetch block files again
	make test_configtxlator

	make test_channel_list
	make test_channel_getinfo

	# make logs_save

	@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."
  1. 解析:执行stop,gen_config_crypto,gen_config_channel,start部分后,暂停${NETWORK_INIT_WAIT}秒,由于这里使用的是raft,所以暂停5s后,再执行下面的部分

四、makefile中stop部分

  1. makefile中stop部分原文
stop: # stop the fabric network
	@echo "Stop the fabric network with ${COMPOSE_FILE}..."
	@docker-compose -f ${COMPOSE_FILE} down >& /tmp/docker-compose.log
  1. 解析:
    -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部分

  1. makefile中gen_config_crypto部分原文
gen_config_crypto: # generate crypto config
	bash scripts/gen_crypto_artifacts.sh
  1. makefile中gen_config_crypto部分解析:执行scripts/gen_crypto_artifacts.sh文件
  2. scripts/gen_crypto_artifacts.sh文件原文
#! /bin/bash
# Generating
#  * crypto-config/*

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 # No need to regen
  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"
  1. 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 # No need to regen
  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解析

  1. 容器创建命令,其中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'
  1. /scripts/cryptogen_cryptoArtifacts.sh文件原文
#!/usr/bin/env bash

# use /tmp/crypto-config.yaml to generate /tmp/crypto-config
# use /tmp/org3/crypto-config.yaml to generate /tmp/org3/crypto-config

cd /tmp # we use /tmp as the base working path

# The crypto-config will be used by channel artifacts generation later
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}

#cryptogen extend \
#	--input ${CRYPTO_CONFIG} \
#	--config=crypto-config.yaml

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}."
  1. /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命令施行后的输出结构是否为空,为空则打印创建失败
  2. 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
  1. crypto-config.yaml文件解析
    -a)定义了orderer排序节点,Specs字段定义了有4个排序节点
    -b)定义了三个组织:org1,org2,org3,且每个组织里的Users字段都设置为1,表明每个组织里只有一个用户

六、makefile中gen_config_channel部分

  1. makefile中gen_config_channel部分原文
gen_config_channel: # generate channel artifacts
	bash scripts/gen_channel_artifacts.sh ${HLF_MODE}
  1. akefile中gen_config_channel部分解析:运行scripts/gen_channel_artifacts.sh文件,且传入参数${HLF_MODE}=raft
  2. scripts/gen_channel_artifacts.sh文件原文
#! /bin/bash
# Generating
#  * channel-artifacts
#    * orderer.genesis.block
#    * channel.tx
#    * Org1MSPanchors.tx
#    * Org2MSPanchors.tx

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"

  1. 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解析

  1. 创建命令
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'
  1. /scripts/configtxgen_channelArtifacts.sh文件原文
#!/usr/bin/env bash

# Use ${FABRIC_CFG_PATH}/configtx.yaml to generate following materials,
# and put under /tmp/$CHANNEL_ARTIFACTS:
# system channel genesis block
# new app channel tx
# update anchor peer tx

# Define those global variables
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} # all generated materials will be put under /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}

#for (( i=1; i<150; i++ ));
#do
#APP_CHANNEL="channel"$i
#APP_CHANNEL_TX=${APP_CHANNEL}".tx"
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
#done

[ ! -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

  1. /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部分

  1. makefile中start部分原文
start: # bootup the fabric network
	@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  # Start a fabric network
  1. 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部分

  1. makefile中channel_test部分原文
channel_test: test_channel_create test_channel_join test_channel_list test_channel_getinfo
  1. makefile中channel_test部分解析:执行test_channel_create,test_channel_join,test_channel_list,test_channel_getinfo四部分

八-1、makefile中test_channel_create部分

  1. makefile中test_channel_create部分原文
test_channel_create: # Init the channel
	@echo "Create channel on the fabric network"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_create.sh"
  1. 解析
    -a)打印Create channel on the fabric network
    -b)使用cli容器执行命令:cd /tmp; bash scripts/test_channel_create.sh,进入到/tmp目录下,执行test_channel_create.sh文件
  2. test_channel_create.sh文件原文
#!/bin/bash

# Importing useful functions for cc testing
if [ -f ./func.sh ]; then
  source ./func.sh
elif [ -f scripts/func.sh ]; then
  source scripts/func.sh
fi

## Create channel
echo_b "=== Creating channel ${APP_CHANNEL} with ${APP_CHANNEL_TX}... ==="

#for (( i=1; i<150; i++ ));
#do
#APP_CHANNEL="channel"$i
#APP_CHANNEL_TX=${APP_CHANNEL}".tx"
channelCreate "${APP_CHANNEL}" "${APP_CHANNEL_TX}" 1 0 ${ORDERER0_URL} ${ORDERER0_TLS_ROOTCERT}
#done

echo_g "=== Created channel ${APP_CHANNEL} with ${APP_CHANNEL_TX} ==="

echo

  1. 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
  2. 最终执行
peer channel create \
      -c ${channel} \
      -o ${orderer_url} \
      -f ${CHANNEL_ARTIFACTS}/${channel_tx} \
      --timeout "${TIMEOUT}s" \
      --tls \
      --cafile ${orderer_tls_rootcert}
  1. 参数填充,最终执行
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部分

  1. 原文
test_channel_list: # List the channel that peer joined
	@echo "List the joined channels"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_list.sh"
  1. 解析:进入cli容器,执行/tmp目录下的scripts/test_channel_list.sh文件
  2. scripts/test_channel_list.sh文件原文
#!/bin/bash

# Importing useful functions for cc testing
if [ -f ./func.sh ]; then
  source ./func.sh
elif [ -f scripts/func.sh ]; then
  source scripts/func.sh
fi

## Create channel
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

  1. scripts/test_channel_list.sh文件解析,for循环中,第一层遍历变量ORGS中的值,其中ORGS=(1 2);第二层遍历PEER中的值,其中PEERS=(0 1),遍历后执行func.sh中的channelList函数
  2. 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
}
  1. 通过函数setEnvs设置cli使用的证书,之后使用peer channel list,依据环境变量中设置的证书去向peer节点查询相应节点加入的channel情况

十、makefile中test_channel_getinfo部分

  1. makefile中test_channel_getinfo原文
test_channel_getinfo: # Get info of a channel
	@echo "Get info of the app channel"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_getinfo.sh"
  1. 解析:进入cli容器,执行/tmp目录下的test_channel_getinfo.sh文件
  2. test_channel_getinfo.sh文件原文
#!/bin/bash

# Importing useful functions for cc testing
if [ -f ./func.sh ]; then
  source ./func.sh
elif [ -f scripts/func.sh ]; then
  source scripts/func.sh
fi

## Join all the peers to the channel
echo_b "=== Getting info of channel ${APP_CHANNEL}... ==="

#set -x

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

  1. test_channel_getinfo.sh文件解析:第一层遍历ORGS=(1 2),第二层遍历PEERS=(0 1),执行func.sh里的channelGetInfo
  2. channelGetInfo函数,根据遍历的数字,通过函数setEnvs设置环境变量使用的证书,再使用命令peer channel getinfo -c businesschannel查询channel信息

十一、makefile中update_anchors部分

  1. makefile中update_anchors原文
update_anchors: # Update the anchor peer
	@echo "Update anchors on the fabric network"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_update_anchors.sh"
  1. makefile中update_anchors解析:进入cli容器,执行test_update_anchors.sh文件
  2. test_update_anchors.sh文件原文
#!/bin/bash

# Importing useful functions for cc testing
if [ -f ./func.sh ]; then
  source ./func.sh
elif [ -f scripts/func.sh ]; then
  source scripts/func.sh
fi

## Set the anchor peers for each org in the channel
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

  1. test_update_anchors.sh文件解析:使用func.sh文件的channelUpdate,传入参数,最终执行peer channel update命令

十二、makefile中cc_test部分

  1. 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部分

  1. makefile中test_cc_install原文
test_cc_install: # Install the chaincode
	@echo "Install chaincode to all peers"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_install.sh"
  1. makefile中test_cc_install解析:进入cli容器,执行test_cc_install.sh文件
  2. test_cc_install.sh文件原文
#!/bin/bash

# Importing useful functions for cc testing
if [ -f ./func.sh ]; then
  source ./func.sh
elif [ -f scripts/func.sh ]; then
  source scripts/func.sh
fi

## Install chaincode on all peers
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} # with go 1.14, we cannot use import path with module, see FAB-17924
  done
done

echo_g "=== Install chaincode done ==="

echo

  1. 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部分

  1. makefile中test_cc_queryinstalled原文
test_cc_queryinstalled: # Query the installed chaincodes
	@echo "Query the installed chaincode"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_queryinstalled.sh"
  1. makefile中test_cc_queryinstalled解析:进入cli容器,执行test_cc_queryinstalled.sh文件
  2. test_cc_queryinstalled.sh文件原文
#!/bin/bash

# Importing useful functions for cc testing
if [ -f ./func.sh ]; then
  source ./func.sh
elif [ -f scripts/func.sh ]; then
  source scripts/func.sh
fi

## Query the installed chaincode on all peers
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

  1. test_cc_queryinstalled.sh文件解析:遍历组织ORGS=(1 2),设置变量值peer_url和peer_tls_rootcert,再执行func.sh文件中的chaincodeQueryInstalled方法,使用命令peer lifecycle chaincode queryinstalled查询链码安装情况

十五、makefile中test_cc_approveformyorg部分

  1. makefile中test_cc_approveformyorg原文
test_cc_approveformyorg: # Approve the chaincode definition
	@echo "Approve the chaincode by all orgs"
	@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_approveformyorg.sh"
  1. makefile中test_cc_approveformyorg解析:进入cli客户机,执行test_cc_approveformyorg.sh文件

猜你喜欢

转载自blog.csdn.net/qq_37589805/article/details/121848278