# Chaincode Operation in Hyperledger Fabric v2+

# 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](https://github.com/SaifDeveloper/FabricNwScratch) 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](https://saifworks.hashnode.dev/hyperledger-fabric-network-setup-from-scratch).

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.


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623128840676/WhIbi7KLk.png)

### 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:


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623135582389/iYu--dTbK.png)

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:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623135898241/G0UAiqzTc.png)

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:


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623167740724/lipNXn8ed.png)


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:


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623167858899/bGkHgdr_l.png)


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.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623168104725/V1L0qDUDa.png)

### 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:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623168966137/u3IcX1cbJ.png)

We use `peer lifecycle chaincode querycommitted --channelID mychannel basic` to check the status of the chaincode committed.



![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623169346583/bu4RcSCOa.png)


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":[]}'

``` 

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623169813377/WPo1y9m4-.png)

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`

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623171477248/UXnyzJzw1.png)


### 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.


