Deep-Dive into FabCar: A Complete Application Example on Hyperledger Fabric (Part 2)

KC Tam
6 min readFeb 25, 2019

This is Part 2 of this series. In Part 1 we have introduced what FabCar is, and how the application architecture looks like. In this part we go into the Chaincode and see how it is structured, and use CLI to simulate the flow of chaincode functions.

5. Understanding FabCar Chaincode

Now it is the right time to take a look the FabCar chaincode. As a recap, chaincode is executed inside the Fabric network (on endorsing peer). It is where the business logic, agreed by all participants, resides and will be executed when conditions are met. In production, the ledger is only updated when chaincode is invoked.

It is where the Chaincode resides.

The chaincode is in fabric-samples/chaincode/fabcar/go/. This chaincode is written in Go, and follows the specific pattern defined in Hyperledger Fabric. In this article we only focus on portions of our interests, which is the data structure, the Init() and Invoke() functions, plus some functions that will be called by Invoke(). The name of these functions begins with lower case.

Data Structure

As FabCar is a “database” in the ledger, here is how the data is structured.

Init()

This is a specific function required in Hyperledger Fabric chaincode. The Init() is executed when the chaincode is instantiated in the Fabric network.

We can set as many initial states as possible with this Init(). But as good practice, we usually leave this empty, and invoke another function later externally. The function we later invoke in this chaincode is initLedger(). Refer to the step 8 in the “4. Bringing Up the Basic Network and Start FabCar Chaincode” section.

Invoke()

This is another specific function required in Hyperledger Fabric chaincode. The Invoke() usually defines some further actions (functions) when the chaincode is invoked. It usually follows the pattern like this.

From the code we learn that, when chaincode is invoked, an argument list is required. The first argument is always the “function”, and the remain is “args”, the argument list for that “function”.

There are total five functions defined, namely

  • queryCar
  • initLedger
  • createCar
  • queryAllCars
  • changeCarOwner

The name is intuitive enough to tell what action will be performed after calling this functions. We will provide a summary of them.

initLedger()

initLedger() is to preload the 10 sets of car data into the ledger. Here we can see the data is “stringified” before putting into the ledger as value with key CARx (line 113). The API to update the ledger is PutState().

This function does not require additional arguments, and only executed once. It does not make sense to repeat running it. When we design Client Application we shall not include any action to this function.

queryAllCars()

queryAllCars() simply iterates the record stored in the ledger and put them into formatted result. No argument is needed for this function. The API for data retrieval from the ledger is GetStateByRange() (line 140).

queryCar()

querCar() allows query on individual car based on CarID.

One argument is required as expected, the CarID, which is used for data retrieval from ledger using GetState() (line 91). The result is returned.

createCar()

createCar() is for adding new car record into the ledger.

As it is a new record, all information is expected. A list of 5 arguments matches the required field: CarID, Maker, Model, Colour and Owner. The data is stringified and placed into ledger using PutState() (line 130).

changeCarOwner()

changeCarOwner() can change the owner of a car specified by CarID.

Two arguments are expected, the CarID and the Owner. This update is done through PutState() (line 191).

This is what the section is about. We omit other structural requirement on Hyperledger Fabric chaincode, but the functions above are good enough for us to move forward to do some chaincode operation demonstration.

6. Demonstration of Chaincode Functions using CLI

Here we begin to demonstrate how the chaincode is working, or more specifically, what happens when the chaincode is queried or invoked.

We are using the CLI container. All commands are issued from CLI. The setup of CLI is that the command is issued to the Peer, with proper certificate setup.

Here are the step for this demonstration

  1. Query All Cars in the ledger
  2. Query the specific car by CarID
  3. Add a new car with detail provided
  4. Query All Cars in the ledger again and we see a new car is in the ledger
  5. Change the owner of a car to someone else
  6. Query that car again and see the change is done

Assuming we have setup the network with ./startFabric.sh. Double check that total six containers running.

Make sure the nodes and chaincode container are running

Step 1: Query all car records

$ docker exec cli peer chaincode invoke -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'

Step 2: Query a specific car by CarID

$ docker exec cli peer chaincode invoke -C mychannel -n fabcar -c '{"Args":["queryCar","CAR4"]}'

Step 3: Add a new car

$ docker exec cli peer chaincode invoke -C mychannel -n fabcar -c '{"Args":["createCar", "CAR12", "Honda", "Accord", "black", "Tom"]}'

Step 4: Query all cars again

$ docker exec cli peer chaincode invoke -C mychannel -n fabcar -c ‘{“Args”:[“queryAllCars”]}’

Step 5: Change owner of CAR4

$ docker exec cli peer chaincode invoke -C mychannel -n fabcar -c ‘{“Args”:[“changeCarOwner”, “CAR4”, “KC”]}’

Step 6: Query CAR4 again

$ docker exec cli peer chaincode invoke -C mychannel -n fabcar -c ‘{“Args”:[“queryCar”,”CAR4"]}’

This ends the demonstration. We have shown how to interact with an instantiated chaincode using CLI. In real life we will use Client Application instead of CLI. In the next section we will examine the FabCar Client Application.

That’s for part 2. In the next part we will examine in detail the FabCar Client Application. Stay tuned.

--

--