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 withcd 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!
Top comments (15)
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
...
You also require "Template" in crypto-config.yaml, otherwise the crypto is not fully generated.
PeerOrgs:
It's also illegal to use capital letters in the naming of channel! The ordered will crash.
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
can you please share you github link for this code ? It will be very helpful
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'
Using the latest fabric images (i.e. removing all instances of ':x86_64-1.0.0-rc1') fixed this.
Thank you for your comment. I had no idea about the capital letters in the channel name causing problems! Thanks!
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.
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.
I m also facing same issue.
Not sure if this is an error, but shouldn't:
be
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.
Hey Damian, thanks for this article. Now, where can I find the next article related to this?
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
very helpful article
How can we write chaincode and maintain ledger after this? Please guide.