Tutorial Hyperledger Fabric: How to build your first network?

This tutorial will introduce you to the Hyperledger Fabric network and will allow you to build your own Hyperledger Fabric network.

It is working on Ubuntu 16.04 with Hyperledger-Fabric version 1.0.5.

The sources are available on Github: github.com/chainhero-website/heroes-service-network

For convenience only, we will create the network we used in our main tutorial.

  1. Installation Guide
    1. Prepare Environment
    2. Dependencies
  2. Configuration
    1. Crypto-Config
    2. Artifacts
  3. Docker-Compose
  4. Conclusion

1. Installation Guide

a. Prepare environment

Before doing anything let’s create our working directory :

mkdir -p $GOPATH/src/github.com/chainHero/heroes-service-network

b. Dependencies

In order for us to correctly create our network we need few binaries provided by Hyperledger Fabric (v1.0.5).

You can either use the binaries we provide or download them from the official repository.

Download them from our repository (Linux x64 ONLY):

cd $GOPATH/src/github.com/chainHero/heroes-service-network && \
svn checkout https://github.com/chainHero/heroes-service-network/branches/master/bin

Download them from the official repository:

  • Linux s390x
  • Linux PPC64Ie
  • Linux AMD 64
  • Windows AMD 64
  • Darwin AMD 64

Once that you have downloaded the bin folder, move it into the heroes-service-network folder.

2. Configuration

a. Crypto-config

To get started we need to define what our network will be composed of. To do so, we need a configuration file.

It will contains the network topology and allows us to generate a set of certificates and keys for both the Organizations and the components that belong to those Organizations.

Let’s create it and start editing it :

cd $GOPATH/src/github.com/chainHero/heroes-service-network && \
touch crypto-config.yaml && \
vi crypto-config.yaml

And paste this inside :

# "OrdererOrgs" - Definition of organizations managing orderer nodes
OrdererOrgs:
  - Name: ChainHero
    Domain: hf.chainhero.io
    # Specs is an array of Spec entries.  Each Spec entry consists of two fields : Hostname and CommonName
    Specs:
      - Hostname: orderer
# "PeerOrgs" - Definition of organizations managing peer nodes
PeerOrgs:
  - Name: Org1ChainHero
    Domain: org1.hf.chainhero.io
    # Allows for the definition of 1 or more hosts that are created sequentially
    # from a template. By default, this looks like "peer%d" from 0 to Count-1.
    # You may override the number of nodes (Count), the starting index (Start)
    # or the template used to construct the name (Hostname).
    Template:
      Count: 2
    Users:
      # The number of user accounts _in addition_ to Admin
      Count: 2

I added few comments for you to understand better what every lines stands for but if you want more information about it you should have a look here.

Now that our configuration file is set up we can use it to create the basis of our network. To do so we will use the Cryptogen tool to generate the cryptographic material (x509 certs) for our various network entities. cryptogen is an utility for generating Hyperledger Fabric key material, however it is mainly meant to be used for testing environment.

Let’s now create a folder named crypto-config and use cryptogen to initialize our network :

cd $GOPATH/src/github.com/chainHero/heroes-service-network && \
mkdir -p crypto-config && \
./bin/cryptogen generate --config=./crypto-config.yaml

Ok, we are done with the crypto files (certificates). You must be able to see two folders inside the crypto-config folder. It must be ordererOrganizations & peerOrganizations.

b. Artifacts

In order for us to finish the initialization of our blockchain we need to create :

  • The orderer genesis block. It is intended, as its name indicates, to correctly initialize Fabric’s orderers.
  • A channel genesis block. The channel is a kind of private network inside the main network which our users will be able to use. This allows you to initialize Fabric’s peers to join a channel.
  • An anchor peer. Its a peer node with an additional feature which allow all other peers to discover and communicate with it.

So let’s create this by editing a configuration file named configtx.yaml :

cd $GOPATH/src/github.com/chainHero/heroes-service-network && \
touch configtx.yaml && \
vi configtx.yaml

Paste this inside :

################################################################################
#
#   SECTION : Profile
#
#   - Different configuration profiles may be encoded here to be specified
#   as parameters to the configtxgen tool. The profiles which specify consortiums
#   are to be used for generating the orderer genesis block.  With the correct
#   consortium members defined in the orderer genesis block, channel creation
#   requests may be generated with only the org member names and a consortium name
#
################################################################################
Profiles:
    ChainHero:
        Orderer:
            <<: *OrdererDefaults
            Organizations:
                - *ChainHero
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *Org1ChainHero
        Consortium: SampleConsortium
        Consortiums:
            SampleConsortium:
                Organizations:
                    - *ChainHero
                    - *Org1ChainHero

################################################################################
#
#   SECTION: Organizations
#
#   - This section defines the different organizational identities which will
#   be referenced later in the configuration.
#
################################################################################
Organizations:
    - &ChainHero
        Name: ChainHero
        ID: hf.chainhero.io
        AdminPrincipal: Role.ADMIN
        MSPDir: crypto-config/ordererOrganizations/hf.chainhero.io/msp

    - &Org1ChainHero
        Name: ChainHeroOrganization1
        ID: org1.hf.chainhero.io
        AdminPrincipal: Role.ADMIN
        MSPDir: crypto-config/peerOrganizations/org1.hf.chainhero.io/msp
        AnchorPeers:
            - Host: peer0.org1.hf.chainhero.io
              Port: 7051

################################################################################
#
#   SECTION: Orderer
#
#   - This section defines the values to encode into a config transaction or
#   genesis block for orderer related parameters.
#
################################################################################
Orderer: &OrdererDefaults
    OrdererType: solo
    Addresses:
        - orderer.hf.chainhero.io:7050
    BatchTimeout: 5s
    # Batch Size: Controls the number of messages batched into a block.
    BatchSize:
        # Max Message Count: The maximum number of messages to permit in a batch.
        MaxMessageCount: 10
        # Absolute Max Bytes: The absolute maximum number of bytes allowed for
        # the serialized messages in a batch. If the "kafka" OrdererType is
        # selected, set 'message.max.bytes' and 'replica.fetch.max.bytes' on the
        # Kafka brokers to a value that is larger than this one.
        AbsoluteMaxBytes: 98 MB
        # Preferred Max Bytes: The preferred maximum number of bytes allowed for
        # the serialized messages in a batch. A message larger than the
        # preferred max bytes will result in a batch larger than preferred max
        # bytes.
        PreferredMaxBytes: 512 KB
    # Max Channels is the maximum number of channels to allow on the ordering
    # network. When set to 0, this implies no maximum number of channels.
    MaxChannels: 0

    # Organizations is the list of orgs which are defined as participants on
    # the orderer side of the network.
    Organizations:

################################################################################
#
#   SECTION: Application
#
#   - This section defines the values to encode into a config transaction or
#   genesis block for application related parameters.
#
################################################################################
Application: &ApplicationDefaults
    Organizations:

Now that our configuration file is ready to use let’s create the artifacts folder, which will contain the output files generated by the binary configtxgen :

cd $GOPATH/src/github.com/chainHero/heroes-service-network && \
mkdir -p artifacts

Then, let’s use the provided binary and our configuration file to create our genesis block :

cd $GOPATH/src/github.com/chainHero/heroes-service-network && \
FABRIC_CFG_PATH=$PWD ./bin/configtxgen -profile ChainHero -outputBlock ./artifacts/orderer.genesis.block

Note that we have to set the environment variable FABRIC_CFG_PATH with the current working directoring (that contains the configuration) because the binary find the configuration file named configtx.yaml through this environment variable.

Now that it have been created let’s see how we create the channel :

FABRIC_CFG_PATH=$PWD ./bin/configtxgen -profile ChainHero -outputCreateChannelTx ./artifacts/chainhero.channel.tx -channelID 
chainhero

Finally, we need a peer node which is called the anchor peer :

FABRIC_CFG_PATH=$PWD ./bin/configtxgen -profile ChainHero -outputAnchorPeersUpdate ./artifacts/org1.chainhero.anchors.tx 
-channelID chainhero -asOrg ChainHeroOrganization1

3. Docker-Compose

In order now to communicate and launch our network which will be Docker based we need to use Docker-Compose. It’s an useful tool which will allow us to launch several dockers at the same time.

If you need to install docker-compose then I’m going to redirect you to one of our tutorial in which we explain step by step how to install docker and docker-compose.

Now that you are all caught up with the installation part we can move on and start the implementation of our network configuration.

So, create a file named docker-compose.yaml and paste the following lines into it :

version: '2'

networks:
  default:

services:

  orderer.hf.chainhero.io:
    image: hyperledger/fabric-orderer:x86_64-1.0.5
    container_name: orderer.hf.chainhero.io
    environment:
      - ORDERER_GENERAL_LOGLEVEL=debug
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
      - ORDERER_GENERAL_LISTENPORT=7050
      - ORDERER_GENERAL_GENESISPROFILE=ChainHero
      - ORDERER_GENERAL_GENESISMETHOD=file
      - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
      - ORDERER_GENERAL_LOCALMSPID=hf.chainhero.io
      - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
      - ORDERER_GENERAL_TLS_ENABLED=true
      - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]

    working_dir: /opt/gopath/src/github.com/hyperledger/fabric
    command: orderer
    volumes:
      - ./artifacts/orderer.genesis.block:/var/hyperledger/orderer/orderer.genesis.block
      - ./crypto-config/ordererOrganizations/hf.chainhero.io/orderers/orderer.hf.chainhero.io/msp:/var/hyperledger/orderer/msp
      - ./crypto-config/ordererOrganizations/hf.chainhero.io/orderers/orderer.hf.chainhero.io/tls:/var/hyperledger/orderer/tls
    ports:
      - 7050:7050
    networks:
      default:
        aliases:
          - orderer.hf.chainhero.io

  ca.org1.hf.chainhero.io:
    image: hyperledger/fabric-ca:x86_64-1.0.5
    container_name: ca.org1.hf.chainhero.io
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca.org1.hf.chainhero.io
      - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.hf.chainhero.io-cert.pem
      - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/--HERE--
      - FABRIC_CA_SERVER_TLS_ENABLED=true
      - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.hf.chainhero.io-cert.pem
      - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/--HERE--
    ports:
      - 7054:7054
    command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
    volumes:
      - ./crypto-config/peerOrganizations/org1.hf.chainhero.io/ca/:/etc/hyperledger/fabric-ca-server-config
    networks:
      default:
        aliases:
          - ca.org1.hf.chainhero.io

  peer0.org1.hf.chainhero.io:
    image: hyperledger/fabric-peer:x86_64-1.0.5
    container_name: peer0.org1.hf.chainhero.io
    environment:
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_VM_DOCKER_ATTACHSTDOUT=true
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_PEER_NETWORKID=chainhero
      - CORE_PEER_PROFILE_ENABLED=true
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/var/hyperledger/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/var/hyperledger/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/var/hyperledger/tls/ca.crt
      - CORE_PEER_ID=peer0.org1.hf.chainhero.io
      - CORE_PEER_ADDRESSAUTODETECT=true
      - CORE_PEER_ADDRESS=peer0.org1.hf.chainhero.io:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.hf.chainhero.io:7051
      - CORE_PEER_GOSSIP_USELEADERELECTION=true
      - CORE_PEER_GOSSIP_ORGLEADER=false
      - CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
      - CORE_PEER_LOCALMSPID=org1.hf.chainhero.io
      - CORE_PEER_MSPCONFIGPATH=/var/hyperledger/msp
      - CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer0.org1.hf.chainhero.io
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start
    volumes:
      - /var/run/:/host/var/run/
      - ./crypto-config/peerOrganizations/org1.hf.chainhero.io/peers/peer0.org1.hf.chainhero.io/msp:/var/hyperledger/msp
      - ./crypto-config/peerOrganizations/org1.hf.chainhero.io/peers/peer0.org1.hf.chainhero.io/tls:/var/hyperledger/tls
    ports:
      - 7051:7051
      - 7053:7053
    depends_on:
      - orderer.hf.chainhero.io
    links:
      - orderer.hf.chainhero.io
    networks:
      default:
        aliases:
          - peer0.org1.hf.chainhero.io

  peer1.org1.hf.chainhero.io:
    image: hyperledger/fabric-peer:x86_64-1.0.5
    container_name: peer1.org1.hf.chainhero.io
    environment:
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_VM_DOCKER_ATTACHSTDOUT=true
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_PEER_NETWORKID=chainhero
      - CORE_PEER_PROFILE_ENABLED=true
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/var/hyperledger/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/var/hyperledger/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/var/hyperledger/tls/ca.crt
      - CORE_PEER_ID=peer1.org1.hf.chainhero.io
      - CORE_PEER_ADDRESSAUTODETECT=true
      - CORE_PEER_ADDRESS=peer1.org1.hf.chainhero.io:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.hf.chainhero.io:7051
      - CORE_PEER_GOSSIP_USELEADERELECTION=true
      - CORE_PEER_GOSSIP_ORGLEADER=false
      - CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
      - CORE_PEER_LOCALMSPID=org1.hf.chainhero.io
      - CORE_PEER_MSPCONFIGPATH=/var/hyperledger/msp
      - CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer1.org1.hf.chainhero.io
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start
    volumes:
      - /var/run/:/host/var/run/
      - ./crypto-config/peerOrganizations/org1.hf.chainhero.io/peers/peer1.org1.hf.chainhero.io/msp:/var/hyperledger/msp
      - ./crypto-config/peerOrganizations/org1.hf.chainhero.io/peers/peer1.org1.hf.chainhero.io/tls:/var/hyperledger/tls
    ports:
      - 8051:7051
      - 8053:7053
    depends_on:
      - orderer.hf.chainhero.io
    links:
      - orderer.hf.chainhero.io
    networks:
      default:
        aliases:
          - peer1.org1.hf.chainhero.io

Be careful, you need to change something in the file !

In the 'docker-compose.yaml' file you need to replace BOTH --HERE-- by the name of the certificate key file located at :

heroes-service-network/crypto-config/peerOrganizations/org1.hf.chainhero.io/ca/

However, as you might have seen there is 2 files located here (the certificate and the key), the name of the file you need to copy should be something like that (finish with _sk):

943fcd5dd60bfc47beeaa0a4736f75c0b0acbe13efb95cb5444e83cf12e0521b_sk

4. Conclusion

Now that your Hyperledger-Fabric Network is perfectly set up you can launch it :

cd $GOPATH/src/github.com/chainHero/heroes-service-network && \
docker-compose up -d

If everything is working fine you must see the same output displayed above after executing the command docker ps

Enjoy your first Hyperledger Fabric network !

You can now build your application! To go further follow the tutorial to create your first application: https://chainhero.io/2018/03/tutorial-build-blockchain-app-2/

Posted by Antoine Chabert