Better Programming

Advice for programmers.

Follow publication

A Complete Guide to Designing and Shipping a Blockchain Solution for a Business

Abhishek Chauhan
Better Programming
Published in
14 min readMay 25, 2022
photo credit: Axel Ahoi

The complex nature of logistics and supply-chain makes it difficult to gain an accurate, real-time overview of a shipment’s status because logistics and supply-chain usually involve multiple participants(e.g. consumers of goods, retailers, distributors, manufacturers, suppliers, and brokers), each of which maintains its own record of a transaction. These records are often unsynchronized, making it tough to get a big-picture view of the situation. However, a blockchain-based supply chain network can provide greater visibility and transparency, upping efficiency and boosting value.

Trade finance and logistics terms

There are a lot of terms used in trade finance and logistics that can be confusing for newcomers to the industry. The following terms refer to certain instruments and artifacts that are in play in our trade scenario. The application we will build in this article uses simplified forms of these instruments:

Letter of credit: A letter of credit (L/C) is basically a bank’s way of saying, “We promise to pay this person for the goods they shipped, as long as they can show us proof that they actually shipped them.” It’s a pretty important document, and the importer’s bank will issue one at the request of its client — the importer.

The L/C outlines the papers that verify the shipment was made, how much needs to be paid, and who will get that money (in our case, the exporter). A sample L/C is illustrated below:

letter of credit

Export license: An export license is an approval granted by a regulatory authority to ship specified goods. In this blog, we will refer to it as E/L for short. A sample E/L is illustrated in the screenshot below:

export license

Bill of lading: A bill of lading (B/L) is a document that proves that the carrier has taken possession of the shipment. It also acts as a contract between the carrier and the exporter and proves that the exporter owns the goods.

  • a shipment receipt
  • a contract where the carrier agrees to transport the goods to a specified destination in return for a fee
  • an ownership title of goods

The bill of lading is also listed in the letter of credit and serves as proof of shipment that will automatically trigger a payment clearance.

bill of landing

Process Workflow

Our workflow involves breaking down transactions into simpler steps in order to make the process more efficient and easier to follow. By deconstructing the interactions among different sets of entities into smaller, more manageable parts, we can streamline the testing process and make it more effective.

transactions workflow
  1. Importer requests goods from the exporter in exchange for money
  2. Exporter accepts the trade deal
  3. Importer asks its bank for an L/C in favour of the exporter
  4. The importer’s bank supplies an L/C in favour of the exporter and is payable to the latter’s bank
  5. The exporter’s bank accepts the L/C on behalf of the exporter
  6. Exporter applies for an E/L from the regulatory authority
  7. Regulatory authority supplies an E/L to the exporter
  8. The exporter prepares a shipment and hands it off to the carrier
  9. The carrier accepts the goods after validating the E/L and then supplies a B/L to the exporter
  10. The exporter’s bank claims half the payment from the importer’s bank
  11. The importer’s bank transfers half the amount to the exporter’s bank
  12. The carrier ships the goods to the destination
  13. The importer’s bank pays the remaining amount to the exporter’s bank

Shared Assets and Data

The participants in the previous workflow must share some information in order for all parties to be aware of the trade arrangement and its progress at any given moment. This includes sharing assets such as documentary and monetary assets, as you can see in the table below:

table with two columns. left side: letter of credit, bill of lading, export license, payment. right side: list of documents
asset types and attributes
table with two columns. left side: trade agreement, letter of credit, export license, shipment. right side: list of requests made
data types and attributes

Participants’ Roles and Capabilities

In our case, there are 6 types of participants: exporters, importers, the exporters’ bank, the importers’ bank, the shipping company, and some regulatory authority. Everyone has different abilities and limitations, which are listed below:

  • Only an importer may apply for an L/C
  • Only an importer’s bank may supply an L/C
  • Only an exporter’s bank may accept an L/C
  • Only an exporter may request an E/L
  • Only a regulatory authority may supply an E/L
  • Only an exporter may prepare a shipment
  • Only a carrier may supply a B/L
  • Only a carrier may update a shipment location
  • Only an importer’s bank may send money, and only an exporter’s bank may receive money

Setting Up the Environment

Installing prerequisites

Now we have design of network in hand, let’s install the prerequisite tools:

  1. Ensure that you have the latest version of Docker using https://docs.docker.com/install/ and Docker-Compose using: https://docs.docker.com/compose/install/
  2. Install the software required for the business network example: https://hyperledger.github.io/composer/latest/installing/ installing-prereqs.
  3. Fabric is implemented using the Go programming language. Note that Go has a syntax similar to C++. We will also use Go to write our chaincode. Go can be installed from the link https://golang.org/.
  4. Set up our environmental variables. GOPATH points to a workspace for the go source code, for example:
$ export GOPATH=$HOME/go

PATH needs to include the Go bin directory in order to store libraries and executables. This can be seen in the following snippet:

$ export PATH=$PATH:$GOPATH/bin

6. Check if you need to install make it on your system. On a Debian/Ubuntu system, you can install it using sudo apt-get install make.

Forking and Cloning the Trade- Finance-Logistics Repository

It is essential that we first fork the repository on GitHub so that we have our own copy of the original source code. We can then clone the source code into a local machine directory by following these steps:

$ cd $GOPATH/src
$ git clone https://github.com/YOUR-USERNAME/trade-finance-logistics

We now have a local copy of all the trade-finance-logistics tutorial materials.

Preparing the Network

To build Fabric and Fabric-CA, you may need to install some dependencies first, such as the gcc, libtool, and ltdl libraries. (On Ubuntu systems, you can install all of the necessary prerequisites by running sudo apt install libltdl-dev and on mac by running brew install libtool). We need to perform the following steps before generating network cryptographic material:

  1. Clone the Fabric (https://github.com/hyperledger/fabric/tree/release-1.1) source code repository by adding the parameter -b release-1.1. Make sure the cloned fabric folder is either present or symbolically linked in $GOPATH/src/github.com/hyperledger/. This is necessary so that when you attempt to build Fabric, it will look for the required libraries in this path.
  2. Run make dockerbuild Docker images for the peers and orderers
  3. Run make configtxgen cryptogento generate the necessary tools to run the network creation commands described in this section
  4. Clone the Fabric-CA from https://github.com/hyperledger/fabric-ca/tree/release-1.1. Make sure the cloned fabric-ca folder is either present or symbolically linked, in $GOPATH/src/github.com/hyperledger/. This is necessary so that when you attempt to build Fabric-CA, it will look for the required libraries in this path.
  5. Run make docker to build the Docker images for the managed service providers(MSPs).

Generate Network Cryptographic Material

The first step in the configuration of a network involves the creation of certificates and signing keys for the MSP of each peer and orderer organization, and for TLS-based communication. We also need to create certificates and keys for each peer and orderer node to be able to communicate with each other and with their respective MSPs.

This setting must be identified in a crypto-config.yaml within the network folder of our codebase. For example, take a look at the definition of the importer’s organization within the file as such:

PeerOrgs:
- Name: ImporterOrg
Domain: importerorg.trade.com
EnableNodeOUs: true
Template:
Count: 1
Users:
Count: 2

This config indicates that the ImporterOrg organization will have one peer. Additionally, two non-admin users will be created. The organization domain name usable by the peer is also defined.

To create cryptographic material for all the organizations, run the cryptogen command as follows:

cryptogen generate --config=./crypto-config.yaml

The output is saved in the crypto-config folder.

Generate Channel Artifacts

To build a network that accurately reflects an organization’s structure, and to establish a channel, the following materials are necessary:

  • The genesis block contains organization-specific certificates that initialize the Fabric blockchain.
  • Channel configuration information
  • Anchor peer configurations for each organization ensure that the blockchain is properly maintained.

The crypto-config.yaml file contains the channel properties while configtx.yaml file, located in the network folder, defines the high-level structure of our trade network as shown in the Profiles section:

As we can see, the channel we are going to create is named FourOrgsTradeChannel, which is defined in the profile. The 4 organizations participating in this channel are labelled ExporterOrg, ImporterOrg, CarrierOrg, and RegulatorOrg, each of which refers to a subsection defined in the Organisationssection. The orderer belongs to its own organization called TradeOrdererOrg.

Each organization listed below contains information about its MSP (ID as well as the location of the cryptographic material, such as keys and certificates) and the hostname and port info for its anchor peers. As an example, the ExporterOrg section contains the following:

- &ExporterOrg
Name: ExporterOrgMSP
ID: ExporterOrgMSP
MSPDir: crypto-config/peerOrganizations/exporterorg.trade.com/msp
AnchorPeers:
- Host: peer0.exporterorg.trade.com
Port: 7051

As you can see, the MSPDirvariable (representing a folder) in this specification references the cryptographic material we generated earlier using the cryptogentool.

The configtxgen tool is used to generate channel artifacts. To generate the genesis block, run the following command from the network folder:

configtxgen -profile FourOrgsTradeOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

The FourOrgsTradeOrdererGenesis keyword corresponds to the profile name in the Profiles section. The genesis block will be saved in the genesis.block file in the channel-artifactsfolder. To generate the channel configuration, run the following code:

configtxgen -profile FourOrgsTradeChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID tradechannel

The channel we will create is named tradechannel, and its configuration is stored in channel-artifacts/channel.tx. To generate the anchor peer configuration for the exporter organization, run:

configtxgen -profile FourOrgsTradeChannel -outputAnchorPeersUpdate ./channel-artifacts/ExporterOrgMSPanchors.tx -channelID tra

The same process should be repeated for the other three organizations while changing the organization names in the preceding command.

You need to set the environment variable FABRIC_CFG_PATH to the folder that has the configtx.yaml file in order for the configtxgen tool to work. The script file trade.sh has a line that makes sure the YAML file is loaded from the folder the command is run in: export FABRIC_CFG_PATH=${PWD}

Generate the Configuration in One Operation

The trade.sh script is configured to generate channel artifacts and cryptographic material using the commands and configuration files described previously. To do this, simply run the following command from within the network folder:

./trade.sh generate -c tradechannel

Although you can name any channel you want here, it’s important to note that the configurations used to develop the middleware later in this article will depend on that name.

The GOPATHvariable is set to /opt/gopath in the container that runs the peer.

Compose a Sample Trade Network

The previous command also creates a network configuration file docker-compose-e2e.yaml, which can be used to start the network as a set of Docker containers using the docker-compose tool. This file is based on the statically configured files base/peer-base.yamland base/docker-compose-base.yaml.

These files work together to specify services and their attributes, which allows us to run all the services we need within Docker containers. This is opposed to having to manually run each individual service on one or more machines. The services we need to run are:

  • Four instances of a Fabric peer, one in each organization
  • One instance of a Fabric ordered
  • Five instances of a Fabric CA, corresponding to the MSPs of each organization

Docker images for each component can be found on the Hyperledger project on Docker Hub (https://hub.docker.com/u/hyperledger/). The images are hyperledger/fabric-peer, hyperledger/fabric-orderer, hyperledger/fabric-ca for peers, orderers, and Certificate Authorities (CAs) respectively.

The base config of a peer can be as follows (see base/peer-base.yaml):

You can configure fabric settings here, but if you use the pre-built Docker image for fabric-peer, the defaults are usually sufficient to get a peer service running. The command to start the peer service is usually specified in the last line of the configuration as peer node start. Also, make sure you configure the logging level using the CORE_LOGGING_LEVEL variable.

In our configuration, the variable is set to INFO, which means that only informational, warning, and error messages will be logged. However, if you wish to debug a peer and need more extensive logging, you can set this variable to DEBUG.

The IMAGE_TAGvariable is set to “latest” in the .env file in the network folder, but you can set a specific tag if you want to pull older images.

It is essential that we configure the hostnames and ports for each peer, and synchronize the cryptographic material generated (using cryptogen) to the container filesystem. The peer in the exporter organization is configured as follows in base/docker-compose-base.yaml:

As specified by the extends parameter, this configuration inherits from the base configuration. Please note that the ID (CORE_PEER_ID) corresponds with the peer’s ID specified inconfigtx.yaml. This identity will be used as the hostname for the peer running in the exporter organization and will be referenced in the middleware code later on in this article.

The volumes section establishes the protocol for copying the cryptographic material produced in the crypto-config folder to the container. The peer service itself listens on port 7051, and the port that clients can use to subscribe to events is designated as 7053.

In this file, you will notice that the in-container ports are the same across all peers. However, they are mapped to different ports on the host machine. Also, please take note that the MSP ID specified here corresponds with the one found in configtx.yaml.

The configuration of the orderer service is similar to the following snippet from base/docker-compose-base.yamlindicates:

orderer.trade.com:
container_name: orderer.trade.com
image: hyperledger/fabric-orderer:$IMAGE_TAG
environment:
- ORDERER_GENERAL_LOGLEVEL=INFO
……
command: orderer
……

The command to initiate the orderer is simply orderer, as the code demonstrates. The logging level can be customized using the ORDERER_GENERAL_LOGLEVEL variable and is set to INFOin our configuration.

The network configuration that we will use is based on a file named docker-compose-e2e.yaml. This file is not in the repository but rather is generated by the command ./trade.sh generate -c tradechannel, which we ran earlier to generate the channel and cryptographic material. This file uses base/docker-compose-base.yaml (and indirectly base/peer-base.yaml) as you can see by examining the file contents.

It is generated from a YAML template file called docker-compose-e2e-template.yaml, which can be found in the network folder. The template file contains variables that are replaced with actual filenames within the crypto-config folder when docker-compose-e2e.yaml is generated.

For example, consider the exporter-ca section in docker-compose-e2e-template.yaml:

exporter-ca:
image: hyperledger/fabric-ca:$IMAGE_TAG
environment:
……
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/EXPORTER_CA_PRIVATE_KEY
……
command: sh -c ‘fabric-ca-server start — ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.exporterorg.trade.com-cert.pem

Now, look at the same section in the generated file docker-compose-e2e.yaml:

exporter-ca:
image: hyperledger/fabric-ca:$IMAGE_TAG
environment:
……
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/ cc58284b6af2c33812cfaef9e40b8c911dbbefb83ca2e7564
……
command: sh -c ‘fabric-ca-server start — ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.exporterorg.trade.com-cert.pem

As you can see, the variable EXPORTER_CA_PRIVATE_KEYhas been replaced with cc58284b6af2c33812cfaef9e40b8c911dbbefb83ca2e7564e8fbf5e7039c22e_sk, both in the env and in the command. If you now examine the contents of the crypto-config folder, you will notice that there is a file named cc58284b6af2c33812cfaef9e40b8c911dbbefb83ca2e7564e8fbf5e7039c22e_sk in the folder crypto- config/peerOrganizations/exporterorg.trade.com/ca/. This file contains the exporter organization’s MSP’s private (secret) signing key.

The code snippet before this contains the outcome of a test run. The main file name will be different every time you run the cryptographic tool.

Now, look at the configuration of an MSP in more detail, taking the example of the exporter organization MSP, as specified in docker-compose-e2e.yaml:

The service that will run in the MSP is the fabric-ca-server, listening on port 7054, bootstrapped with the certificates and keys created using cryptogen, and using the default login and password (admin and adminpw, respectively) configured in the fabric-ca image. The command to start a Fabric CA server instance is fabric-ca-server start, as you can see in the preceding code.

Peers and CAs are configured for TLS-based communication, as indicated in the preceding configurations. The reader must note that if TLS is disabled in one, it must be disabled in the other too.

Also, as can be observed by examining docker-compose-e2e.yaml, we do not create a Fabric CA server (and container) for the orderer’s organization. For the exercise we will go through in this book, statically created admin users and credentials for the orderer are sufficient; we will not be registering new orderer organization users dynamically, so a Fabric CA server is not needed.

Network Components’ Configuration Files

We have demonstrated how peers, orderers, and CAs can be configured in docker-compose YAML files. But such configurations are meant to override settings that have already been made by default in the components’ respective images. Though a detailed description of these configurations is beyond the scope of this book, we will list the respective files and mention how a user may make changes to them.

For a peer, acore.yaml file contains all of the important runtime settings, including but not limited to addresses, port numbers, security and privacy, and the gossip protocol. You can create your own file and sync it to the container using a custom Dockerfile instead of the one that is used by the hyperledger/fabric-peerimage by default. If you log in to a running peer container (let’s take the Exporter organization’s peer’s container from the network we just launched):

docker exec -it f86e50e6fc76 bash

Then you will find the core.yaml file in the folder/etc/hyperledger/fabric/.

Similarly, an orderer’s default configuration lies in orderer.yaml, which is also synced to /etc/hyperledger/fabric/ on the container running the hyperledger/fabric-orderer image. Keep in mind that both the core.yaml and orderer.yamlfiles are synced to the peer and orderer containers, so if you wish to create custom files, you will need to sync these YAML files to both containers.

A Fabric CA server also has a configuration file called fabric-ca-server-config.yaml , which is synced to /etc/hyperledger/fabric-ca-server/ on the container running the hyperledger/fabric-ca image. You can create and sync custom configurations as you would for a peer or an orderer.

Launching a Sample Trade Network

So, now that we have all the configuration for our network, and also the channel artifacts and cryptographic material required to run it, all we need to do is start the network using the docker-compose command, as follows:

docker-compose -f docker-compose-e2e.yaml up

You can run this as a background process and redirect the standard output to a log file if you so choose. Otherwise, you will see the various containers starting up and logs from each displayed on the console.

On some OS configurations, setting up Fabric can be tricky. If you run into problems, consult the documentation. A detailed description of how to install a Fabric network and examples is provided at https://hyperledger-fabric.readthedocs.io/en/release-1.1/samples.html.

The network can be launched in the background using our trade.sh script as well. Just run the following:

./trade.sh up

From a different terminal window, if you run docker ps -a , you will see something as follows:

We have four peers, four MSPs, and an orderer running in separate containers. Our trade network is up and ready to run our application!

To view the running logs of a given container, note the container ID (first column in the preceding list) and simply run:

docker logs <container-ID>

To bring the network down, you can use either the docker-compose command: docker-compose -f docker-compose-e2e.yaml down Or our trade.sh script: ./trade.sh down .

Summary

In this article, we introduced the business use case. We have also deployed our first Hyperledger Fabric network and have now transitioned from theory to practice. Well done!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Abhishek Chauhan
Abhishek Chauhan

Written by Abhishek Chauhan

👨‍💻 Blockchain dev sharing insights on innovative solutions. Follow me on LinkedIn: https://www.linkedin.com/in/ac12644 🤝 GitHub: https://github.com/ac12644

Responses (1)

Write a response