Guide to setting up your first Hyperledger Fabric network (Part 2)
Overview
This part serves a next step after completing part 1 of the guide. In part 1, we discussed the different components that are needed to bootstrap a simple network. We formed one organization, created a channel, and joined that organization to that channel.
In this part, we are going to write a chaincode (smart contract), install and instantiate it, and interact with it. We are going to use the repository that we developed in the previous guide. The repository contains both the network and chaincode as well as useful scripts to automate crucial tasks.
What is chaincode?
Chaincode (smart contract) is a piece of code that is used to provide access to the state of the ledger in a channel. Chaincode is the only way to gain access to the ledger and the ledger cannot be accessed outside of that chaincode. Chaincode can also be used to implement access control permissions as well as complex business logic while updating or reading the data in the ledger.
If you have experience writing smart contracts using Solidity in Ethereum or other public blockchain, you might notice similarities. We have a chaincode class named FirstChaincode which has two functions that are available to be executed from outside the ledger. initLedger function adds car entries into the ledger. The second function queryAllCars returns all the car objects that have been initialized.
We use the chaincode utils developed by the TheLedger. You will find the chaincode Node.js SDK to be quite different if you look at the official chaincode samples developed by Hyperledger Fabric. These utilities are intended to make writing chaincode easier.
We are going to start the network that we built in the previous article, create and join channels, install and instantiate the chaincode, and finally call functions on the chaincode.
Building the network
Go to the network directory and run the following commands.
Starting the network
This command will start all the docker containers.
docker-compose -f docker-compose.yml up -d
Creating and joining the channel
A new channel mychannel is created and Org1 is joined to that channel.
We created a simple chaincode which adds entries in the ledger and queries them. We might get into exploring the Node.js SDK that enables us to build client applications for Hyperledger Fabric network.
If you want to get your hands on the code, you can get it here.
Guide to setting up your first Hyperledger Fabric network (Part 1)
There are two ways to go about building applications on Hyperledger Fabric framework. The first method is to use Composer and the other is work directly on core Fabric and writing chaincode using Golang, Node.js, or Java.
What is Composer and why you should stay away from it?
Hyperledger Composer is a set of tools that makes the whole process of building blockchain application faster and easier. Composer speeds up the development time significantly and provides RESTful APIs for your applications to interact with.
Composer also abstracts away essential development steps that would otherwise prove crucial to understand critical parts of the Fabric framework. While the tool is helpful for rapid prototyping and can prove vital for a non-technical or a beginner to get started, however it does abstract away the most interesting parts of the technology.
Composer is helpful to get started on learning the technology but it you wish to understand the ins and outs of technology, Composer is not the way to go.
Here, we will be building a small network with one ordering service and one organization. We will be creating one channel for that organization and bootstrap one anchor peer in this part.
In the next part, we will then be using Typescript to write chaincode in Node.js environment and install it on the peer to provide access to the ledger.
If you wish to get your hands on the code, you can find the repository here.
Installing the development environment
If you haven’t already set up the development environment for Hyperledger Fabric, I urge you to head to this article I wrote a week ago.
What we will be building
We will be creating a simple network with one ordering service (orderer), one organization with one peer. We will create one channel and then install chaincode on that channel. In real life, one channel with one organization makes no sense but we are building it like this for the sake of simplicity.
If you are not familiar with the terms that I used and want to learn the basic of Fabric, there is no better place than the official documentation.
Let’s get started
Create a new directory and name it first-network. This will be our root directory for the project.
Create a new directory inside first-network and name it network.
Create a new file call crypto-config.yaml inside network directory.
Defining orderer and organizations in crypto-config.yaml
We define the orderer and different organizations that we want to be part of the network in a .yaml file. We normally call it crypto-config.yaml. Put the following in the crypto-config.yaml file.
As we can see, we have defined one orderer and one organization. The domain/ID of the orderer is orderer.example.com and the domain of the peer organization is org1.example.com. The Template Count defines the number of peers that we want to bootstrap as part of the network and Users Count defines the number of users that will belong to that organization when the network is first created.
Defining specifications of the orderer and organizations in configtx.yaml
Create a new file called configtx.yaml inside the network directory. The project structure will now look like this.
First we define the MSP IDs of our Orderer and Org1 and also define the paths to the certificates that we will generate later. The path that we define in MSPDir does not exist right now. We will generate the certificates and create the paths later. Here, we also define the domain and port of anchor peers for our organization.
The we configure the capabilities of our network as having the ability to create new channels, etc,. Then we define Orderer specifications as running on solo consensus algorithm and its port.
Finally, we define Profiles that we will be using to refer to these specifications. We define the genesis block for our Orderer as OneOrgOrdererGenesis. The thing that we need to understand here is that there is no global blockchain ledger in the Fabric framework and ledgers are only available at the channel level. And there are two types of channels in a Fabric network, a system channel that is used by different orderers in the network and application channels that are composed of different peers at the application level. OneOrgOrdererGenesis is the profile name of the genesis block of the ledger in the system channel that is used to start the Orderer.
Then we define a consortium called SampleConsortium with Org1 as part of that consortium. And then we have the profile name of our channel called OneOrgChannel with Org1 as a member of that channel.
Create cryptographic materials
Open a terminal window in the /first-network/network directory and execute these commands.
cryptogen generate --config=./crypto-config.yaml
The Cryptogen tool that we installed in the previous article will be used to generate crypto materials to be used when signing transactions. This will create a new directory and output two more directories inside it. Our project looks like this now.
The new directories will have the crypto material for our orderer and peer organization.
Create genesis block and configuration transactions
Execute the following commands to generate a genesis block, a channel transaction, and an anchor peer configuration transaction. We will then use these configuration transactions to bootstrap a Fabric network.
Configtxgen tool that we installed in the previous article will be used to generate configuration transactions.
configtxgen uses the profile that we defined in the configtx.yaml file. The tool will look for the profile named OneOrgOrdererGenesis in the configtx.yaml.
The tool will look for a channel profile named OneOrgChannel and output a configuration transaction named channel.tx in the /config directory. We also provided the ID of the channel.
Now that we have the configuration transactions, we will now move on to using these configuration transactions to start Orderer and create a channel.
Configuring docker-compose.yml
We will be using a tool called docker-compose to start multiple docker containers that will work to simulate a Fabric network. To make things simpler, we will not be using multiple machines, we will be taking advantage of the power of docker and docker-compose to simulate multiple machines.
We will not be talking much about docker-compose here. If you want to learn more, visit docker’s documentation.
Create a new file called docker-compose.yml inside /first-network/network directory.
Paste this in docker-compose.yml.
version: '2'
networks:
basic:
services:
ca.example.com:
image: hyperledger/fabric-ca
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca.example.com
- FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem
- FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/c8934e1a2f95d83d34852d9615f7c92880947bc1a077a9c0ae393fa33e8e6454_sk
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
volumes:
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
container_name: ca.example.com
networks:
- basic
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer
environment:
- ORDERER_GENERAL_LOGLEVEL=debug
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/msp/orderer/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/orderer
command: orderer
ports:
- 7050:7050
volumes:
- ./config/:/etc/hyperledger/configtx
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/:/etc/hyperledger/msp/orderer
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/msp/peerOrg1
networks:
- basic
peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_PEER_ID=peer0.org1.example.com
- CORE_LOGGING_PEER=debug
- CORE_CHAINCODE_LOGGING_LEVEL=DEBUG
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
# # the following setting starts chaincode containers on the same
# # bridge network as the peers
# # https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_basic
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984
# The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
# provide the credentials for ledger to connect to CouchDB. The username and password must
# match the username and password set for the associated CouchDB.
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: peer node start
# command: peer node start --peer-chaincodedev=true
ports:
- 7051:7051
- 7053:7053
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/msp/peer
- ./crypto-config/peerOrganizations/org1.example.com/users:/etc/hyperledger/msp/users
- ./config:/etc/hyperledger/configtx
depends_on:
- orderer.example.com
- couchdb
networks:
- basic
couchdb:
container_name: couchdb
image: hyperledger/fabric-couchdb
# Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
# for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
environment:
- COUCHDB_USER=
- COUCHDB_PASSWORD=
ports:
- 5984:5984
networks:
- basic
cli:
container_name: cli
image: hyperledger/fabric-tools
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
- CORE_CHAINCODE_KEEPALIVE=10
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/phr
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
networks:
- basic
As you can probably guess, we will be using docker-compose to start five containers namely ca.example.com, orderer.example.com, peer0.org.example.com, couchdb, and cli.
ca.example.com will be used to issue identities to the users in the network. The certificate authority is owned by Org1.
orderer.example.com will be the orderer of our network.
peer0.org.example.com will be the only peer in our network which will host our ledger and chaincode.
couchdb is the container for the database.
cli is used to install and instantiate chaincode on peer0 owned by Org1.
The orderer container uses the genesis.block that we generated earlier to start the orderer.
Before we start the network, we need to do a very important change in the docker-compose.yml.
Execute this command from the network directory.
ls crypto-config/peerOrganizations/org1.example.com/ca
You will see a file with _sk appended at the end. Copy the name of the file, the secret key of our CA. Go back to docker-compose.yml file and search for the keyword “secret_key_here”. Replace the phrase “secret_key_here” with the name of the file you just copied. We are good to go now.
Starting the network
Run the command to start the network.
docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb
The command will start four containers that will form our network.
You can verify the containers that are running by executing the command.
docker ps
You should see an output like this.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
621bbda9f6ac hyperledger/fabric-peer "peer node start" 4 seconds ago Up 3 seconds 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp peer0.org1.example.com
1e3f3476f727 hyperledger/fabric-orderer "orderer" 7 seconds ago Up 4 seconds 0.0.0.0:7050->7050/tcp orderer.example.com
32fcf0d2baa9 hyperledger/fabric-ca "sh -c 'fabric-ca-se…" 7 seconds ago Up 4 seconds 0.0.0.0:7054->7054/tcp ca.example.com
de9b898e3c09 hyperledger/fabric-couchdb "tini -- /docker-ent…" 7 seconds ago Up 4 seconds 4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp couchdb
If you see a similar output as above, you have successfully started a Hyperledger Fabric network.
Now, we will create a channel and join Org1 to that channel.
Creating and joining channel
Executing the following command will create a new channel called mychannel.
Now, our peer from Org1 is joined to the channel mychannel.
Conclusion
We created the simplest network with one orderer and one organization. In reality, there are multiple orderers and multiple organizations connected to multiple channels. We might get into exploring it later down the line.
If you want to get your hands on the code, you can get it here.
In the next part, we will learn to code chaincode in Node.js and install it on our peer.
The Right Way To Set-up The Hyperledger Fabric Development Environment
Hyperledger Fabric is an exciting technology and is progressing rapidly with the approach of move fast and break things so it can sometimes turn out to be a soul-destroying task to set up the Fabric development environment. Even the official documentation falls short of discussing everything there is in setting up the environment. So, I have written this guide to lay down all the steps you will need to go through to set up the development environment. I will try to keep this guide updated to reflect the latest changes in the Fabric protocol.]
Understanding the basics
I am not going to bore you with explaining what blockchain is and why it matters and explain the use cases of permissioned blockchain technology frameworks like Hyperledger Fabric. If you want to learn the basics of blockchain, Hyperledger Fabric, and its use cases. There is no better way than to study the official documentation here.
Installing the development environment
Installing one wrong package version might generate errors that can take days to debug. These steps have been tested to work well on Ubuntu 18.04 LTS.
Let us get started.
Installing cURL
cURL is a tool that is used to transfer data over the internet.
Execute the command to install cURL.
sudo apt-get install curl
Installing Docker
Docker is a tool designed to make it easier to create, deploy, and run applications in virtual containers. We will use docker to set up simulate different peers in the network. We use docker CLI container to interact with the peers and ordering service, install and upgrade chaincode, and create and join channels.
Uninstall previous docker packages.
If you previously installed docker on your machine. You will need to remove all previous docker packages.
To identify what installed package you have:
dpkg -l | grep -i docker
If you see packages like docker-engine, docker, docker.io. Write them like in the command below. It is possible that you have other packages of docker, you will need to uninstall them too.
The above commands will not remove images, containers, volumes, or user created configuration files on your host. If you wish to delete all images, containers, and volumes run the following commands:
You need to eliminate the requirement of using sudo while working with docker
Create the docker group.
sudo groupadd docker
Add your user to the docker group.
sudo usermod -aG docker $USER
Log out and log back in.
Try running the docker command without sudo and verify if the above steps were successful.
docker run hello-world
Installing docker-compose
Docker Compose is a tool for running multi-container Docker applications. You need to define all the containers that your application depends on in a .yaml file. Then, with one single command, all the service are started and your application starts running.
Run this command to download the latest version of Docker Compose.
Go language is used to write chaincode business logic for the channels. You can also write chaincode in Node.js and Java. Whichever language you decide to use, you need to set up the $GOPATH.
You need to set a new prefix for npm to eliminate the need of using sudo while installing packages.
Go to your home directory and create a directory for global installations.
mkdir ~/.npm-global
Configure npm to use the new directory path for installations.
npm config set prefix '~/.npm-global'
Open the file~/.profile file.
nano ~/.profile
Add this line at the bottom of the file.
export PATH=~/.npm-global/bin:$PATH
Save the file and exit with CTRL + X, press Y, and then press ENTER.
On the command line, update your system variables:
source ~/.profile
Installing Hyperledger Fabric packages.
The documentation of Hyperledger Fabric provides a script that will download and install samples and binaries to your system. These sample applications installed are useful to learn more about the capabilities and operations of Hyperledger Fabric.
Go to your home directory and execute the following command.
This will install 1.4 version of Hyperledger Fabric binaries.
The command above downloads and executes a bash script that will download and extract all of the platform-specific binaries you will need to set up your network.
It also retrieves some executable binaries that are needed in development and places them in the bin sub-directory of the current working directory.
To set these binaries to be run from anywhere on your machine. Open the file~/.profile file.
nano ~/.profile
Add this line at the bottom.
export PATH=~/fabric-samples/bin:$PATH
Save the file and exit with CTRL + X, press Y, and then press ENTER.
On the command line, update your system variables:
source ~/.profile
Run the sample network
Go to the first-network directory.
cd fabric-samples/first-network
Run the following command to generate crypto materials, start the network, and install chaincode.
./byfn.sh up
The above command will bootstrap a sample network with fabcar chaincode installed. You can head to here to learn more about the network that we have just started.
Conclusion
After a year of development on Hyperledger Fabric framework, I have realized the importance of getting small things right when setting up the environment. Many errors that you might face during development might well be due to the mistakes in setting up the environment.
I hope this guide will help beginners starting to learn this new technology. Please feel free to point out mistakes in this guide.
Get in touch
Interested in starting your own blockchain project, but don’t know how? Get in touch at https://xord.solutions/contact