Publish a Business Network in Multi-host HyperLedger Fabric

Photo by Fré Sonneveld on Unsplash

Well in my previous post I showed how to setup a Hyperledger Fabric in muliple physical machines, if you don’t see it you can take a look here.

It’s kind of important to have the same structure of Fabric that is created in my previous post. If you have another structure, we can try it, the basics are always the same.

I basically start an Hyperledger Fabric that has:

  • Orderer
  • Certificate Authority
  • Peer 0
  • Peer 1 (This is running in other physical machine).

Is important to know that out Hyperledger Fabric also just has one Organization, is not a Multi-Organization network.

Let’s begin creating a Peer Admin Card to our Hyperledger Fabric.

Create a Peer Admin Card

In this step we will create a Peer Admin Card for our Hyperledger Fabric network, now we will create a file named createPeerAdminCard.sh.

This file have the responsabilty to create our server peer admin, that we will use to manage our network.

So we will put this code inside the file:
Usage() {
 echo ""
 echo "Usage: ./createPeerAdminCard.sh [-h host] [-n]"
 echo ""
 echo "Options:"
 echo -e "\t-h or --host:\t\t(Optional) name of the host to specify in the connection profile"
 echo -e "\t-n or --noimport:\t(Optional) don't import into card store"
 echo ""
 echo "Example: ./createPeerAdminCard.sh"
 echo ""
 exit 1
}

Parse_Arguments() {
 while [ $# -gt 0 ]; do
 case $1 in
 --help)
 HELPINFO=true
 ;;
 --host | -h)
 shift
 HOST="$1"
 ;;
 --noimport | -n)
 NOIMPORT=true
 ;;
 esac
 shift
 done
}

HOST=localhost
Parse_Arguments $@

if [ "${HELPINFO}" == "true" ]; then
 Usage
fi

# Grab the current directory
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

if [ -z "${HL_COMPOSER_CLI}" ]; then
 HL_COMPOSER_CLI=$(which composer)
fi

echo
# check that the composer command exists at a version >v0.16
COMPOSER_VERSION=$("${HL_COMPOSER_CLI}" --version 2>/dev/null)
COMPOSER_RC=$?

if [ $COMPOSER_RC -eq 0 ]; then
 AWKRET=$(echo $COMPOSER_VERSION | awk -F. '{if ($2<19) print "1"; else print "0";}')
 if [ $AWKRET -eq 1 ]; then
 echo Cannot use $COMPOSER_VERSION version of composer with fabric 1.1, v0.19 or higher is required
 exit 1
 else
 echo Using composer-cli at $COMPOSER_VERSION
 fi
else
 echo 'No version of composer-cli has been detected, you need to install composer-cli at v0.19 or higher'
 exit 1
fi

cat << EOF > DevServer_connection.json
<JSON CONNECTION PROFILE SECTION>
EOF

PRIVATE_KEY="${DIR}"/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/<KeyStoreFile>
CERT="${DIR}"/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem

if [ "${NOIMPORT}" != "true" ]; then
 CARDOUTPUT=/tmp/PeerAdmin@hlfv1.card
else
 CARDOUTPUT=PeerAdmin@hlfv1.card
fi

"${HL_COMPOSER_CLI}" card create -p DevServer_connection.json -u PeerAdmin -c "${CERT}" -k "${PRIVATE_KEY}" -r PeerAdmin -r ChannelAdmin --file $CARDOUTPUT

if [ "${NOIMPORT}" != "true" ]; then
 if "${HL_COMPOSER_CLI}" card list -c PeerAdmin@hlfv1 > /dev/null; then
 "${HL_COMPOSER_CLI}" card delete -c PeerAdmin@hlfv1
 fi

"${HL_COMPOSER_CLI}" card import --file /tmp/PeerAdmin@hlfv1.card 
 "${HL_COMPOSER_CLI}" card list
 echo "Hyperledger Composer PeerAdmin card has been imported, host of fabric specified as '${HOST}'"
 rm /tmp/PeerAdmin@hlfv1.card
else
 echo "Hyperledger Composer PeerAdmin card has been created, host of fabric specified as '${HOST}'"
fi

Connection Profile

Now we have to update the file with our Connection Profile, we will replace the <JSON CONNECTION PROFILE SECTION> tag with the following json.

{
"name": "hlfv1",
"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
}
}
}
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org1.example.com",
"peer1.org1.example.com"
],
"certificateAuthorities": [
"ca.example.com"
]
}
},
"orderers": {
"orderer.example.com": {
"url": "grpc://<IP First Server>:7050",
"grpcOptions": {
"ssl-target-name-override": "orderer.example.com"
},
"tlsCACerts": {
"pem": "<Orderer CA Cert>"
}
}
},
"peers": {
"peer0.org1.example.com": {
"url": "grpc://<IP First Server>:7051",
"eventUrl": "grpc://<IP First Server>:7053",
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.example.com"
},
"tlsCACerts": {
"pem": "<Peer CA Cert>"
}
},
"peer1.org1.example.com": {
"url": "grpc://<IP Second Server>:8051",
"eventUrl": "grpc://<IP Second Server>:8053",
"grpcOptions": {
"ssl-target-name-override": "peer1.org1.example.com"
},
"tlsCACerts": {
"pem": "<Peer CA Cert>"
}
}
},
"certificateAuthorities": {
"ca.example.com": {
"url": "http://<IP First Server>:7054",
"caName": "ca.example.com",
"httpOptions": {
"verify": false
}
}
}
}

We need to modify several things in this json, first we will put our servers IP in the tags <IP First Server> and <IP Second Server>.
After that we need to update our Certificates, we need to update this tags <Orderer CA Cert> and <Peer CA Cert>.
To get value of <Orderer CA Cert> we will execute this:

$ awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt

This will return something like this:
-----BEGIN CERTIFICATE-----\nMII...ao1FM=\n-----END CERTIFICATE-----\n

We will copy that output inside the <Orderer CA Cert> tag, we will see something like this.

{
"orderer.example.com": {
"url": "grpc://<IP First Server>:7050",
"grpcOptions": {
"ssl-target-name-override": "orderer.example.com"
},
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----\nMIICNjCCAdygAw.....ojmoLOGj\n-----END CERTIFICATE-----\n"
}
}
}

Now we will do the same with the <Peer CA Cert>, executing this command:
$ awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

This it will show this output:
-----BEGIN CERTIFICATE-----\nMII...75hQ==\n-----END CERTIFICATE-----\n

And our json has to look like this

{
"peers": {
"peer0.org1.example.com": {
"url": "grpc://<IP First Server>:7051",
"eventUrl": "grpc://<IP First Server>:7053",
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.example.com"
},
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----\nMIICST...75hQ==\n-----END CERTIFICATE-----\n"
}
},
"peer1.org1.example.com": {
"url": "grpc://<IP Second Server>:8051",
"eventUrl": "grpc://<IP Second Server>:8053",
"grpcOptions": {
"ssl-target-name-override": "peer1.org1.example.com"
},
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----\nMIICST...75hQ==\n-----END CERTIFICATE-----\n"
}
}
}
}

Important: The certificates must be in one line, and in the same way that are shown in the examples!

Other Configurations

Thats all regarding our connection profile for out Peer Admin Card, now we have to update PRIVATE_KEY variable, it’s located after the connection profile.

PRIVATE_KEY="${DIR}"/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/<KeyStoreFile>

As you can see the <KeyStoreFile> is located in the path showed before, so the variable it will look like this.

PRIVATE_KEY="${DIR}"/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/3c4f94b15fc3eef33c85dd640dbce88bb4e72df43599185d6acb81b96fefae98_sk

CardPeerAdminCard.sh Execution

Now we will execute the createPeerAdminCard.sh

$ ./createPeerAdminCard.sh

You will see that your peer admin card has been created, and a list with all the card availables for our network.

With that we have our Peer Admin Card created and ready for use, now we will install a Business Network using the card.

Install the Business Network

For this of course we need a Business Network, we will take it from https://composer-playground.mybluemix.net/ here is an example Business Network, we need to export the .bna file and move it to our first server.

Important: You must remember the version of the Business Network that you are exporting, you will use the version number in the commands in the future.

In the image we see that the version number is 0.2.7

After that we will execute the following command to install the business network in out Hyperledger Fabric.

$ composer network install --card PeerAdmin@hlfv1 --archiveFile my-basic-sample.bna

And we will see this output if it’s all Ok.

✔ Installing business network. This may take a minute...
Successfully installed business network my-basic-sample, version 0.2.6
Command succeeded

Now we will execute this command to start out Business Network.

$ composer network start --networkName my-basic-sample --networkVersion 0.2.6 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card

This has to be the output

Starting business network my-basic-sample at version 0.2.6 
Processing these Network Admins:
 userName: admin
✔ Starting business network definition. This may take a minute...
Successfully created business network card:
 Filename: networkadmin.card
Command succeeded

We have to import our Business Network card now.
 
$ composer card import --file networkadmin.card

Showing this output

Successfully imported business network card
 Card file: networkadmin.card
 Card name: admin@my-basic-sample
Command succeeded

Now just we will test the connection to our Business Network running:

$ composer network ping --card admin@my-basic-sample

And the output:

The connection to the network was successfully tested: my-basic-sample
 Business network version: 0.2.6
 Composer runtime version: 0.20.0
 participant: org.hyperledger.composer.system.NetworkAdmin#admin
 identity: org.hyperledger.composer.system.Identity#01959ec6ef322fe987223f002498b3a80b03dad2882a353ebfaf20be9370907f
Command succeeded

Well and that’s all, now we have our Hyperledger Fabric running in two separate machines with one Business Network running on it!.

Let’s do some validation, using de Composer Playground

Run this command in your first server to start an instance of the Playground API to play around

$ composer-playground -p 8081

So, if we browse to that point to the port specified before we must see something like this.

The image show us the two card that we created the Peer Admin Card, and the Network Admin Card, we will go inside our Business Network, clicking Connect Now, go to the Test tab.

We will add a new Participant, clicking the Create New Participant button in the top right.

And let’s click Create New, if everything its ok, we will see our participant in the grid.

Now lets run the docker ps command in our first server.

$ docker ps

And let see the logs of our Peer 0

$ docker logs <Peer 0 Container Id>

We have to see some activity in our Peer:

2018-08-13 23:48:23.701 UTC [kvledger] CommitWithPvtData -> INFO 03c Channel [mychannel]: Committed block [3] with 1 transaction(s)

Let’s repeat this process to our Peer 1 in our second server.

$ docker ps

And let see the logs of our Peer 1

$ docker logs <Peer 1 Container Id>

We have to see some activity in our Peer.

2018-08-13 23:48:23.731 UTC [kvledger] CommitWithPvtData -> INFO 03b Channel [mychannel]: Committed block [3] with 1 transaction(s)

And that’s all, we see that our Hyperledger Fabric with an Business Network is working like charm! :)


Looking to develop your blockchain project? Drop us a line at hello@1950Labs.com