Blockchain — Hyperledger implementation

Pradeep Batchu
8 min readAug 4, 2019

--

In this article, we will implement blockchain with two organizations set up with one orderer. We could notice all the ledger information in hyperledger explorer and interact with blockchain using Hyperledger composer rest server.

Implement Hyperledger fabric and Hyperledger Composer Business network archive.

In this section, we will set up two orgs Hyperledger with an orderer. We will create business network archive using hyperledger composer and deploy the network on blockchain. Follow below steps.

We will use Google Cloud Platform for proof of concept.

  1. Create compute engine with ubuntu version 16, 50 GB disk space and 1 cpu 12 GB Memory
  2. Log into VM SSH console.
  3. Prepare VM ready with blockchain pre requisites . This will set up node, npm, git, python , docker and docker-compose
curl -O https://hyperledger.github.io/composer/v0.19/prereqs-ubuntu.shchmod u+x prereqs-ubuntu.sh./prereqs-ubuntu.shlogout

You should notice following versions.

Installation completed, versions installed are:

Node: v8.16.0
npm: 6.4.1
Docker: Docker version 19.03.1, build 74b1e89e8a
Docker Compose: docker-compose version 1.13.0, build 1719ceb
Python: Python 2.7.12

4. Re login to SSH console and run following commands for installing Hyperledger composer

// Hyper ledger composer client that is needed to install the 
// network, create network cards etc
npm install -g composer-cli@0.20
// Hyperledger composer generator and yo will help in creating basic // code for code chain
npm install -g generator-hyperledger-composer@0.20
npm install -g yo

5. Get Hyperledger fabric sample repository. We will be using hyperledger provided artifacts for creating multi org set up.

git clone --single-branch --branch multi-org https://github.com/mahoney1/fabric-samples.git

6. We should download all the hyperledger docker images and start docker containers.

cd fabric-samplescurl -sSL http://bit.ly/2ysbOFE | bash -s 1.2.1 1.2.1 0.4.10cd first-network./byfn.sh -m generate// Above command generate artifacts that are needed for generate../byfn.sh -m up -s couchdb -a

7. Observe the log and you will notice there are transactions happened with sample chaincode. If you would like to do more transactions with same chain code, you can try this

docker exec -it cli bash

for example:

peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'peer chaincode query -C mychannel -n mycc -c '{"Args":["query","b"]}'peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","20"]}'peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'peer chaincode query -C mychannel -n mycc -c '{"Args":["query","b"]}'

8. Create temporary working directories

mkdir -p /tmp/composer/org1

mkdir -p /tmp/composer/org2

9. Copy below connection details to your favorite notepad.

{
"name": "byfn-network",
"x-type": "hlfv1",
"version": "1.0.0",
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300",
"eventHub": "300",
"eventReg": "300"
},
"orderer": "300"
}
}
},
"channels": {
"mychannel": {
"orderers": [
"orderer.example.com"
],
"peers": {
"peer0.org1.example.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"eventSource": true
},
"peer1.org1.example.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"eventSource": true
},
"peer0.org2.example.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"eventSource": true
},
"peer1.org2.example.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"eventSource": true
}
}
}
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org1.example.com",
"peer1.org1.example.com"
],
"certificateAuthorities": [
"ca.org1.example.com"
]
},
"Org2": {
"mspid": "Org2MSP",
"peers": [
"peer0.org2.example.com",
"peer1.org2.example.com"
],
"certificateAuthorities": [
"ca.org2.example.com"
]
}
},
"orderers": {
"orderer.example.com": {
"url": "grpcs://localhost:7050",
"grpcOptions": {
"ssl-target-name-override": "orderer.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORDERER_CA_CERT"
}
}
},
"peers": {
"peer0.org1.example.com": {
"url": "grpcs://localhost:7051",
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORG1_CA_CERT"
}
},
"peer1.org1.example.com": {
"url": "grpcs://localhost:8051",
"grpcOptions": {
"ssl-target-name-override": "peer1.org1.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORG1_CA_CERT"
}
},
"peer0.org2.example.com": {
"url": "grpcs://localhost:9051",
"grpcOptions": {
"ssl-target-name-override": "peer0.org2.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORG2_CA_CERT"
}
},
"peer1.org2.example.com": {
"url": "grpcs://localhost:10051",
"grpcOptions": {
"ssl-target-name-override": "peer1.org2.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORG2_CA_CERT"
}
}
},
"certificateAuthorities": {
"ca.org1.example.com": {
"url": "https://localhost:7054",
"caName": "ca-org1",
"httpOptions": {
"verify": false
}
},
"ca.org2.example.com": {
"url": "https://localhost:8054",
"caName": "ca-org2",
"httpOptions": {
"verify": false
}
}
}
}

In the above json, we need to update three variables. INSERT_ORG1_CA_CERT, INSERT_ORG2_CA_CERT and INSERT_ORDERER_CA_CERT

Copy the certificate details to temporary folder.

awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt > /tmp/composer/org1/ca-org1.txtawk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt > /tmp/composer/org2/ca-org2.txtawk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt > /tmp/composer/ca-orderer.txt

Open /tmp/composer/org1/ca-org1-txt file copy the contents of the file as is and replace the “INSERT_ORG1_CA_CERT” in above json.

Open /tmp/composer/org2/ca-org2-txt file copy the contents of the file as is and replace the “INSERT_ORG2_CA_CERT” in above json.

Open /tmp/composer/ca-orderer.txt file copy the contents of the file as is and replace the “INSERT_ORDERER_CA_CERT” in above json.

Save the json as byfn-network-org1.json in “/tmp/composers/org1” folder

Change the client.organization in the nodepad to Org2 and save a copy to “/tmp/composers/org2” as byfn-network-org2.json file

10. Copy the certificates to temporary folder.

export ORG1=crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp

cp -p $ORG1/signcerts/A*.pem /tmp/composer/org1

cp -p $ORG1/keystore/*_sk /tmp/composer/org1
export ORG2=crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp

cp -p $ORG2/signcerts/A*.pem /tmp/composer/org2

cp -p $ORG2/keystore/*_sk /tmp/composer/org2

11. Let’s create composer business network archive. We will do this in root folder.

cd ~
yo hyperledger-composer:businessnetwork

a. Enter byfn-network for the network name, and desired information for description, author name, and author email.

b. Select Apache-2.0 as the license.

c. Select org.example.mynetwork as the namespace.

d. Select No when asked whether to generate an empty network or not.

Replace the contents of byfn-network/permissions.acl with below

/**
* Access control rules for tutorial-network
*/
rule Default {
description: "Allow all participants access to all resources"
participant: "ANY"
operation: ALL
resource: "org.example.mynetwork.*"
action: ALLOW
}

rule SystemACL {
description: "System ACL to permit all access"
participant: "ANY"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}

cd to byfn-network and run following command to create bna file

composer archive create -t dir -n .

You can notice byfn-network@0.0.1.bna file under byfn-network folder.

12. Create network cards

composer card create -p /tmp/composer/org1/byfn-network-org1.json -u PeerAdmin -c /tmp/composer/org1/Admin@org1.example.com-cert.pem -k /tmp/composer/org1/*_sk -r PeerAdmin -r ChannelAdmin -f PeerAdmin@byfn-network-org1.cardcomposer card create -p /tmp/composer/org2/byfn-network-org2.json -u PeerAdmin -c /tmp/composer/org2/Admin@org2.example.com-cert.pem -k /tmp/composer/org2/*_sk -r PeerAdmin -r ChannelAdmin -f PeerAdmin@byfn-network-org2.card

13. Import network cards to the networks

composer card import -f PeerAdmin@byfn-network-org1.card --card PeerAdmin@byfn-network-org1composer card import -f PeerAdmin@byfn-network-org2.card --card PeerAdmin@byfn-network-org2

14. Import business network archive to the network

composer network install --card PeerAdmin@byfn-network-org1 --archiveFile byfn-network@0.0.1.bnacomposer network install --card PeerAdmin@byfn-network-org2 --archiveFile byfn-network@0.0.1.bna

15. Create endorsement file “/tmp/composer/endorsement-policy.json”

{
"identities": [
{
"role": {
"name": "member",
"mspId": "Org1MSP"
}
},
{
"role": {
"name": "member",
"mspId": "Org2MSP"
}
}
],
"policy": {
"2-of": [
{
"signed-by": 0
},
{
"signed-by": 1
}
]
}
}

16. Retrieve business network cards

composer identity request -c PeerAdmin@byfn-network-org1 -u admin -s adminpw -d alicecomposer identity request -c PeerAdmin@byfn-network-org2 -u admin -s adminpw -d bob

17. Starting the business network

composer network start -c PeerAdmin@byfn-network-org1 -n byfn-network -V 0.0.1 -o endorsementPolicyFile=/tmp/composer/endorsement-policy.json -A alice -C alice/admin-pub.pem -A bob -C bob/admin-pub.pem

This step might take 5 min. If you get error try running same command again.

18. Create business network cards in org1 and org2

composer card create -p /tmp/composer/org1/byfn-network-org1.json -u alice -n byfn-network -c alice/admin-pub.pem -k alice/admin-priv.pemcomposer card import -f alice@byfn-network.cardcomposer network ping -c alice@byfn-networkcomposer card create -p /tmp/composer/org2/byfn-network-org2.json -u bob -n byfn-network -c bob/admin-pub.pem -k bob/admin-priv.pemcomposer card import -f bob@byfn-network.cardcomposer network ping -c bob@byfn-network

Hyperledger Explorer

Hyperledger Explorer is a blockchain module and one of the Hyperledger projects hosted by The Linux Foundation. Designed to create a user-friendly Web application, Hyperledger Explorer can view, invoke, deploy or query blocks, transactions and associated data, network information (name, status, list of nodes), chain codes and transaction families, as well as any other relevant information stored in the ledger.

Install Hyperledger explorer

Get blockchain-explorer code from github

git clone https://github.com/hyperledger/blockchain-explorer.git

  1. Get the keystore key for org1 peer admin.
ls ~/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore

Copy the value.

2. Open first-network.json from blockchain-explorer and update the Org1MSP adminPrivateKey path with the key you copied from above step.

vi ~/blockchain-explorer/examples/net1/connection-profile/first-network.json

3. Copy the crypto keys from fabric-samples to blockchain

cp -r ~/fabric-samples/first-network/crypto-config/* ~/blockchain-explorer/examples/net1/crypto

Notice two folders (ordererOrganizations, peerOrganizations)under ~/blockchain-explorer/examples/net1/crypto

4. Now go back to ~/blockchain-explorer run follow command to start the hyperledger explorer.

docker-compose up -d

Check if dockers running successfully

docker ps

5. You can access explorer with external IP address on port 8090. Use admin/adminpw as userid and password.

Rest API to interact with the block chain

<<Explain rest api>>

Set up gitlab account.

  1. Move cards that can interact with blockchain to a new folder
mkdir ~/composer-repo
cp -r ~/.composer ~/composer-repo

2. Push composer-repo files to gitlab.

3. Create ubuntu 16 vm and install pre requisites

Create two files in a new docker folder. Dockerfile and startup.sh

startup.sh

cp -r ~/blockchain-blog-artifacts ~/.composer
composer-rest-server -c alice@byfn-network -n never -u true -w true

Dockerfile

FROM hyperledger/composer-rest-server
COPY startup.sh startup.sh
ENTRYPOINT ["/bin/sh","startup.sh"]

4. Get the repo to your local using git clone and update ipaddress with in connection.json file under blockchain-blog-artifacts for alice. Location of connection.json example: ~/blockchain-blog-artifacts/cards/alice@byfn-network

sed -i 's/localhost/<<EXTERNAL IP ADDRESS>>/g' connection.json 

5. Build docker image and run composer rest server with the cards available

docker build --no-cache -t blockchain/composer-rest-server .docker run -v  ~/blockchain-blog-artifacts:/home/composer/blockchain-blog-artifacts -p 8080:3000 -d blockchain/composer-rest-server

You can visit swagger specs at external ip : 8080/explorer . You should see rest end points

6. Create participants. Add couple of participants. For that click on SampleParticipant and post a request.

Sample Request:

{
“$class”: “org.example.mynetwork.SampleParticipant”,
“participantId”: “1”,
“firstName”: “pradeep”,
“lastName”: “batchu”
}

7. Add asset value “xrp” to assetId 1 and participant you created above

{
“$class”: “org.example.mynetwork.SampleAsset”,
“assetId”: “1”,
“owner”: “org.example.mynetwork.SampleParticipant#1”,
“value”: “xrp”
}

8. Create a transaction and change the new value to “btc”

{
“$class”: “org.example.mynetwork.SampleTransaction”,
“asset”: “org.example.mynetwork.SampleAsset#1”,
“newValue”: “btc”
}

You can see all the transactions in hyperledger explore.

All we have done were on Org1, since alice belongs to Org1. Let’s create new VM for org2.

Follow above steps except step 4 where change on external url for Bob connection instead of alice. Instantiate few transactions and observe the transactions are available on both orgs and we can see transactions clearly.

Happy Blockchain.

--

--