Blockchains technology has been a topic of discussion from past few years in industry. The distributed and immutable nature of blockchains coupled with strong cryptography is assumed useful in almost every field of technology from finance to IoT. In this post, we would like to share our learning acquired during setting up hyperledger on photon OS. I will walk through the steps to install hyperledger on Photon VM and then connecting three peer nodes that includes two validating nodes and one member service node. Prior to going to installation, we will first go through a brief discussion on what is hyperledger blockchain.
Hyperledger is termed as Distributed Permissioned Ledger where validators can be whitelisted and blacklisted. Unlike other blockchains, hyperledger project allows developers to create their own digital assets with a distributed ledger powered by nodes built on the principle of PBFT. The system could be used to digitally back a real asset (such as a house), create new coins, or form a fault-tolerant system of consensus. Hyperledger blockchain allows user to write chaincode, a business rules script executed within a transaction.
Following are the steps to install and configure three-node hyperledger blockchain on Photon OS using Docker virtualization tools for development purpose. The entire installation and configurations takes less than 60 minutes.
Prerequisites:
- Download and install photon OS. Click here to download Photon OS. We recommend the minimum of 4GB memory and 10 GB hard disk to be allocated for the VM. Select "Photo Full" option while installing the operating system. Click here for more details.
- Enable SSH in photon OS, to do this change "PermitRootLogin no" to "PermitRootLogin yes" in /etc/ssh/sshd_config file. This is required as we need to open multiple terminal for the VM to run chain code and peer nodes.
- Check for updates and verify that latest version of Docker is available.
- # docker -v
- # tdnf update docker, output of the command should look something like below
- Since hyperledger fabric project is written using go lang, make sure latest version of go is installed by updating it.
- Install docker-compose using following curl command
# curl -L "https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
Check docker-compose version using command,
# docker-compose version
- Start Docker by executing following commands
# systemctl start docker
# systemctl enable docker
Pulling the Hyperledger Fabric images and running peer nodes
Use following commands to pull in latest images for hyperledger fabric and membership services from DockerHub.
# docker pull hyperledger/fabric-peer:latest
# docker pull hyperledger/fabric-membersrvc:latest
Now run the peer node and member service using docker-compose, to do that we need to build a docker-compose.yml file.
Create a file with name docker-compose.yml and copy following contents to the file. Running this file will start a blockchain with three nodes that has one member service node and two validating nodes.
version: '2'
services:
membersrvc:
image: hyperledger/fabric-membersrvc:latest
ports:
- "7054:7054"
command: membersrvc
environment:
- MEMBERSRVC_CA_LOGGING_SERVER=INFO
- MEMBERSRVC_CA_LOGGING_CA=INFO
- MEMBERSRVC_CA_LOGGING_ECA=INFO
- MEMBERSRVC_CA_LOGGING_ECAP=INFO
- MEMBERSRVC_CA_LOGGING_ECAA=INFO
- MEMBERSRVC_CA_LOGGING_ACA=INFO
- MEMBERSRVC_CA_LOGGING_ACAP=INFO
- MEMBERSRVC_CA_LOGGING_TCA=INFO
- MEMBERSRVC_CA_LOGGING_TCAP=INFO
- MEMBERSRVC_CA_LOGGING_TCAA=INFO
- MEMBERSRVC_CA_LOGGING_TLSCA=INFO
volumes:
- /var/run/docker.sock:/var/run/docker.sock
vp0:
image: hyperledger/fabric-peer:latest
ports:
- "7050:7050"
- "7051:7051"
- "7053:7053"
command: sh -c "sleep 10; peer node start"
environment:
- CORE_PEER_ID=vp0
- CORE_SECURITY_ENROLLID=test_vp0
- CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT
- CORE_PEER_DISCOVERY_PERIOD=60s
- CORE_PEER_DISCOVERY_TOUCHPERIOD=61s
- CORE_PEER_ADDRESSAUTODETECT=true
- CORE_VM_ENDPOINT=unix:///var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_PKI_ECA_PADDR=membersrvc:7054
- CORE_PEER_PKI_TCA_PADDR=membersrvc:7054
- CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054
- CORE_SECURITY_ENABLED=true
- CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft
- CORE_PBFT_GENERAL_MODE=batch
- CORE_PBFT_GENERAL_N=4
volumes:
- /var/run/docker.sock:/var/run/docker.sock
links:
- membersrvc
vp1:
image: hyperledger/fabric-peer:latest
ports:
- "8050:7050"
- "8051:7051"
- "8053:7053"
command: sh -c "sleep 10; peer node start"
environment:
- CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051
- CORE_PEER_ID=vp1
- CORE_SECURITY_ENROLLID=test_vp1
- CORE_SECURITY_ENROLLSECRET=5wgHK9qqYaPy
- CORE_PEER_DISCOVERY_PERIOD=60s
- CORE_PEER_DISCOVERY_TOUCHPERIOD=61s
- CORE_PEER_ADDRESSAUTODETECT=true
- CORE_VM_ENDPOINT=unix:///var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_PKI_ECA_PADDR=membersrvc:7054
- CORE_PEER_PKI_TCA_PADDR=membersrvc:7054
- CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054
- CORE_SECURITY_ENABLED=true
- CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft
- CORE_PBFT_GENERAL_MODE=batch
- CORE_PBFT_GENERAL_N=4
volumes:
- /var/run/docker.sock:/var/run/docker.sock
links:
- membersrvc
- vp0
vp2:
image: hyperledger/fabric-peer:latest
ports:
- "9050:7050"
- "9051:7051"
- "9053:7053"
environment:
- CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051
- CORE_PEER_ID=vp2
- CORE_SECURITY_ENROLLID=test_vp2
- CORE_SECURITY_ENROLLSECRET=vQelbRvja7cJ
- CORE_PEER_DISCOVERY_PERIOD=60s
- CORE_PEER_DISCOVERY_TOUCHPERIOD=61s
- CORE_PEER_ADDRESSAUTODETECT=true
- CORE_VM_ENDPOINT=unix:///var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_PKI_ECA_PADDR=membersrvc:7054
- CORE_PEER_PKI_TCA_PADDR=membersrvc:7054 - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054 - CORE_SECURITY_ENABLED=true - CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft - CORE_PBFT_GENERAL_MODE=batch - CORE_PBFT_GENERAL_N=4 volumes: - /var/run/docker.sock:/var/run/docker.sock links: - membersrvc - vp0
Run following command to start a blockchain with three peer nodes.
# docker-compose up |
Running chaincode
Start a new terminal window. We need to download a sample chaincode available in Docker fabric source code repository. Copy the chaincode to src directory in the $GOPATH as shown below.
# mkdir -p $GOPATH/src/github.com/chaincode_example02/
# cd $GOPATH/src/github.com/chaincode_example02
# curl --request GET https://raw.githubusercontent.com/hyperledger/fabric/master/examples/chaincode/go/chaincode_example02/chaincode_example02.go> chaincode_example02.go
Prior to deploying the chaincode we need to build the chaincode. Clone hyperledger fabric project to $GOPATH folder so that you can build your chaincode.
# mkdir -p $GOPATH/src/github.com/hyperledger
# cd $GOPATH/src/github.com/hyperledger
# git clone http://gerrit.hyperledger.org/r/fabric
Now build the chaincode using following command
# cd $GOPATH/src/github.com/chaincode_example02
# go build
Deploy Chaincode
Now that you have build the chaincode, it can be deployed using following chaincode command
# CORE_CHAINCODE_ID_NAME=mycc CORE_PEER_ADDRESS=0.0.0.0:7051 ./chaincode_example02
Output of the above command should look something like below:
As shown above if "Received REGISTERED" message is not received then must be some error.
Once the chaincode is registered you can send requests. Open another terminal and send following basic curl commands to chaincode.
# curl 172.19.0.3:7050/network/peers
# curl 172.19.0.3:7050/chain/blocks/0
# curl 172.19.0.3:7050/chain
Login using REST API:
To log in through the REST API, send a POST request to the /registrar
endpoint, containing the enrollmentID
and enrollmentPW
listed in the eca.users
section of the membersrvc.yaml file.
curl -i -X POST \ -d \ '{ "enrollId": "jim", "enrollSecret": "6avZQLwcUe9b" }' \ |
Chaincode Deploy Operation:
Execute following curl command to initiate deploy transaction, since security is enabled we need to pass "enrollmentID" with the "secureContext" element.
curl -i -X POST -H "Content-Type:application/json" -d '{ "jsonrpc": "2.0", "method": "deploy", "params": { "type": 1, "chaincodeID":{ "path":https://github.com/masterDev1985/learn-chaincode/finished, “name”: “mycc” }, "ctorMsg": { "args":["init","a", "100", "b", "200"] }, "secureContext": "jim" }, "id": 1}' 'http://localhost:7050/chaincode' |
Chaincode Invoke Operation:
Execute following curl command to send invoke transaction to the chaincode.
curl -i -X POST -H "Content-Type:application/json" -d '{ "jsonrpc": "2.0", "method": "invoke", "params": { "type": 1, "chaincodeID":{ "path":"https://github.com/masterDev1985/learn-chaincode/finished", "name": "mycc" }, "ctorMsg": { "args":["invoke", "a", "b", "20"] }, "secureContext": "jim" }, "id": 1}' 'http://localhost:7050/chaincode' |
Chain code Query Operation
Execute following curl command to send query transaction to the chaincode.
curl -i -X POST -H "Content-Type:application/json" -d '{ "jsonrpc": "2.0", "method": "query", "params": { "type": 1, "chaincodeID":{ "path":"https://github.com/masterDev1985/learn-chaincode/finished", "name": "mycc" }, "ctorMsg": { "args":["query", "a"] }, "secureContext": "jim" }, "id": 1}' 'http://localhost:7050/chaincode |
Now the blockchain for development and testing purpose is ready, you can now send invoke and query transaction to the chaincode and verify its working !
References:
[1] fabric/Chaincode-setup.md at master · hyperledger/fabric · GitHub
[2] Fabric Developer Setup - Hyperledger Fabric
[3] Core API - Hyperledger Fabric