How to deploy chaincode in Hyperledger Fabric 2.0?

Published: 2020-02-06 10 minutes
Category:
dev
▪ Tags:
blockchain
hyperledger

With the new release of Hyperledger Fabric 2.0 the lifecycle of chaincode has been changed. It means that commands used to deploy chaincode in < 2.0 release (no matter if using peer binary or SDK) will not work. In this article I show how to deploy chaincode to the Hyperledger Fabric 2.0.

With the new release of Hyperledger Fabric 2.0 the lifecycle of chaincode has been changed. It implies also the changes in the chaincode deployment process – what basically means that commands used to deploy chaincode in < 2.0 release (no matter if using peer binary or SDK) will not work.

In this article I show how to deploy chaincode to the Hyperledger Fabric 2.0.

Channel configuration changes in Hyperledger Fabric 2.0

One of the most important changes of chaincode lifecycle in the Fabric 2.0 is that the rights to chaincode operations are now encoded in channel definition. In the most basic scenario, the change included in the configtx.yaml indicates who has the right to endorse the chaincode changes. Fabric 2.0 ACL can specify the rights to even single blockchain operations (like querying peer if chaincode exists). We will not focus on the customization but only highlight the minimum change.

Hyperledger Fabric 2.0 chaincode deployment steps

Here are the steps in order to succeed with chaincode deployment in Hyperledger Fabric 2.0

1. Upgrade all the Docker images

Upgrade the docker images tags to given values:

  • peer, orderer, fabric-tools: 2.0.0 (I assume that you use Raft orderer, in case of Kafka search for the newest Kafka and Zookeeper tags) couch: 0.4.18
  • CA: 1.4.4 (however this article doesn’t focus on CA)

2. Update configtx.yaml

I assume you setup fresh Fabric setup otherwise you will have to update blockchain configuration rather than setup it from scratch (updating the configtx.yaml file will allow to generate fresh blockchain configuration). Here is the change which must be done in configtx.yaml in order to apply to new 2.0 specification:

  • For every organization add the Endorsement section in the Policies section with the signature of organization peer. Lack of this entry will for example not allow you to install chaincode with private collections. At least from the tests I’ve done so far, not required for orderer organization. Example:
          
    - &Org1
            Name: Org1MSP
            ID: Org1MSP
            MSPDir: crypto-config/peerOrganizations/org1/msp
            Policies:
                Readers:
                    Type: Signature
                    Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
                Writers:
                    Type: Signature
                    Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
                Admins:
                    Type: Signature
                    Rule: "OR('Org1MSP.admin')"
                Endorsement:
                    Type: Signature
                    Rule: "OR('Org1MSP.peer')"
            AnchorPeers:
                - Host: org1-peer0
                  Port: 7051
          
        
  • Your capabilities section should look like below:
          
    Capabilities:
        Channel: &ChannelCapabilities
            V2_0: true
        Orderer: &OrdererCapabilities
            V2_0: true
        Application: &ApplicationCapabilities
            V2_0: true
          
        
  • Your application section should have added 2 new sections LifecycleEndorsement and Endorsement, except the existing Readers, Writers, Admins. Here below is the example section which is not very restrictive (means that every organization can apply the chaincode change). Please align it to your need:
          
Application: &ApplicationDefaults
    Organizations:
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        LifecycleEndorsement:
            Type: ImplicitMeta
            Rule: "ANY Endorsement"
        Endorsement:
            Type: ImplicitMeta
            Rule: "ANY Endorsement"
    Capabilities:
        <<: *ApplicationCapabilities
          
        

3. Regenerate configuration

The configuration must be regenerated (need new genesis block) – use configtxgen tool. You can also regenerate crypto-config with cryptogen tool if you want and can but it’s not necessary. Run the blockchain with new genesis block, then also recreate your channel with channel transaction.

4. Prepare chaincode deployment container and script

This assumes you load the chaincode using fabric-tools docker image container which has all the keys and environment vars setup. If you was using your cli before upgrade to 2.0 for chaincode deployment you can use this image, just add there the setupchaincode.sh script and your chaincode sources with appropriate path mapping (volumes section in docker compose file definition, take a look on following docker compose file example).

This is minimal container settings for the one I use. It requires you to set your local chaincode path (on local machine). This is the file content (don’t invoke it yet, it requires you to have also the chaincode deployment setupchaincode.sh script):

          
    # Copyright IBM Corp. All Rights Reserved.
    #
    # SPDX-License-Identifier: Apache-2.0
    #

    version: '2'

    networks:
      byfn:

    services:

      chaincode-deployer:
        container_name: chaincode-deployer
        image: hyperledger/fabric-tools:$IMAGE_TAG
        tty: true
        stdin_open: true
        environment:
          - GOPATH=/opt/gopath
          - FABRIC_LOGGING_SPEC=DEBUG
        working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
        command: /opt/gopath/src/github.com/hyperledger/fabric/peer/setupchaincode.sh && /bin/bash
        volumes:
          # Change your local chaincode path!!!
          # If you change the location in container also remember to change in setupchaincode.sh
          - ./your/local/chaincode/path:/opt/gopath/src/github.com/chaincode/examplechaincode
          # Change according to your paths
          - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
          - ./setupchaincode.sh:/opt/gopath/src/github.com/hyperledger/fabric/peer/setupchaincode.sh
        networks:
          - byfn
        ports:
          - 15050:15050
          
        

This is the setupchaincode.sh script which does the work of chaincode deployment. Configure all the variables according to your configuration:

          
    #!/usr/bin/env bash
    ## MUST BE CHANGED EVERY BUILD
    CHAINCODE_VERSION=1.0

    ## Chaincode info - CONFIGURE ONCE
    CHAINCODE_LANG=node
    CHAINCODE_NAME=examplechaincode
    CHAINCODE_INIT_ARGS='{"Args":[]}'
    CHAINCODE_LABEL=${CHAINCODE_NAME}_${CHAINCODE_VERSION}
    CHAINCODE_PACKAGE_NAME=${CHAINCODE_LABEL}.tar.gz
    # Source path in the cli container
    CHAINCODE_SOURCE_PATH=/opt/gopath/src/github.com/chaincode/examplechaincode

    # Other info - CONFIGURE ONCE
    CHANNEL_NAME=mychannel
    ORDERER=orderer.org1.fabric
    ORDERER_ADDRESS=${ORDERER}:7050
    ORDERER_CA_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/org1.fabric/orderers/orderer.org1.fabric/msp/tlscacerts/tlsca.org1.fabric-cert.pem

    export CORE_PEER_ADDRESS=peer0.org1.fabric:7051
    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric/peers/peer0.org1.fabric/tls/server.crt
    export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric/peers/peer0.org1.fabric/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric/users/Admin@org1.fabric/msp

    # Dont change anything below, should work fine

    installChaincode() {
      PEER_ADDRESS=$1
      PEER_CERT_PATH=$2
      SEQUENCE=$3
      echo 'Installing chaincode on peer: ' $PEER_ADDRESS
      peer lifecycle chaincode install $CHAINCODE_PACKAGE_NAME >&install-log.txt
      PACKAGE_ID=$(awk '{for(i=1;i<=NF;i++)if($i=="identifier:")print $(i+1)}' install-log.txt)
      peer lifecycle chaincode approveformyorg -o $ORDERER_ADDRESS --tls --cafile $ORDERER_CA_FILE --channelID $CHANNEL_NAME --name $CHAINCODE_NAME --version $CHAINCODE_VERSION --init-required --package-id $PACKAGE_ID --waitForEvent --sequence $SEQUENCE
      peer lifecycle chaincode commit -o $ORDERER_ADDRESS --tls --cafile $ORDERER_CA_FILE --channelID $CHANNEL_NAME --name $CHAINCODE_NAME --version $CHAINCODE_VERSION --sequence $SEQUENCE --init-required
      peer chaincode invoke -o $ORDERER_ADDRESS --tls --cafile $ORDERER_CA_FILE --ordererTLSHostnameOverride $ORDERER -C $CHANNEL_NAME -n $CHAINCODE_NAME --peerAddresses $PEER_ADDRESS --isInit -c $CHAINCODE_INIT_ARGS --tlsRootCertFiles $PEER_CERT_PATH
      echo 'Finished installing chaincode on peer: ' $PEER_ADDRESS
    }

    # Generate chaincode package - common step
    peer lifecycle chaincode package $CHAINCODE_PACKAGE_NAME --path $CHAINCODE_SOURCE_PATH --lang $CHAINCODE_LANG --label $CHAINCODE_LABEL

    # Get sequence value
    peer lifecycle chaincode querycommitted --channelID $CHANNEL_NAME >&sequence.txt
    seq=$(awk '{for(i=1;i<=NF;i++)if($i=="Sequence:")print $(i+1)}' sequence.txt)
    SEQUENCE=$(echo "${seq//,}")
    if [ -z $SEQUENCE ] ; then
      SEQUENCE=1
      echo 'No sequence yet, initializing with 1, got: '$SEQUENCE
    else
      SEQUENCE=$(($SEQUENCE + 1))
      echo 'Incrementing sequence by 1, got: '$SEQUENCE
    fi
    installChaincode $CORE_PEER_ADDRESS $CORE_PEER_TLS_ROOTCERT_FILE $SEQUENCE
          
        

5. Deploy chaincode

Prepare folder and put there:

  • docker compose file for running fabric-tools deployment container (I’ve gave example content, please configure for your needs)
  • current crypto-config
  • setupchaincode.sh (please configure it for your needs)

You can run it with: docker-compose -f chaincode-deployer.yaml up

The script should install chaincode correctly only if you have the same non restrictive endorsement (single organization approval is enough to install chaincode). Otherwise you will have to repeat peer lifecycle chaincode approveformyorg multiple times (and probably the steps before) before running peer lifecycle chaincode commit .

Summary

Hyperledger Fabric is the permissioned blockchain which is very features rich especially allowing for very wide configuration. The new chaincode deployment model gives more flexibility in the definition of chaincode deployment permissions.

dev
blockchain
hyperledger