Building an application specific blockchain using Cosmos SDK Part-2

Harish Bhawnani
Coinmonks
8 min readApr 7, 2022

--

In Part-1, we realised our use-case and decided the route of application specific blockchain to achieve our goal. Now we will start diving into the technical aspects of our application.

Photo by Nick Morrison on Unsplash

To start building blockchain using cosmos sdk, one should be quite familiar with the basic concepts around Tendermint and Cosmos SDK architecture. I would highly recommend to go through the given links (documentation) for better understanding. Also it would be great to learn about Starport as we will be using Starport cli as our development tool for building the chain.

Before we continue with development, I hope you have gone through the documentation around the design of Cosmos SDK. Basically it provides us the boilerplate implementation of ABCI interface which helps us to interact with Tendermint consensus engine. Note that we will be using golang to write our application. As Tendermint is written in golang, our app can be easily compiled into the Tendermint binary, otherwise we would require a unix socket connection to communicate with the Tendermint process.

Before we jump right into development, let us summarise the important points around cosmos SDK design-

  • Tendermint communicates with the application via ABCI (Application Blockchain Interface). So there should be no other open ports from our application server to outside Internet. All interactions should happen via tendermint core engine. Any state transition, not happening via Tendermint will be security breach.
  • Following are the important methods of ABCI, an app must implement -
    * CheckTx- When a transaction is received by Tendermint, it is passed to the application via CheckTx to verify if it is valid, before adding it to the mempool. This is to protect the mempool against spam transactions. Handler known as AnteHandler should be invoked to execute validation steps such as checking for sufficient fees and signature validation. Note that this doesn’t guarantee that an invalid Tx won’t make it to the mempool. Therefore during transaction processing step (DeliverTX), app should revalidate the message and impose certain gas consumption to discourage the spam transactions.
    * DeliverTx- The state transitions occurs during this stage. Each transaction in a given block, is passed to the application via DeliverTx in order to be processed. Cosmos sdk takes care of decoding the transaction and routing rpc messages to their corresponding modules.
    * BeginBlock/EndBlock: These methods are executed at the beginning and the end of each block. It is useful to trigger automatic logic execution. Note that expensive operations must be avoided here.
  • Best part of using Cosmos SDK is that we do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of baseapp. As an application developer we are supposed to extend the baseapp by embedding it in our custom app.
  • An ABCI app is basically an object comprising of baseapp (from sdk), list of store keys (keys to access the module’s stores), list of module’s keepers( objects that handles reads and writes for their own module store), appCodec (to serialize and deserialize the data structure in order to store data as []byte in module’s store).
  • An app is composed of various built-in and custom modules. Each module has its own KVStore.The inter-module interactions happen via capability principles. This ensures security across modules. A module can define a predefined set of capabilities, which other modules can use by importing their keeper interface. For instance keeper struct of our custom module would need to embed the keeper interface of bank module to handle fund transfer related capabilities.
  • The moduleManager is an important entity in sdk. It is basically an object containing list of all the application modules. It determines the order of execution between modules for various functions like InitChain, BeginBlocker and EndBlocker. It takes care of registering the Msgservice and grpc query service of each module. It also helps in initialising and exporting genesis for all the modules.
  • As an application developer we will be mostly focussing on Msg, Query service and Genesis state of our custom module.
  • We will be using Starport cli, for all scaffolding operations.Using starport is the most easiest way to get started with cosmos sdk. It helps us to scaffold the code, generate type definitions, proto definitions, download dependencies, compile our code into binary, test simulation etc.

Without further delay lets install the starport cli!

Before installing starport, ensure that Golang has been properly installed on your machine.

Starport Installation -

Execute the following command in your terminal -

curl https://get.starport.com/starport! | bash

This will install the starport binary under /usr/local/bin directory. To verify if cli is installed properly, run command starport --version . If it throws an error instead of printing the version, there might be some issue with installation. If the error says-command not found then most probably terminal isn’t able to find the starport binary as path isn’t properly setup on machine.

Note that we are using starport version (v0.19.5) for this tutorial.Once starport has been installed run the command to scaffold the chain

starport scaffold chain github.com/harry-027/deal

This will scaffold the chain with the name deal . Feel free to change the username harry-027 . Ideally this should be your github account user name where you will be deploying the source code. Note that this command will also generate a custom module with name deal same as that of the chain. If you don’t want to generate the custom module for now , run the above command with the flag--no-module . You can later generate the module via command starport scaffold module [name] [flags]. Later option also gives the flexibility to enable ibc via flags, if required.

Now let’s change the root directory to deal folder and run the command starport chain serve. This will spin up our single node cluster blockchain in development mode. We will now focus on developing our own custom module deal and integrate it with the app.

Before we start coding the functionality for our custom deal module, let us understand the business flow -

Concepts -

Photo by Shubham Dhage on Unsplash

UseCase -

Usually big online e-commerce stores work together with vendors to complete order delivery for a consumer in a given deadline. An online store owner takes care of handling the online store and order delivery whereas vendor takes care of preparing & shipping the product (handing it over to the store owner for delivery to end user). Objective here is to handle the deals & order’s fund over blockchain so that fair amount of commission is distributed among parties as per the initial agreement.

Deal-

Here, a deal is basically an agreement between two business parties around the commission rate on order completion. In our use-case basically a store owner makes a deal with vendor for a certain fixed commission rate (1% <= r% <= 100%) which will be applicable after each order delivery. This means after successful delivery under a given deal for a given deadline, a fixed amount of commission will be transferred to the vendor account.

Contract-

Here, each order from an end user is represented by a contract. Based on online cart and user details, an online store owner initiates a contract on blockchain under a deal, which includes certain details such as end user wallet address, order details under contract description, start time, time to be taken by owner for delivery and contract expiry time. In order to execute the contract successfully, vendor needs to commit the contract before its expiry. Note that, vendor needs to input shipping time for committing the contract. Contract can be marked as committed, only if shipping time is less than half of delivery time.

Contract Approval-

Once the contract has been committed by vendor, end user is supposed to make payment so that order can be processed on time. The payment from end user is basically held in an escrow account which is basically the deal module account. The contract is marked as approved after successful payment from end user which also triggers a custom event to inform vendor about contract approval.Note that the end user needs to approve the contract before the expiry time so that order processing can get started.

Contract Shipping-

Once the contract has been approved, vendor can start processing the order and make it ready for consumer. While handing over product to store owner, vendor can initiate a tx to change the contract status to IN-DELIVERY. This marks the vendor role here as completed. With this tx, shipping delay also gets recorded if any with respect to committed shipping time.

Order Delivered-

Once the order has reached to end user door step, he needs to initiate a tx for marking the order as completed. This tx will calculate if there is any delivery delay and will release funds from escrow account to respective parties based on calculated delay charges (shipping/delivery) if any and commission rate. Note that in case of shipping or delivery delay, consumer will get back an amount of refund (delay charges) proportional to delay.Delay charges will be deducted from respective parties commission (from vendor commission in case of shipping delay and from store owner commission in case of delivery delay).

Order Cancelled-

Consumer can mark the order as cancelled if delay with respect to delivery time is more than or equal to 20 minutes. Note that if the order cancellation is successful, user gets back the complete refund (funds from escrow account are transferred back to user account)

This is enough for now :) . In next section we will handle the data types and query handlers for our custom deal module.

--

--