Building a Tendermint & Cosmos SDK App (Part 2): Intro to Cosmos SDK
This is the second post in the series of blog posts explaining how to build applications on top of a blockchain using Tendermint and Cosmos-SDK. The link to the previous post can be found here
This post will introduce Cosmos-SDK. In order to make building applications on top of the Tendermint platform easier, the Cosmos team has created a Cosmos-SDK. Let’s revisit everything we need to implement if we want to build on top of Tendermint:
- Transactions — format, structure, validation
- Application state — how to represent it in memory and how to store it
- Cryptography — picking the appropriate crypto libraries for the cryptography that we need
- Storage — deciding how the state is stored and implementing it with a database backend
- ABCI methods
- Validator set election
- Client — maintaining connections, validating blockchain headers etc.
- Wallet/Key management
Cosmos-SDK takes care of all of the things listed above, providing sane defaults as well as plugability whenever it is possible. It provides standard transaction format, good state and storage implementations, ABCI methods implementation that can be overridden, client, cli and wallet implementation that works out of the box and can be built upon.
It also contains several highly useful modules, ready to be used in our application logic, which often can save us a great amount of time. These modules implement validator set election part of the consensus — delegated proof of stake with slashing, manage user accounts, user token balances, and even provide on-chain governance that anybody can use.
Cosmos-SDK contains the following building blocks:
- Baseapp — this is a simple application frame on top of Tendermint that does not contain any logic, but contains the implementation of the required ABCI methods. It allows to expand upon and replace all of the hooks with our logic, without having to deal with all of the details that we don’t need. It is the central point of the whole application
- Store — contains implementation of storage layer required to store blockchain data and application state. By default everything is stored in GoLevelDB, a Go’s implementation of the LevelDB key-value storage. The interface to storage is in the form of abstract key-value store, allowing a developer to plug in his own implementation if we desire so.
- Cryptography — contains implementation of most usual cryptography, like digital signature schemes and key generation.
- Client — contains implementation of client that can be used while developing client-side applications in Go
- Modules — contains 10+ modules with various functionalities, the most well known being:
- Auth — provides storage and management of user accounts
- Bank — allows maintaining balances and transferring different tokens
- Staking — implements a Delegated Proof of Stake
- Slashing — adds slashing feature to DPoS
- Governance — implements on-chain governance
- Wallet/Key Management — contains basic functionality for deriving keys, listing keys, encrypting keys (via passphrase) while they are stored on file system, and using them to sign the transaction before broadcasting it to the rest of the network to be included in the following block
By using Tendermint and Cosmos-SDK you can create application-specific blockchains, with any arbitrary logic that you want to have on top of this blockchain platform. To showcase that, we are going to build something very arbitrary. We are going to build the tic-tac-toe game on top of a blockchain. It will be as simple as possible, intended to demonstrate how to code arbitrary logic on top of Tendermint.
To build something with Cosmos-SDK, following the architectural principles set by it, we begin by dividing our application into appropriate modules.
All of the modules are encouraged to follow this structure:
- Keeper — this is the central component of a module, which should contain the core business logic. This is where the messages inside the transactions are processed and the state is modified in the case of a success.
- Messages — this defines the messages that exist in this module. Messages are what users send, packaged in transactions, when they want to interact with the blockchain by writing to it. Most of the modules have several messages, example: CreateValidator, DelegateTokens, UndelegateTokens etc. Every message has to have its routing info which is usually the name of the module, its type, validation logic, encoding, and the required list of signers.
- Handler — serves to process the messages and hand them to the keeper which should execute the main logic of the module. It performs the preprocessing and unpacking of messages.
- Querier — serves to handle the queries to read the application state of a given module. The queries can be arbitrary and are specified by the query path, offering the biggest flexibility possible
- Codec — registers all of the types that belong to the module, that are going to be encoded with Cosmos-SDK. Cosmos-SDK uses go-amino (https://github.com/tendermint/go-amino)
Cosmos-SDK, as Tendermint itself, is written in Go. Which is a good, popular, and safe choice for writing blockchains. Therefore, in the rest of the series, we will be using Go when writing the application.