[Blockchain] Hyperledger Fabric: network.sh
포스트 난이도: HOO_Senior
# fabric-samples v2.5
If you're venturing into the world of Hyperledger Fabric, understanding the core components of a smart contract is essential. In this post, we’ll break down the key functions within the network.sh file.
https://github.com/hyperledger/fabric
When you first explore Hyperledger Fabric, you'll encounter the test network folder and the network.sh script, which helps generate your first blockchain network. This simple test network is not just for study—it's practical for developing and testing applications. With two organizations, Org1 and Org2, the test network is ideal for building prototypes. Here's a quick look at the key functions of network.sh to help you understand it better.
# clearContainers()
function clearContainers() {
infoln "Removing remaining containers"
${CONTAINER_CLI} rm -f $(${CONTAINER_CLI} ps -aq --filter label=service=hyperledger-fabric) 2>/dev/null || true
${CONTAINER_CLI} rm -f $(${CONTAINER_CLI} ps -aq --filter name='dev-peer*') 2>/dev/null || true
${CONTAINER_CLI} kill "$(${CONTAINER_CLI} ps -q --filter name=ccaas)" 2>/dev/null || true
}
- Stops and removes all Docker containers related to the Fabric network.
- When bringing down the network, this function ensures no containers are left running.
# removeUnwantedImages()
function removeUnwantedImages() {
infoln "Removing generated chaincode docker images"
${CONTAINER_CLI} image rm -f $(${CONTAINER_CLI} images -aq --filter reference='dev-peer*') 2>/dev/null || true
}
- Removes Docker images generated for chaincode containers, which are often left behind.
- Helps clean up the environment when tearing down the network.
# checkPrereqs()
function checkPrereqs() {
## Check if your have cloned the peer binaries and configuration files.
peer version > /dev/null 2>&1
if [[ $? -ne 0 || ! -d "../config" ]]; then
errorln "Peer binary and configuration files not found.."
errorln
errorln "Follow the instructions in the Fabric docs to install the Fabric Binaries:"
errorln "https://hyperledger-fabric.readthedocs.io/en/latest/install.html"
exit 1
fi
# use the fabric peer container to see if the samples and binaries match your
# docker images
LOCAL_VERSION=$(peer version | sed -ne 's/^ Version: //p')
DOCKER_IMAGE_VERSION=$(${CONTAINER_CLI} run --rm hyperledger/fabric-peer:latest peer version | sed -ne 's/^ Version: //p')
infoln "LOCAL_VERSION=$LOCAL_VERSION"
infoln "DOCKER_IMAGE_VERSION=$DOCKER_IMAGE_VERSION"
if [ "$LOCAL_VERSION" != "$DOCKER_IMAGE_VERSION" ]; then
warnln "Local fabric binaries and docker images are out of sync. This may cause problems."
fi
for UNSUPPORTED_VERSION in $NONWORKING_VERSIONS; do
infoln "$LOCAL_VERSION" | grep -q $UNSUPPORTED_VERSION
if [ $? -eq 0 ]; then
fatalln "Local Fabric binary version of $LOCAL_VERSION does not match the versions supported by the test network."
fi
infoln "$DOCKER_IMAGE_VERSION" | grep -q $UNSUPPORTED_VERSION
if [ $? -eq 0 ]; then
fatalln "Fabric Docker image version of $DOCKER_IMAGE_VERSION does not match the versions supported by the test network."
fi
done
## check for cfssl binaries
if [ "$CRYPTO" == "cfssl" ]; then
cfssl version > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
errorln "cfssl binary not found.."
errorln
errorln "Follow the instructions to install the cfssl and cfssljson binaries:"
errorln "https://github.com/cloudflare/cfssl#installation"
exit 1
fi
fi
## Check for fabric-ca
if [ "$CRYPTO" == "Certificate Authorities" ]; then
fabric-ca-client version > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
errorln "fabric-ca-client binary not found.."
errorln
errorln "Follow the instructions in the Fabric docs to install the Fabric Binaries:"
errorln "https://hyperledger-fabric.readthedocs.io/en/latest/install.html"
exit 1
fi
CA_LOCAL_VERSION=$(fabric-ca-client version | sed -ne 's/ Version: //p')
CA_DOCKER_IMAGE_VERSION=$(${CONTAINER_CLI} run --rm hyperledger/fabric-ca:latest fabric-ca-client version | sed -ne 's/ Version: //p' | head -1)
infoln "CA_LOCAL_VERSION=$CA_LOCAL_VERSION"
infoln "CA_DOCKER_IMAGE_VERSION=$CA_DOCKER_IMAGE_VERSION"
if [ "$CA_LOCAL_VERSION" != "$CA_DOCKER_IMAGE_VERSION" ]; then
warnln "Local fabric-ca binaries and docker images are out of sync. This may cause problems."
fi
fi
}
- Checks if the required Hyperledger Fabric binaries and Docker images are available and match the expected versions.
- Ensures that the local environment is set up correctly before the network starts. If versions mismatch, it will issue a warning (If you want to follow my version setup, you can check out this post: https://whoishoo.tistory.com/745)
# createOrgs()
function createOrgs() {
if [ -d "organizations/peerOrganizations" ]; then
rm -Rf organizations/peerOrganizations && rm -Rf organizations/ordererOrganizations
fi
# Create crypto material using cryptogen
if [ "$CRYPTO" == "cryptogen" ]; then
which cryptogen
if [ "$?" -ne 0 ]; then
fatalln "cryptogen tool not found. exiting"
fi
infoln "Generating certificates using cryptogen tool"
infoln "Creating Org1 Identities"
set -x
cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output="organizations"
res=$?
{ set +x; } 2>/dev/null
if [ $res -ne 0 ]; then
fatalln "Failed to generate certificates..."
fi
infoln "Creating Org2 Identities"
set -x
cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output="organizations"
res=$?
{ set +x; } 2>/dev/null
if [ $res -ne 0 ]; then
fatalln "Failed to generate certificates..."
fi
infoln "Creating Orderer Org Identities"
set -x
cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output="organizations"
res=$?
{ set +x; } 2>/dev/null
if [ $res -ne 0 ]; then
fatalln "Failed to generate certificates..."
fi
fi
# Create crypto material using cfssl
if [ "$CRYPTO" == "cfssl" ]; then
. organizations/cfssl/registerEnroll.sh
#function_name cert-type CN org
peer_cert peer peer0.org1.example.com org1
peer_cert admin Admin@org1.example.com org1
infoln "Creating Org2 Identities"
#function_name cert-type CN org
peer_cert peer peer0.org2.example.com org2
peer_cert admin Admin@org2.example.com org2
infoln "Creating Orderer Org Identities"
#function_name cert-type CN
orderer_cert orderer orderer.example.com
orderer_cert admin Admin@example.com
fi
# Create crypto material using Fabric CA
if [ "$CRYPTO" == "Certificate Authorities" ]; then
infoln "Generating certificates using Fabric CA"
${CONTAINER_CLI_COMPOSE} -f compose/$COMPOSE_FILE_CA -f compose/$CONTAINER_CLI/${CONTAINER_CLI}-$COMPOSE_FILE_CA up -d 2>&1
. organizations/fabric-ca/registerEnroll.sh
while :
do
if [ ! -f "organizations/fabric-ca/org1/tls-cert.pem" ]; then
sleep 1
else
break
fi
done
infoln "Creating Org1 Identities"
createOrg1
infoln "Creating Org2 Identities"
createOrg2
infoln "Creating Orderer Org Identities"
createOrderer
fi
infoln "Generating CCP files for Org1 and Org2"
./organizations/ccp-generate.sh
}
- Generates cryptographic material (certificates and keys) for the organizations in the network.
- Uses the cryptogen tool (for testing) or a Fabric Certificate Authority (CA) to generate the identities.
- Creates the certificates for the two peer organizations (Org1 and Org2) and the ordering service (the component responsible for ordering transactions).
- This is essential because, in a permissioned blockchain like Hyperledger Fabric, each participant needs cryptographic credentials to interact with the network.
# networkUp()
function networkUp() {
checkPrereqs
# generate artifacts if they don't exist
if [ ! -d "organizations/peerOrganizations" ]; then
createOrgs
fi
COMPOSE_FILES="-f compose/${COMPOSE_FILE_BASE} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_BASE}"
if [ "${DATABASE}" == "couchdb" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f compose/${COMPOSE_FILE_COUCH} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_COUCH}"
fi
DOCKER_SOCK="${DOCKER_SOCK}" ${CONTAINER_CLI_COMPOSE} ${COMPOSE_FILES} up -d 2>&1
$CONTAINER_CLI ps -a
if [ $? -ne 0 ]; then
fatalln "Unable to start network"
fi
}
- Brings up the Fabric network.
- First, it checks if the prerequisites are met by calling checkPrereqs().
- If the network is not already running, it will generate cryptographic material using createOrgs() and then start the Docker containers for the network (peers, ordering service, etc.). -> Don't forget to run the Docker!
- Initializes the network and sets up the basic components (peers, orderers) to start interacting with smart contracts.
# createChannel()
function createChannel() {
# Bring up the network if it is not already up.
bringUpNetwork="false"
local bft_true=$1
if ! $CONTAINER_CLI info > /dev/null 2>&1 ; then
fatalln "$CONTAINER_CLI network is required to be running to create a channel"
fi
# check if all containers are present
CONTAINERS=($($CONTAINER_CLI ps | grep hyperledger/ | awk '{print $2}'))
len=$(echo ${#CONTAINERS[@]})
if [[ $len -ge 4 ]] && [[ ! -d "organizations/peerOrganizations" ]]; then
echo "Bringing network down to sync certs with containers"
networkDown
fi
[[ $len -lt 4 ]] || [[ ! -d "organizations/peerOrganizations" ]] && bringUpNetwork="true" || echo "Network Running Already"
if [ $bringUpNetwork == "true" ]; then
infoln "Bringing up network"
networkUp
fi
# now run the script that creates a channel. This script uses configtxgen once
# to create the channel creation transaction and the anchor peer updates.
scripts/createChannel.sh $CHANNEL_NAME $CLI_DELAY $MAX_RETRY $VERBOSE $bft_true
}
- Creates a channel on the Fabric network.
- A channel is a private communication pathway where participants exchange data.
- Channels allow multiple applications or consortium to exist within the same Fabric network.
- This function ensures the network is up and running and then creates a channel for organizations to join.
- You need a channel to deploy and invoke smart contracts (chaincode) on the Fabric network.
- It’s where the smart contracts run and store transaction data.
# deployCC()
function deployCC() {
scripts/deployCC.sh $CHANNEL_NAME $CC_NAME $CC_SRC_PATH $CC_SRC_LANGUAGE $CC_VERSION $CC_SEQUENCE $CC_INIT_FCN $CC_END_POLICY $CC_COLL_CONFIG $CLI_DELAY $MAX_RETRY $VERBOSE
if [ $? -ne 0 ]; then
fatalln "Deploying chaincode failed"
fi
}
- Deploys a smart contract (chaincode) onto the channel.
- Calls the deployCC.sh script to deploy the smart contract to the channel and make it available for invocation (Invoke).
- This is where the actual logic (smart contracts) is deployed.
- After deploying, organizations can interact with the chaincode by invoking its functions.
# invokeChaincode()
function invokeChaincode() {
export FABRIC_CFG_PATH=${PWD}/../config
. scripts/envVar.sh
. scripts/ccutils.sh
setGlobals $ORG
chaincodeInvoke $ORG $CHANNEL_NAME $CC_NAME $CC_INVOKE_CONSTRUCTOR
}
- Invokes a transaction on the deployed chaincode.
- Calls a smart contract function (method) and executes a transaction.
- This is where the interaction with the smart contract happens, typically writing data to the blockchain (e.g., transferring assets, updating records).
# queryChaincode()
function queryChaincode() {
export FABRIC_CFG_PATH=${PWD}/../config
. scripts/envVar.sh
. scripts/ccutils.sh
setGlobals $ORG
chaincodeQuery $ORG $CHANNEL_NAME $CC_NAME $CC_QUERY_CONSTRUCTOR
}
- Queries the deployed chaincode for information.
- Retrieves data from the blockchain based on the smart contract logic.
- This is used to read data from the blockchain without making any state changes.
# networkDown()
function networkDown() {
local temp_compose=$COMPOSE_FILE_BASE
COMPOSE_FILE_BASE=compose-bft-test-net.yaml
COMPOSE_BASE_FILES="-f compose/${COMPOSE_FILE_BASE} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_BASE}"
COMPOSE_COUCH_FILES="-f compose/${COMPOSE_FILE_COUCH} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_COUCH}"
COMPOSE_CA_FILES="-f compose/${COMPOSE_FILE_CA} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_CA}"
COMPOSE_FILES="${COMPOSE_BASE_FILES} ${COMPOSE_COUCH_FILES} ${COMPOSE_CA_FILES}"
# stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3
COMPOSE_ORG3_BASE_FILES="-f addOrg3/compose/${COMPOSE_FILE_ORG3_BASE} -f addOrg3/compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_ORG3_BASE}"
COMPOSE_ORG3_COUCH_FILES="-f addOrg3/compose/${COMPOSE_FILE_ORG3_COUCH} -f addOrg3/compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_ORG3_COUCH}"
COMPOSE_ORG3_CA_FILES="-f addOrg3/compose/${COMPOSE_FILE_ORG3_CA} -f addOrg3/compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_ORG3_CA}"
COMPOSE_ORG3_FILES="${COMPOSE_ORG3_BASE_FILES} ${COMPOSE_ORG3_COUCH_FILES} ${COMPOSE_ORG3_CA_FILES}"
if [ "${CONTAINER_CLI}" == "docker" ]; then
DOCKER_SOCK=$DOCKER_SOCK ${CONTAINER_CLI_COMPOSE} ${COMPOSE_FILES} ${COMPOSE_ORG3_FILES} down --volumes --remove-orphans
elif [ "${CONTAINER_CLI}" == "podman" ]; then
${CONTAINER_CLI_COMPOSE} ${COMPOSE_FILES} ${COMPOSE_ORG3_FILES} down --volumes
else
fatalln "Container CLI ${CONTAINER_CLI} not supported"
fi
COMPOSE_FILE_BASE=$temp_compose
# Don't remove the generated artifacts -- note, the ledgers are always removed
if [ "$MODE" != "restart" ]; then
# Bring down the network, deleting the volumes
${CONTAINER_CLI} volume rm docker_orderer.example.com docker_peer0.org1.example.com docker_peer0.org2.example.com
#Cleanup the chaincode containers
clearContainers
#Cleanup images
removeUnwantedImages
# remove orderer block and other channel configuration transactions and certs
${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf system-genesis-block/*.block organizations/peerOrganizations organizations/ordererOrganizations'
## remove fabric ca artifacts
${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf organizations/fabric-ca/org1/msp organizations/fabric-ca/org1/tls-cert.pem organizations/fabric-ca/org1/ca-cert.pem organizations/fabric-ca/org1/IssuerPublicKey organizations/fabric-ca/org1/IssuerRevocationPublicKey organizations/fabric-ca/org1/fabric-ca-server.db'
${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf organizations/fabric-ca/org2/msp organizations/fabric-ca/org2/tls-cert.pem organizations/fabric-ca/org2/ca-cert.pem organizations/fabric-ca/org2/IssuerPublicKey organizations/fabric-ca/org2/IssuerRevocationPublicKey organizations/fabric-ca/org2/fabric-ca-server.db'
${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf organizations/fabric-ca/ordererOrg/msp organizations/fabric-ca/ordererOrg/tls-cert.pem organizations/fabric-ca/ordererOrg/ca-cert.pem organizations/fabric-ca/ordererOrg/IssuerPublicKey organizations/fabric-ca/ordererOrg/IssuerRevocationPublicKey organizations/fabric-ca/ordererOrg/fabric-ca-server.db'
${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf addOrg3/fabric-ca/org3/msp addOrg3/fabric-ca/org3/tls-cert.pem addOrg3/fabric-ca/org3/ca-cert.pem addOrg3/fabric-ca/org3/IssuerPublicKey addOrg3/fabric-ca/org3/IssuerRevocationPublicKey addOrg3/fabric-ca/org3/fabric-ca-server.db'
# remove channel and script artifacts
${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf channel-artifacts log.txt *.tar.gz'
fi
}
- Shuts down the Fabric network and cleans up all related resources.
- Stops all the containers.
- Cleans up any Docker volumes and artifacts generated during network setup (e.g., cryptographic material, block files). Used when you want to completely stop and reset the network.
해당 포스트는 미국 석사생의 질문으로 영어로 작성되었습니다.
* Sourced by: Hyperledger Fabric. (2024). Hyperledger Fabric Project. GitHub repository. https://github.com/hyperledger/fabric