Introduction
Hyperledger fabric v2+ comes with many changes and the way we deploy the chaincode is one of them. In this article we will go through the step by step process of chaincode deployment. By the end of this tutorial, one should get a sound knowledge of chaincode deployment process.
How does v2+ compare with the older versions ?
In previous versions of HLF(prior to v2), the chaincode deployment would consist of:
- Chaincode Installation
- Chaincode Instantiation
- Chaincode Query/Invoke
In HLF(v2+), things have changed. We now have:
- Chaincode Packaging
- Chaincode Approval
- Chaincode Commit
- Chaincode Query/invoke
Setup
We will be using a sample network which is just a modification of "test-network" running Fabric v2.2.3 LTS. This modified network, has built in CLIs for two orgs which will avoid the hassle of providing the environment variables again and again for different operations. If you want to understand the network setup from scratch you may refer to one of my previous articles.
For the chaincode, will use asset-transfer-basic
chaincode which comes with the fabric installation and is present inside the "fabric-samples" directory. For the sake of simplicity, we will stick to the chaincode deployment process rather than development part. We will work with the golang version of this chaincode but feel free to try out java/javascript/typescript versions of this chaincode, which are provided in the "fabric-samples".
Step 1: Bring up the network
Navigate to the "test-network" directory inside the "fabric-samples". Run the following script to bring up the network and create a channel, mychannel
is the default channel which will get created.
cd abric-samples/scratchNw
mkdir channel-artifacts
./noviceNw.sh
After the script executes, you should be able to see two peers belonging to each organization, single orderer and two CLIs.
Step 2: Packaging the Chaincode
First we navigate to the chaincode directory and resolve the dependencies.
cd fabric-samples/scratchNw/chaincode/asset-transfer-basic/chaincode-go
GO111MODULE=on go mod vendor
Then we package the chaincode, by going inside cliorg1
:
docker exec -it cliorg1
peer lifecycle chaincode package ccPackages/basic.tar.gz --path chaincode/asset-transfer-basic/chaincode-go --lang golang --label basic_1.0
We should see basic.tar.gz
package inside the ccPackages
directory.
Step 3: Install the Chaincode
We will be using the basic.tar.gz
package generated in the previous step to install the chaincode in org1 and org2.
From the cliorg1,
peer lifecycle chaincode install ccPackages/basic.tar.gz
You should see something like this:
A package identifier is returned. In this case its basic_1.0:2c47b5b060a64aafa3c878b4bcb0ca680bdb2417ca8855b5440fa595562517d2
If at any point of time we want to get the list of chaincodes installed:
peer lifecycle chaincode queryinstalled
You should see:
This is useful when we want to retrieve the package IDs.
Now we install the chaincode in org2.
Open a new terminal. First we go inside cliorg2, then from cliorg2
:
docker exec -it cliorg2
peer lifecycle chaincode install ccPackages/basic.tar.gz
Step 4: Approve Chaincode
As per the Lifecycle Endoresement policy defined in configtx.yaml
file, we need to have majority endorsement in ordrer to commit the chainocode in the next step. So, in our case we would require approvals from both the orgs.
We go inside cliorg1
, export the chaincode package id which we got from previous step and approve the chaincode.
docker exec -it cliorg1
export PACKAGE_ID=basic_1.0:2c47b5b060a64aafa3c878b4bcb0ca680bdb2417ca8855b5440fa595562517d2
peer lifecycle chaincode approveformyorg -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA --channelID mychannel --name basic --version 1.0 --package-id ${PACKAGE_ID} --sequence 1
You should see something similar:
Similarly for org2, we go inside cliorg2
, export the chaincode package id and approve the chaincode.
docker exec -it cliorg2
export PACKAGE_ID=basic_1.0:2c47b5b060a64aafa3c878b4bcb0ca680bdb2417ca8855b5440fa595562517d2
peer lifecycle chaincode approveformyorg -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA --channelID mychannel --name basic --version 1.0 --package-id ${PACKAGE_ID} --sequence 1
Here's the output:
We can check if the chaincode are ready to be committed. From the cliorg1
and cliorg2
execute:
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --output json
You should see the output showing the approvals from both the orgs.
Step 5: Commit Chaincode
To commit a chaincode, we need to do it from only one peer.
From cliorg1
, execute:
peer lifecycle chaincode commit -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA --channelID mychannel --name basic --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles $PEER0_ORG1_CA --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles $PEER0_ORG2_CA --version 1.0 --sequence 1
We should see the output as:
We use peer lifecycle chaincode querycommitted --channelID mychannel basic
to check the status of the chaincode committed.
After the chaincode is committed, the chaincode lifecycle is complete. We can now invoke/query the chaincode.
Step 6: Invoke / Query Chaincode
From cliorg1
we invoke the chaincode. We invoke the "initLedger" function and the chaincode logic will initialize with six assets. These assets will be stored in the ledger.
peer chaincode invoke -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA -C mychannel -n basic --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles $PEER0_ORG1_CA --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles $PEER0_ORG2_CA -c '{"function":"InitLedger","Args":[]}'
Let us try and query the chaincode, from cliorg1
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
Also we try to query the chaincode, from cliorg2
We should see the same output from cliorg1
and cliorg1
Cleanup
./network.sh down
docker volume prune
docker network prune
Conclusion
We were successfully able to deploy the chaincode into the network. We got a good overview of the steps which are involved in the new chaincode lifeycle which was introduced in Hyperledger Fabric version 2.
Do leave a comment, if you have any queries or faced any issues.