First clarify the network steps of a single machine:
Generate organization
Generate certificates for your organization
Generate Genesis block
Generate channel
Generate node join channel
Set anchor node
Then find out what steps in the script are started through those instructions:
Let's first look at the startup parameters of a network
cd test-network/ ./network.sh up createChannel -c mychannel -ca && ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-java -ccl java
Before and after & & above are actually two different lines of instructions
-
The previous instruction runs the script with the parameter up createChannel ca (the certificate generation method with ca and without ca will be different. In the current work, we use the ca tag to start) to create a channel for starting the network and use ca to generate encryption materials
-
The latter instruction runs the script with the parameter deployCC to install the chain code (smart contract) on the channel
The directory for running scripts must be under test network /
It can be seen that the shell script network.sh is the key tool for us to start the network and run our blockchain application!
1.networkup( )
-
First perform the network up() function, which is called in the function.
-
checkPrep() - mainly checks the version of docker
-
createOrgs() – createOrgs is divided into the following steps: (take the startup mode of - ca as an example)
createOrgs( )
-
Start the ca node through docker compose
-
Load registerEnroll.sh -- what's the content of this script?
- createOrg1()
- createOrg2()
- createOrderer()
- The above three functions are defined in this shell
-
Then execute the functions defined in the shell
-
createOrg1
-
createOrg2
-
createOrderer
-
Next, execute the ccp-generate.sh script
- The script function is to create a certificate file and place it under organizations /
-
-
Next, check whether the database is used. If couchdb is used, start a related container with docker
-
2.createChannel( )
Then the organization file certificate is finished,If you want to use,Next, you need to create a Genesis block Genesis block uses tools configtxgen, The configuration of Genesis block is TwoOrgsApplicationGenesis The channel MSP allows the nodes and users to be recognized as members of the network With the organization's encrypted files and Genesis blocks,peers and orderer Your service will start This step will be in createChannel() When
-
After the content of up() ends, a channel will be created after the network is started, that is, the function createChannel()
-
The first step of the function is to check whether the network is starting. If not, execute the up() above
-
If the network is OK, run createChannel.sh under scripts / - let's see what's in it
Contents of createChannel.sh
create folder
- First, a folder channel artifacts / will be created to store the channel files
Definition of four functions
1. Next is the definition of a function createChannelGenesisBlock()
-
An important instruction in this function is
configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/${CHANNEL_NAME}.block -channelID $CHANNEL_NAME #Through this instruction, use the configtxgen tool mentioned earlier to create a Genesis block, which is stored under the newly created channel artifacts /
2. Define a createChannel() – the content is as follows
#A delay instruction is written in the script to leave time for the raft consensus, which is omitted here setGlobals 1 #The following is a long instruction. It can be seen that the channel is created according to the genesis block file created in channel artifacts / osnadmin channel join --channelID $CHANNEL_NAME --config-block ./channel-artifacts/${CHANNEL_NAME}.block -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY" >&log.txt
3. In addition, a function joinChannel() is defined - I also write the content summary in the code block
#First, these lines of instructions $1 is the first parameter added when the function runs #Ep:joinChannel 1 #Then create a peer node in org1 and join the channel ORG=$1 setGlobals $ORG #After that, there is also a delayed instruction in the script, which is omitted here #The next step is to join the peer node peer channel join -b $BLOCKFILE >&log.txt
4. There is also a function definition for setting anchor node setanchor()
#This function also has processing parameters ORG=$1 #Next, enter the docker container of the node. Instead of bash, the script setAnchorPeer.sh is directly run docker exec cli ./scripts/setAnchorPeer.sh $ORG $CHANNEL_NAME #In the above setAnchorPeer.sh, different host names and ports are set according to different incoming parameters, that is, the anchor node information is determined
- Then, the above is the definition of the four functions in the script - createchannelgenesisblock -- createchannel -- joinchannel -- setanchor()
Next, call these functions to complete the creation of channels, the creation and addition of nodes and the setting of anchor nodes
#Create Genesis block createChannelGenesisBlock #Next, set the position of some variables in the following functions, such as the position of Genesis block data BLOCKFILE FABRIC_CFG_PATH=$PWD/../config/ BLOCKFILE="./channel-artifacts/${CHANNEL_NAME}.block" #Create channel createChannel #Create peer nodes for org1 and org2 and join channels joinChannel 1 joinChannel 2 #Set anchor nodes for org1 and org2 setAnchorPeer 1 setAnchorPeer 2
-
3.deployCC( )
-
The network and channel have been started! Then the next step is to install the chain code on the channel and compile the app, so the function deployCC() in the next step is used
-
Damn it, the content of this function is to run the deployCC.sh script under scripts /. Of course, a lot of chain code information and channel information will be passed in during operation, so that the chain code can be deployed on the channel. In fact, we can run it directly on our main server with network.sh script and instructions, regardless of single machine or multiple machines, without seeing the underlying layer, However, we can continue to study deeply
-
What else to say, rush this script! Let's vim go in Kangkang
deployCC.sh
As mentioned above, we passed in many parameters. The first long section of the script is to check these variables print and confirm whether there is a lack of key information
According to the input chain code language information, the compiled tools are also different Ep: java – gradle javascript/typescript - npm
#If it's go if [ "$CC_SRC_LANGUAGE" = "go" ]; then CC_RUNTIME_LANGUAGE=golang infoln "Vendoring Go dependencies at $CC_SRC_PATH" pushd $CC_SRC_PATH GO111MODULE=on go mod vendor popd successln "Finished vendoring Go dependencies"
#java elif [ "$CC_SRC_LANGUAGE" = "java" ]; then CC_RUNTIME_LANGUAGE=java infoln "Compiling Java code..." pushd $CC_SRC_PATH ./gradlew installDist popd successln "Finished compiling Java code" CC_SRC_PATH=$CC_SRC_PATH/build/install/$CC_NAME
#js elif [ "$CC_SRC_LANGUAGE" = "javascript" ]; then CC_RUNTIME_LANGUAGE=node elif [ "$CC_SRC_LANGUAGE" = "typescript" ]; then CC_RUNTIME_LANGUAGE=node infoln "Compiling TypeScript code into JavaScript..." pushd $CC_SRC_PATH npm install npm run build popd successln "Finished compiling TypeScript code into JavaScript"
Obviously, the above if elif code structure will not run completely, but will be compiled according to your chain code language parameters. In addition to the above compilation instructions, there are quite a few function definitions in the script:
packageChaincode() installChaincode() queryInstalled() approveForMyOrg() checkCommitReadiness()
commitChaincodeDefinition() queryCommitted() chaincodeInvokeInit() chaincodeQuery()
Nine functions!!! Grass (I mean, there's a lot of grass
Now that I've done it, I'd better finish reading it on my knees
- packageChaincode()
#It is mainly an instruction to package chain code peer lifecycle chaincode package ${CC_NAME}.tar.gz --path ${CC_SRC_PATH} --lang ${CC_RUNTIME_LANGUAGE} --label ${CC_NAME}_${CC_VERSION} >&log.txt
-
installChaincode()
#It is mainly an instruction to install chain code with parameters peer lifecycle chaincode install ${CC_NAME}.tar.gz >&log.txt
-
queryInstalled()
#With reference peer lifecycle chaincode queryinstalled >&log.txt
-
approveForMyOrg()
#With reference peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --package-id ${PACKAGE_ID} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt
-
checkCommitReadiness()
#With reference peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} --output json >&log.txt
-
commitChaincodeDefinition()
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" --channelID $CHANNEL_NAME --name ${CC_NAME} "${PEER_CONN_PARMS[@]}" --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt
-
queryCommitted()
#With reference peer lifecycle chaincode queryinstalled >&log.txt
-
chaincodeInvokeInit()
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" -C $CHANNEL_NAME -n ${CC_NAME} "${PEER_CONN_PARMS[@]}" --isInit -c ${fcn_call} >&log.txt
-
chaincodeQuery()
#With reference peer chaincode query -C $CHANNEL_NAME -n ${CC_NAME} -c '{"Args":["queryAllCars"]}' >&log.txt
The above is the definition of nine functions. It is not difficult to see that each function calls an instruction (I omitted the part to judge whether the timeout occurs)
After the functions are defined, the instructions to execute these functions are as follows:
#First pack the chain code packageChaincode #peer installation in organization 1 installChaincode 1 #peer installation in organization 2 installChaincode 2 #Check whether the installation is successful queryInstalled 1 #Approved by organization 1 approveForMyOrg 1 #Check whether the chain code definition has passed. Org1 has passed but Org2 has not checkCommitReadiness 1 "\"Org1MSP\": true" "\"Org2MSP\": false" checkCommitReadiness 2 "\"Org1MSP\": true" "\"Org2MSP\": false" #The next step is the same for organization 2 approveForMyOrg 2 #At this time, both organizations have passed. Check it checkCommitReadiness 1 "\"Org1MSP\": true" "\"Org2MSP\": true" checkCommitReadiness 2 "\"Org1MSP\": true" "\"Org2MSP\": true" #Both organizations have agreed to submit the chain code commitChaincodeDefinition 1 2 #Check the submission status of org1 queryCommitted 1 #Check the submission status of org2 queryCommitted 2 #If there are initialization parameters, execute the chain code chaincodeInvokeInit 1 2
-
4.networkDown( )
-
The above is the process of using the fabric network. If the network is closed, there is the function network
-
Down( )
-
Delete containers through docker compose
-
Delete the certificate and other files generated by the network through docker compose
When shutting down the network, you can directly use the script down
Now that you understand the bottom layer of network startup, let's take a look at what needs to be modified in case of multi machine configuration
docker-compose.yaml
We create nodes of three organizations through docker compose, then we need to modify the startup configuration files of these nodes to connect them into a network
After creating the orgs certificate file, we need to copy it to each server to ensure that the encrypted files of the same organization on different machines are still consistent
The channel files channel artifacts / also need to be copied in this way
For the rest, just follow the script and remember the six big steps