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.
# 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
# systemctl start docker
# systemctl enable docker
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 |
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_example0... > 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
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
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" }' \ |
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' |
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' |
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