Deep-Dive into FabCar: A Complete Application Example on Hyperledger Fabric (Part 1)
Hyperledger Fabric comes with a lot of application examples, and among them FabCar is a complete end-to-end application. A complete blockchain application has two portions of code: the Chaincode portion which is deployed and executed inside the Fabric network, and the Client Application is where the external world interacts with the chaincode deployed on a Fabric network.
While the official document provides very detail discussion on both parts, this set of articles plans to give some illustration and explanation on this example. We first depict the application itself as a whole picture, and then deep dive into each part of this whole picture, one by one. And from this I hope readers have an overall picture on how a typical business blockchain application would be built.
The code I am using here is based on Hyperledger Fabric release 1.4 (link). There is some significant improvement compared to previous releases, in particular on the client application side. You can take a look on this new release.
2. Overall Picture of FabCar
FabCar is a database of car records stored in the ledger of a Fabric network. We can consider this as a traditional database storing the data: it is like a table, indexed with a Car Identifier (CarID), and the information of Maker, Model, Colour and Owner is recorded for this car.
The data are stored in the world state database inside the ledger. Interaction with the data is through chaincode. FabCar comes with a Chaincode, containing the functions which can interact with the stored data in the ledger. They are for database (ledger) initiation, query and update. The world state is queried or updated only through these chaincode functions, and any update is logged in the blockchain inside the ledger as tamper-resistant record.
So far things mentioned above happen inside the Fabric network. Application is only useful when it is connected to external world. The external part is Client Application. Client application interacts with the Fabric network and the deployed chaincodes through Software Development Kit (SDK). Hyperledger Fabric currently provides Java and Node SDK with official support, while those for other programming frameworks like Go and Python are also available.
As introduced in my previous work (link), the application portion (Client Application and Chaincode) is independent from the infrastructure (Fabric network). Theoretically the application can be deployed in any Fabric network deployment, be it of one single organization or a complicated setup with many. We do not code any “infrastructure” information on the Chaincode part. We just specify when we install and instantiate Chaincode about the channel name of the infrastructure. On Client Application side, we also have to specify the Peer, channel ID (name) and chaincode ID (name) in the code in order to speak to the correct deployed chaincode in the Fabric network. We will see it when we touch on the Chaincode and Client Application in coming sections.
The whole setup can be summarized in the following diagram.
Now we are ready to break this diagram into parts, deep diving into each of them.
3. The Basic Network
Introduction of Basic Network
FabCar application can run on any Fabric networks. In the demonstration (as suggested in the official tutorial) we run FabCar on the Basic Network. In this section we first examine how a Basic Network looks like.
From this section up we will largely refer to material in the fabric-samples. You can either git clone to your local machine, or just access the link to make reference on them. Here is the link for fabric-samples: https://github.com/hyperledger/fabric-samples.git.
The Basic Network setup is kept in the directory fabric-samples/basic-network/. When we inspect the content, we see the common two YAML files (crypto-config.yaml and configtx.yaml) for setup of the organization, the certificates for each participant and configuration transactions. Basic Network also comes with the folder config/ and crypto-config/, preloaded with a set of generated files. To simplify the whole setup, we will not generate them, and just use those certificates and configuration transactions provided in config/ and crypto-config/.
According to the design, the physical network is composed of
- Fabric CA (ca.example.com): The Certificate Authority (CA) for the whole Basic Network. We will later use this Fabric CA to generate client certification.
- Orderer (orderer.example.com): There is only one orderer in the Basic Network.
- Peer (peer0.org1.example.com): There is only one organization (Org1) in the Basic Network, and only one peer in Org1.
This is almost the minimum Fabric network, good enough for testing business blockchain application.
If we take a look on the docker-compose YAML file (docker-composer.yml), which is used to bring up nodes (containers) for the network, we see two more containers defined besides the three mentioned above.
- CouchDB: This is used as the world state database by the Peer. As part of the Peer, we are not showing this in any diagram.
- CLI: this command line interface (CLI) container is used for chaincode interaction during the demo. It is good for demonstration and trouble shooting on the chaincode, and is not required in production as the interaction is mainly from Client Application.
Several shell scripts come with Basic Network.
./start.sh: This script first bring down any containers if there are any opened before. Then it will bring up the four containers (CA, Orderer, Peer and CouchDB). After containers are up, it performs the creation of channel mychannel, and joins the only peer to mychannel. With this infrastructure established, the Basic Network is ready for any chaincode operations (installation, instantiation, etc).
Note that we are not running ./start.sh directly. We will call this by another script in FabCar (./startFabric.sh). We will talk about this in next section.
./stop.sh: This script simply stops all containers defined in the docker-compose file. We will use this after we finish the whole demonstration.
./teardown.sh: This script further removes all stopped containers. It also removes the chaincode container (we see this later) image.
So here is how the Basic Network setup looks like after running ./start.sh.
And we see total four containers running after we start the Basic Network.
4. Bringing Up the Basic Network and Start FabCar Chaincode
For demo purpose, the Basic Network is being brought up by a script in FabCar directory, fabric-samples/fabcar/. The script is ./startFabric.sh.
We now examine what happens after running the script. Here is the flow of tasks this script performs
- Set whether we are using Go or Node chaincode. The default is using Go.
- Remove the folder hfc-key-store/. This is where the certificates for client application are stored prior to release 1.4. We are not using this any more the new location is inside another directory.
- Go to basic-network/ directory and execute the ./start.sh. That’s where the Basic Network is brought up. After ./start.sh is executed, as mentioned in previous part, the nodes (containers) are running with mychannel setup in the network.
- Bring up the CLI container. Now we have one more container for chaincode interaction.
- Use the CLI to bring up the FabCar chaincode. This includes three steps
- Install the chaincode to peer (chaincode id is fabcar)
- Instantiate chaincode fabcar in mychannel with the endorsement policy. The policy is set that endorsement is required from either Org1 or Org2 member. Although we only have Org1 in Basic Network, this policy is still well satisfied.
- Invoke a function initLedger() with no arguments. This relates to the content of chaincode. According to the chaincode, this function will preload 10 sets of car data into the ledger. We will see it more in next section.
These are the tasks the ./startFabric.sh performs. After executing we have a bigger picture of the network.
Here is what we see after running ./startFabric.sh script. After the similar output as ./start.sh in previous section, we see a new CLI container is brought up, and the chaincode is installed and invoked.
Beside the four containers of the Basic Network, we now see two more containers: one CLI and one dev-peer0.org1.example.com-fabcar-1.0. This appears after chaincode is instantiated.
That’s for part 1. In the next part we will examine in detail the FabCar chaincode, and simulate the chaincode functions using CLI. Stay tuned.