loading...
Cover image for Your first Hyperledger Fabric network

Your first Hyperledger Fabric network

damcosset profile image Damien Cosset Updated on ・13 min read

Introduction

In this article, we will build a simple blockchain network with Hyperledger Fabric. Fabric allows us to build a private blockchain. There are no cryptocurrencies involved. After this, you will have a decent understanding of the different parts needed to start your own private blockchain. In this example, our network will be composed of 3 organisations. Each organisation will have two peers each.

Pre-requisites

  • You must have docker and docker-compose installed. Refer to the Docker install page. To make sure you have Docker installed, you can run docker -v in your terminal. This should return something like:
Docker version 18.03.1-ce, build 9ee9f40
  • Fabric already gives us some network samples to play around and explore. To get them, open a terminal window and run: git clone -b master https://github.com/hyperledger/fabric-samples.git

This will create a fabric-samples folder with some fabric samples inside. There are a lot of useful informations in these folders, but we won't explore them here.

  • Next, we will download the platform specific binaries. This will extract some binaries that we will need later. Move into the fabric-samples folder with cd fabric-samples and run :
curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0

This will create a bin folder in your fabric-samples folder.

That's it! Now, we are ready to build our new network from scratch!

Cryptogen

First, inside your fabric-samples folder, create a new folder called cool-network, this is where all the magic will happen. Then, because we will use the 1.1.0 version, let's do a git checkout v1.1.0 to make sure there are no mistakes because of the version.

Generate our certificates and keys

Our first step will be to generate all the certificates and keys for the organisations and peers inside them. In our network, everyone will have to prove who they claim to be. The certificates we will generate will prove their identities and allow them to sign and verify transactions. Transactions will be signed by an entity's private key and verified by a public one.

To generate these materials, we will use the cryptogen tool. We got this tool by downloading the platform-specific binaries ( you have a file called cryptogen in the bin folder ). The cryptogen tool consumes a crypto-config.yaml file. So, inside our cool-network folder, go ahead and create this file. You can copy and paste the following inside and I'll explain what is going on:

OrdererOrgs:
  - Name: OrderingService
    Domain: cool-network.com
    Specs:
      - Hostname: orderer

PeerOrgs:
  - Name: Microsoft
    Domain: microsoft.cool-network.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users: 
      Count: 1
  - Name: Apple
    Domain: apple.cool-network.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users: 
      Count: 1
  - Name: IBM
    Domain: ibm.cool-network.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users:
      Count: 1

There are two parts in this file: OrdererOrgs and PeerOrgs. Before we study this file we must explain what Orderers are.

In Fabric, the Ordering Service is a collection of network entities. The orderers make sure that the transactions are dealt with in the right order ( first-come-first-serve ). The orderer is then responsible for packaging transactions into blocks.

So, what do we have in this file? We first define the Orderer Service. We give it a name, a domain and a hostname under the specs key. The naming convention goes like this: {Hostname}.{Domain}. So, our orderer will be named orderer.cool-network.com.

Next, we define our 3 organisations. We define their names and domains. The key EnableNodeOUs is set to true. This is outside the scope of this article but setting this to true will allow us to define additional policies for the network members. Finally, we have a Count key set to 1 for each organisation. This means that there will be two peers per organisation. Why? Because each organisation will have an Admin by default. So, the number of peers in an organisation will be [Count + 1].

Running the cryptogen tool

Everything is now in place for us to generate our certificates and keys. Make sure you are inside the cool-network folder and run:

../bin/cryptogen generate --config crypto-config.yaml --output=crypto-config

The cryptogen tool has a generate method that will do the job for us. We provide a config file and an output folder. You should see the following in your terminal:

microsoft.cool-network.com
apple.cool-network.com
ibm.cool-network.com

And a crypto-config file just appeared in your cool-network folder! This is where all the certificates and keys for the orderers, organisations and peers are stored.

Configtxgen

Next, we will use the configtxgen tool. This tool will do three important things:

  • create the orderer genesis block
  • create the channel configuration transaction
  • create the anchor peer transactions, one for each peer organisation

Channel: In Fabric, you have the possibility to create channels. These channels allow organisations to create private sub-networks inside the greater network. In our case, we could imagine a channel that only Microsoft and IBM would be a part of, and another that only Apple and IBM would be a part of.

Anchor peer: An anchor peer on a channel is a public peer that all others peers can discover and communicate with. Each organisation on a channel has an anchor peer.

Creating the file

The configtxgen tool consumes a configtx.yaml file. Create it and copy-paste the following:

# Profiles

Profiles:
    OrdererGenesis:
      Capabilities:
        <<: *ChannelCapabilities
      Orderer:
        <<: *OrdererDefaults
        Organizations:
          - *OrdererOrg
        Capabilities:
          <<: *OrdererCapabilities
      Consortiums:
        MyFirstConsortium:
          Organizations:
            - *Microsoft
            - *IBM
            - *Apple
    channelthreeorgs:
      Consortium: MyFirstConsortium
      Application:
        <<: *ApplicationDefaults
        Organizations:
          - *Microsoft
          - *IBM
          - *Apple
        Capabilities:
          <<: *ApplicationCapabilities


# Organizations

Organizations:

  - &OrdererOrg
    Name: OrderingService
    ID: OrdererMSP
    MSPDir: crypto-config/ordererOrganizations/cool-network.com/msp

  - &Microsoft
    Name: MicrosoftMSP
    ID: MicrosoftMSP
    MSPDir: crypto-config/peerOrganizations/microsoft.cool-network.com/msp
    AnchorPeers:
      - Host: peer0.microsoft.cool-network.com
        Port: 7051

  - &Apple
    Name: AppleMSP
    ID: AppleMSP
    MSPDir: crypto-config/peerOrganizations/apple.cool-network.com/msp
    AnchorPeers:
      - Host: peer0.apple.cool-network.com
        Port: 7051

  - &IBM
    Name: IBMMSP
    ID: IBMMSP
    MSPDir: crypto-config/peerOrganizations/ibm.cool-network.com/msp
    AnchorPeers:
      - Host: peer0.ibm.cool-network.com
        Port: 7051

# Orderer

Orderer: &OrdererDefaults

  OrdererType: solo
  Addresses: 
    - orderer.cool-network.com:7050
  BatchTimeout: 2s
  BatchSize:
    MaxMessageCount: 10
    AbsoluteMaxBytes: 99 MB
    PreferredMaxBytes: 512 KB
  Kafka:
    Brokers: 
      - 127.0.0.1:9092

  Organizations:

# Application

Application: &ApplicationDefaults

  Organizations:

# Capabilities

Capabilities:
    Global: &ChannelCapabilities
        V1_1: true
    Orderer: &OrdererCapabilities
        V1_1: true
    Application: &ApplicationCapabilities
        V1_1: true

There are a few different sections here. The most important Profiles and Organizations for now. In Profiles, we describe the orderer genesis block, our channel ( with the three organisations ) and we also defined a Consortium. Pay attention to the headers ( OrdererGenesis and channelthreeorgs) as they will be used later. In Organizations, we specify where are stored the certificates for each organisation. We just created these certificates with cryptogen. We also specify the anchor peers for each organisation. ( MSP means Membership Service Provider )

The ordererType key in the Orderer section is set to solo. Because we are in a development environment, we have only one orderer. If we were in a production environment, we would define several orderers in case one or several of them were faulty. For now, this will do just fine.

Running configtxgen

First, create a folder called channel-artifacts to hold our artifacts.

We can now run the configtxgen tool. Run the following command:

../bin/configtxgen -profile OrdererGenesis -outputBlock ./channel-artifacts/genesis.block

Notice the OrdererGenesis header we specified earlier. This will create a genesis.block file for our orderer genesis block. . You should see the following in your terminal:

2018-06-22 18:39:13.218 CEST [common/tools/configtxgen] main -> INFO 001 Loading configuration
2018-06-22 18:39:13.251 CEST [msp] getMspConfig -> INFO 002 Loading NodeOUs
2018-06-22 18:39:13.252 CEST [msp] getMspConfig -> INFO 003 Loading NodeOUs
2018-06-22 18:39:13.254 CEST [msp] getMspConfig -> INFO 004 Loading NodeOUs
2018-06-22 18:39:13.254 CEST [common/tools/configtxgen] doOutputBlock -> INFO 005 Generating genesis block
2018-06-22 18:39:13.258 CEST [common/tools/configtxgen] doOutputBlock -> INFO 006 Writing genesis block

Next, we must run a command to create our channel configuration transaction:

../bin/configtxgen -profile channelthreeorgs -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID channelthreeorgs

Notice the channelthreeorgs header we specified earlier. This will create a channel.tx file and this should appear in your terminal:

2018-06-22 18:41:42.241 CEST [common/tools/configtxgen] main -> INFO 001 Loading configuration
2018-06-22 18:41:42.263 CEST [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx
2018-06-22 18:41:42.267 CEST [msp] getMspConfig -> INFO 003 Loading NodeOUs
2018-06-22 18:41:42.271 CEST [msp] getMspConfig -> INFO 004 Loading NodeOUs
2018-06-22 18:41:42.273 CEST [msp] getMspConfig -> INFO 005 Loading NodeOUs
2018-06-22 18:41:42.317 CEST [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 006 Writing new channel tx

Next, we must create our anchor peers transactions. We will have three commands to run, one for each organisation. For Microsoft:

../bin/configtxgen -profile channelthreeorgs -outputAnchorPeersUpdate ./channel-artifacts/MicrosoftAnchor.tx -channelID channelthreeorgs -asOrg MicrosoftMSP

Notice we use the same channel header, and we use the ID we specified earlier (MicrosoftMSP). We specify a output file ( here MicrosoftAnchor.tx)

This should appear in your terminal:

2018-06-22 18:46:30.945 CEST [common/tools/configtxgen] main -> INFO 001 Loading configuration
2018-06-22 18:46:30.973 CEST [common/tools/configtxgen] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update
2018-06-22 18:46:30.976 CEST [common/tools/configtxgen] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update

Great! Now run that following two commands for IBM and Apple respectively:

../bin/configtxgen -profile channelthreeorgs -outputAnchorPeersUpdate ./channel-artifacts/IBMAnchor.tx -channelID channelthreeorgs -asOrg IBMMSP


../bin/configtxgen -profile channelthreeorgs -outputAnchorPeersUpdate ./channel-artifacts/AppleAnchor.tx -channelID channelthreeorgs -asOrg AppleMSP

Creating peer-base and docker-compose files

We are almost there, we now need to specify a few docker files to tell our network where to find some images, how to be configured...

First, create a base folder. In this folder, create two files, one called docker-compose-base.yaml and another called peer-base.yaml.

peer-base.yaml

version: '2'

services:
  peer-base:
    image: hyperledger/fabric-peer:x86_64-1.0.0-rc1
    environment:
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn
      - CORE_LOGGING_LEVEL=INFO
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_GOSSIP_USELEADERELECTION=true
      - CORE_PEER_GOSSIP_ORGLEADER=false
      - CORE_PEER_PROFILE_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start

docker-compose-base.yaml

version: '2'

services:

  orderer.cool-network.com:
    container_name: orderer.cool-network.com
    image: hyperledger/fabric-orderer:x86_64-1.0.0-rc1
    environment:
      - ORDERER_GENERAL_LOGLEVEL=INFO
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
      - ORDERER_GENERAL_GENESISMETHOD=file
      - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/genesis.block
      - ORDERER_GENERAL_LOCALMSPID=OrdererMSP
      - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
      # enabled TLS
      - 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:
    - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
    - ../crypto-config/ordererOrganizations/cool-network.com/orderers/orderer.cool-network.com/msp:/var/hyperledger/orderer/msp
    - ../crypto-config/ordererOrganizations/cool-network.com/orderers/orderer.cool-network.com/tls/:/var/hyperledger/orderer/tls
    - orderer.cool-network.com:/var/hyperledger/production/orderer
    ports:
      - 7050:7050

  peer0.microsoft.cool-network.com:
    container_name: peer0.microsoft.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.microsoft.cool-network.com
      - CORE_PEER_ADDRESS=peer0.microsoft.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.microsoft.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.microsoft.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=MicrosoftMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer0.microsoft.cool-network.com:/var/hyperledger/production
    ports:
      - 7051:7051
      - 7053:7053

  peer1.microsoft.cool-network.com:
    container_name: peer1.microsoft.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.microsoft.cool-network.com
      - CORE_PEER_ADDRESS=peer1.microsoft.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.microsoft.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.microsoft.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=MicrosoftMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/microsoft.cool-network.com/peers/peer1.microsoft.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/microsoft.cool-network.com/peers/peer1.microsoft.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer1.microsoft.cool-network.com:/var/hyperledger/production

    ports:
      - 8051:7051
      - 8053:7053

  peer0.apple.cool-network.com:
    container_name: peer0.apple.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.apple.cool-network.com
      - CORE_PEER_ADDRESS=peer0.apple.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.apple.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.apple.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=AppleMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/apple.cool-network.com/peers/peer0.apple.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/apple.cool-network.com/peers/peer0.apple.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer0.apple.cool-network.com:/var/hyperledger/production
    ports:
      - 9051:7051
      - 9053:7053

  peer1.apple.cool-network.com:
    container_name: peer1.apple.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.apple.cool-network.com
      - CORE_PEER_ADDRESS=peer1.apple.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.apple.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.apple.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=AppleMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/apple.cool-network.com/peers/peer1.apple.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/apple.cool-network.com/peers/peer1.apple.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer1.apple.cool-network.com:/var/hyperledger/production
    ports:
      - 10051:7051
      - 10053:7053

  peer0.ibm.cool-network.com:
    container_name: peer0.ibm.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.ibm.cool-network.com
      - CORE_PEER_ADDRESS=peer0.ibm.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.ibm.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.ibm.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=IBMMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/ibm.cool-network.com/peers/peer0.ibm.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/ibm.cool-network.com/peers/peer0.ibm.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer0.ibm.cool-network.com:/var/hyperledger/production
    ports:
      - 11051:7051
      - 11053:7053

  peer1.ibm.cool-network.com:
    container_name: peer1.ibm.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.ibm.cool-network.com
      - CORE_PEER_ADDRESS=peer1.ibm.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.ibm.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.ibm.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=IBMMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/ibm.cool-network.com/peers/peer1.ibm.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/ibm.cool-network.com/peers/peer1.ibm.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer1.ibm.cool-network.com:/var/hyperledger/production
    ports:
      - 12051:7051
      - 12053:7053

These files set up the base for our network, with some fabric images along with some environments variables.

Finally, the last file we will add is a docker-compose-cli.yaml file. This file will be in the root of our cool-network project. The file creates a cli container and bootstrap all of our organisations declared in our base folder.

docker-compose-cli.yaml


version: '2'

volumes:
  orderer.cool-network.com:
  peer0.microsoft.cool-network.com:
  peer1.microsoft.cool-network.com:
  peer0.apple.cool-network.com:
  peer1.apple.cool-network.com:
  peer0.ibm.cool-network.com:
  peer1.ibm.cool-network.com:

networks:
  byfn:

services:

  orderer.cool-network.com:
    extends:
      file:   base/docker-compose-base.yaml
      service: orderer.cool-network.com
    container_name: orderer.cool-network.com
    networks:
      - byfn

  peer0.microsoft.cool-network.com:
    container_name: peer0.microsoft.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.microsoft.cool-network.com
    networks:
      - byfn

  peer1.microsoft.cool-network.com:
    container_name: peer1.microsoft.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.microsoft.cool-network.com
    networks:
      - byfn

  peer0.apple.cool-network.com:
    container_name: peer0.apple.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.apple.cool-network.com
    networks:
      - byfn

  peer1.apple.cool-network.com:
    container_name: peer1.apple.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.apple.cool-network.com
    networks:
      - byfn

  peer0.ibm.cool-network.com:
    container_name: peer0.ibm.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.ibm.cool-network.com
    networks:
      - byfn

  peer1.ibm.cool-network.com:
    container_name: peer1.ibm.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.ibm.cool-network.com
    networks:
      - byfn

  cli:
    container_name: cli
    image: hyperledger/fabric-tools:x86_64-1.0.0-rc1
    tty: true
    stdin_open: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      #- CORE_LOGGING_LEVEL=DEBUG
      - CORE_LOGGING_LEVEL=INFO
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.microsoft.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=MicrosoftMSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/peers/peer0.apple.cool-network.com/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: /bin/bash
    volumes:
        - /var/run/:/host/var/run/
        - ./../chaincode/:/opt/gopath/src/github.com/chaincode
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - orderer.cool-network.com
      - peer0.microsoft.cool-network.com
      - peer1.microsoft.cool-network.com
      - peer0.apple.cool-network.com
      - peer1.apple.cool-network.com
      - peer0.ibm.cool-network.com
      - peer1.ibm.cool-network.com
    networks:
      - byfn

Great, now we can run docker-compose -f docker-compose-cli.yaml up -d. You should see something like this is your terminal:

WARNING: The COMPOSE_PROJECT_NAME variable is not set. Defaulting to a blank string.
Creating network "cool-network_byfn" with the default driver
Creating volume "cool-network_orderer.cool-network.com" with default driver
Creating volume "cool-network_peer0.microsoft.cool-network.com" with default driver
Creating volume "cool-network_peer1.microsoft.cool-network.com" with default driver
Creating volume "cool-network_peer0.apple.cool-network.com" with default driver
Creating volume "cool-network_peer1.apple.cool-network.com" with default driver
Creating volume "cool-network_peer0.ibm.cool-network.com" with default driver
Creating volume "cool-network_peer1.ibm.cool-network.com" with default driver
Creating peer1.apple.cool-network.com     ... done
Creating peer0.apple.cool-network.com     ... done
Creating orderer.cool-network.com         ... done
Creating peer1.microsoft.cool-network.com ... done
Creating peer1.ibm.cool-network.com       ... done
Creating peer0.ibm.cool-network.com       ... done
Creating peer0.microsoft.cool-network.com ... done
Creating cli                              ... done

Now, we can run our cli container with docker start cli and enter inside the container with docker exec -it cli bash:

➜  cool-network git:(1252c7a) ✗ docker exec -it cli bash
root@9f8760ee6be8:/opt/gopath/src/github.com/hyperledger/fabric/peer#

Tadaaaa, our network is now running!! You can explore the different folders, you will find all the certificates, variables and everything that we defined in our yaml files.

Conclusion

I hope this tutorial was clear enough for you to understand how to setup a Hyperledger Fabric environment. Of course, for now, this network can't do much without any chaincode ( or smart contracts ). This will be the topic for a later article. Have fun!

Discussion

pic
Editor guide
Collapse
jean507 profile image
Jean Le Bouthillier

Did you test this code before posting?

You generate the genesis block as "genesis.block" and later on use "orderer.genesis.block"

../bin/configtxgen -profile OrdererGenesis -outputBlock ./channel-artifacts/genesis.block

...

  • ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block

You also require "Template" in crypto-config.yaml, otherwise the crypto is not fully generated.

PeerOrgs:

  • Name: Microsoft Domain: microsoft.cool-network.com EnableNodeOUs: true Template: Count: 2 Users: Count: 1

It's also illegal to use capital letters in the naming of channel! The ordered will crash.

Collapse
danionita profile image
danionita

Actually, changing
'ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block'
to
'ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/genesis.block'
breaks the code, because '/var/hyperledger/orderer/genesis.block' does not exist.

The original code was correct because in docker-compose-base.yaml, you mount the following volume:
../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block

Collapse
saifdeveloper profile image
Saif Ali

can you please share you github link for this code ? It will be very helpful

Collapse
danionita profile image
danionita

However, after fixing this, Ithe orderer fails to start with the following error:
' Error creating configtx manager and handlers: Error deserializing key Capabilities for group /Channel: Unexpected key Capabilities'

Collapse
danionita profile image
danionita

Using the latest fabric images (i.e. removing all instances of ':x86_64-1.0.0-rc1') fixed this.

Collapse
damcosset profile image
Damien Cosset Author

Thank you for your comment. I had no idea about the capital letters in the channel name causing problems! Thanks!

Collapse
jbgodilo profile image
Jeson Godilo

Hi, Thanks for this very good article of you. Though seems like you've got a wrong pattern of configuration in configtx.yaml. When I tried your configuration I've got an error. And so I put the Profiles at the very end of the file and it works. I think you should put the Profile then at the very end part of the file. Thank you.

Collapse
tharinducs profile image
Tharindu Sandaruwan

when I try to create a channel after setting up this network It is giving me an error of like this.

2019-01-19 12:05:06.702 UTC [msp] getMspConfig -> WARN 001 Intermediate certs folder not found at [/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp/intermediatecerts]. Skipping. [stat /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp/intermediatecerts: no such file or directory]
2019-01-19 12:05:06.712 UTC [msp] getMspConfig -> WARN 002 TLS intermediate certs folder not found at [/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp/tlsintermediatecerts]. Skipping. [stat /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp/tlsintermediatecerts: no such file or directory]
2019-01-19 12:05:06.713 UTC [msp] getMspConfig -> WARN 003 crls folder not found at [/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp/crls]. Skipping. [stat /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp/crls: no such file or directory]
2019-01-19 12:05:06.714 UTC [msp] getMspConfig -> INFO 004 MSP configuration file not found at [/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp/config.yaml]: [stat /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp/config.yaml: no such file or directory]
Error: Error connecting due to rpc error: code = Unavailable desc = grpc: the connection is unavailable
Usage:
peer channel create [flags]

Flags:
-c, --channelID string In case of a newChain command, the channel ID to create.
-f, --file string Configuration transaction file generated by a tool such as configtxgen for submitting to orderer
-t, --timeout int Channel creation timeout (default 5)

Global Flags:
--cafile string Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
--logging-level string Default logging level and overrides, see core.yaml for full syntax
-o, --orderer string Ordering service endpoint
--test.coverprofile string Done (default "coverage.cov")
--tls Use TLS when communicating with the orderer endpoint
-v, --version Display current version of fabric peer server

I tried it with this command.

peer channel create -o orderer.cool-network.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.t
x --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/cool-network.com/orderers/orderer.cool-network.com/ms
p/tlscacerts/tlsca.cool-network.com-cert.pem

Can you help me to solve this problem? Thank you.

Collapse
venki208 profile image
duddu venkatesh

I m also facing same issue.

Collapse
danionita profile image
danionita

Not sure if this is an error, but shouldn't:

CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls/server.crt
CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls/server.key
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/peers/peer0.apple.cool-network.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp

be

CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls/server.crt
CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls/server.key
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/**microsoft**.cool-network.com/peers/peer0.**microsoft**.cool-network.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/**microsoft**.cool-network.com/users/Admin@**microsoft**.cool-network.com/msp
Collapse
jbgodilo profile image
Jeson Godilo

Hi Damien,

I successfully started the network created using your tutorial above. Now, what I am trying to do is install a business network archive file in one of 3 organizations but unfortunately I encountered an error doing that. I don't if it is because of the version. Because I also followed the one that use the first-network and I successfully install the file in the network. Version used in first-network is 1.2.0.

Collapse
_aisahihoonmain profile image
Swapnil K. Deshmukh

Hey Damian, thanks for this article. Now, where can I find the next article related to this?

Collapse
marcelloromani profile image
Marcello Romani

Thanks for the well written article.

My question is what is the role of MicrosoftAnchor.tx

I don't see it referenced in the docker compose files.

Thanks

Collapse
chudamaniestam profile image
chudamani

very helpful article

Collapse
planetsamee profile image
Samee Shah

How can we write chaincode and maintain ledger after this? Please guide.