Demo of Three-Node Two-Channel Setup in Hyperledger Fabric

Overview

Since the demo of a multi-channel setup (link) on a localhost is published last December, I keep receiving questions about a multi-node deployment. This is by all means the most common production setup, in which each organization has their own infrastructure setup in their own datacenter.

Setup

It is a very simple setup. In this fabric network we only have one orderer. There are total three organizations, in each of which a peer node is configured. For simplicity we take out most of components, and only observe the behaviour of setting up channels in multiple nodes.

Demo Steps

The process in this demo follows what we learn from Build Your First Network (BYFN). What’s new is to crate four nodes on AWS.

Step 1: Bring Up the Four Nodes

Step 1.1: Create 4 AWS EC2 instances

  • Select Ubuntu 16.04 LTS
  • Use t2.small instances
  • For demo purpose, just use Security Group that open everything. In production, only open those IP and ports which is needed
  • Orderer
  • Node 1 for Org1
  • Node 2 for Org2
  • Node 3 for Org3
The four EC2 instances for demonstration.
$ cd fabric-samples/first-network
$ ./byfn.sh up
$ ./byfn.sh down
It is only the IP addresses of my EC2 instances. Use your own in your setup.

Step 2: Generate Crypto and Network Artifacts

As a practice of Build Your First Network (BYFN), we first prepare configurations. In this demo I use my own localhost.

$ cd fabric-samples
$ mkdir 3node2channel && cd 3node2channel
$ mkdir channel-artifacts
$ mkdir deployment
$ ../bin/cryptogen generate —-config=./crypto-config.yaml
$ export FABRIC_CFG_PATH=$PWD
$ ../bin/configtxgen -profile ThreeOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
$ ../bin/configtxgen -profile ChannelAll -outputCreateChannelTx ./channel-artifacts/channelall.tx -channelID channelall$ ../bin/configtxgen -profile Channel12 -outputCreateChannelTx ./channel-artifacts/channel12.tx -channelID channel12

Step 3: Examine the Docker-Compose Files

Another set of important files are the docker compose files, which determine what and how nodes are brought up and running for the setup.

  • docker-compose-base.yml: This is the base for both orderers and peers. This file is referred in other docker compose files.
  • docker-compose-orderer.yml: This is for orderer node.
  • docker-compose-node#.yml: This is for node of Org1, Org2 and Org3.
  • As said, the directory structure has been considered. If you are not following the previous steps, make sure you update the directory (mainly on the volumes)
  • There are entries of extra hosts (extra_hosts). It is quite straight forward: what we need is to specify other nodes with their (private) IP addresses. These entries will then be configured inside /etc/hosts of the containers.
  • Each Org comes with a peer and a CLI. We will use CLI for chaincode operations.

Step 4: Upload the 3node2channel Directory to All Nodes

In my local host

// fabric-samples directory
$ tar cf 3node2channel.tar 3node2channel/
// update to all nodes (use your own key file and public IP addresses)
$ scp -i ~/Downloads/aws.pem 3node2channel.tar ubuntu@3.90.64.249:/home/ubuntu/fabric-samples/
$ scp -i ~/Downloads/aws.pem 3node2channel.tar ubuntu@3.92.233.164:/home/ubuntu/fabric-samples/
$ scp -i ~/Downloads/aws.pem 3node2channel.tar ubuntu@18.233.151.196:/home/ubuntu/fabric-samples/
$ scp -i ~/Downloads/aws.pem 3node2channel.tar ubuntu@52.23.207.17:/home/ubuntu/fabric-samples/
My localhost

Step 5: Extract the Directory and Bring Up Nodes

For all nodes

// in fabric-samples
$ tar xf 3node2channel
$ cd 3node2channel/deployment
$ docker-compose -f docker-compose-orderer.yml up -d
$ docker ps
Orderer Node
$ docker-compose -f docker-compose-node1.yml up -d
$ docker ps
Node 1 for Org1
$ docker-compose -f docker-compose-node2.yml up -d
$ docker ps
Node 2 for Org2
$ docker-compose -f docker-compose-node3.yml up -d
$ docker ps
Node 3 for Org3

Step 6: Setup Channel channelall

$ docker exec -e "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel create -o orderer.example.com:7050 -c channelall -f /var/hyperledger/configs/channelall.tx
Node 1
$ docker exec -e "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel join -b channelall.block
Node 1: peer0.org1 joins channelall
// node1
$ docker cp peer0.org1.example.com:channelall.block .
// localhost$ scp -i ~/Downloads/aws.pem ubuntu@3.92.233.164:/home/ubuntu/fabric-samples/3node2channel/deployment/channelall.block .$ scp -i ~/Downloads/aws.pem channelall.block ubuntu@18.233.151.196:/home/ubuntu/fabric-samples/3node2channel/deployment/$ scp -i ~/Downloads/aws.pem channelall.block ubuntu@52.23.207.17:/home/ubuntu/fabric-samples/3node2channel/deployment/// node2
$ docker cp channelall.block peer0.org2.example.com:/channelall.block
// node3
$ docker cp channelall.block peer0.org3.example.com:/channelall.block
Node 1: copy the channelall.block from peer0.org1 to Node 1
My localhost: scp the channelall.block from Node 1 and to Node 2 and 3
Node 2: copy the channelall.block from Node 2 to peer0.org2
Node 3: copy the channelall.block from Node 3 to peer0.org3
$ docker exec -e "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/users/Admin@org2.example.com/msp" peer0.org2.example.com peer channel join -b channelall.block
Node 2: peer0.org2 joins channelall
$ docker exec -e "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/users/Admin@org3.example.com/msp" peer0.org3.example.com peer channel join -b channelall.block
Node 3: peer0.org3 joins channelall

Step 7: Chaincode Operations

We are using Simple Asset Chaincode (sacc), which is already inside fabric-sample.

$ docker exec -it cli peer chaincode install -n mycc -p github.com/chaincode/sacc -v v0
Chaincode Installation in All nodes: here Node 1 is shown
$ docker exec -it cli peer chaincode instantiate -o orderer.example.com:7050 -C channelall -n mycc github.com/chaincode/sacc -v v0 -c '{"Args": ["a", "100"]}' -P "OR('Org1MSP.member', 'Org2MSP.member','Org3MSP.member')"
Chaincode Instantiation with “a” set to 100 on Node 1
$ docker exec -it cli peer chaincode query -C channelall -n mycc -c '{"Args":["query","a"]}'
Query value of “a” on Node 2
$ docker exec -it cli peer chaincode invoke -o orderer.example.com:7050 -C channelall -n mycc -c '{"Args":["set","a", "200"]}'
Invoke to set value of “a” to 200 on Node 3
$ docker exec -it cli peer chaincode query -C channelall -n mycc -c '{"Args":["query","a"]}'
Query the value of “a” again on Node 2

Step 8: Setup Channel channel12 and Chaincode Instantiation

This is same as Step 6 and 7, but now we are working on channel12. I omit those screenshot as it’s almost the same as in Step 6.

$ docker exec -e "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel create -o orderer.example.com:7050 -c channel12 -f /var/hyperledger/configs/channel12.tx
$ docker exec -e "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel join -b channel12.block
// node1
$ docker cp peer0.org1.example.com:channel12.block .
// localhost$ scp -i ~/Downloads/aws.pem ubuntu@3.92.233.164:/home/ubuntu/fabric-samples/3node2channel/deployment/channel12.block .$ scp -i ~/Downloads/aws.pem channel12.block ubuntu@18.233.151.196:/home/ubuntu/fabric-samples/3node2channel/deployment/// node2
$ docker cp channel12.block peer0.org2.example.com:/channel12.block
$ docker exec -e "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/users/Admin@org2.example.com/msp" peer0.org2.example.com peer channel join -b channel12.block
$ docker exec -it cli peer chaincode instantiate -o orderer.example.com:7050 -C channel12 -n mycc github.com/chaincode/sacc -v v0 -c '{"Args": ["b", "1"]}' -P "OR('Org1MSP.member', 'Org2MSP.member')"
Chaincode Instantiation with “b” set to 1 on Node 1, on channel12
$ docker exec -it cli peer chaincode query -C channel12 -n mycc -c '{"Args":["query","b"]}'
Query value of “b” from Node 2
Query value of “b” from Node 3: Org3 is not in channel12
$ docker exec -it cli peer chaincode query -C channelall -n mycc -c '{"Args":["query","b"]}'
Query value of “b” from chanelall on Node 1

Step 9 Clean Up

When we complete our setup, we can clean up everything.

// orderer
$ docker-compose -f docker-compose-orderer.yml down
// node1
$ docker-compose -f docker-compose-node1.yml down
$ docker rm $(docker ps -aq)
$ docker rmi $(docker images net-* -q)
// node2
$ docker-compose -f docker-compose-node2.yml down
$ docker rm $(docker ps -aq)
$ docker rmi $(docker images net-* -q)
// node3
$ docker-compose -f docker-compose-node3.yml down
$ docker rm $(docker ps -aq)
$ docker rmi $(docker images net-* -q)

Summary

In this article we show how to deploy a three-node setup for three organizations. Although it seems a bit complicated, the logic is quite straight forward. We largely use what we learn from Build Your First Network (BYFN), and with careful preparation of the docker compose files, we demonstrate how multiple channels are created and observe the behaviour of same chaincode across multiple channels.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store