Tendermint provides infrastructure software that allows developers to build their own blockchain solutions. The Tendermint approach has two unique characteristics.
Tendermint utilizes a Byzantine fault tolerant (BFT) algorithm that allows for up to one-third of nodes failing or behaving maliciously.
Tendermint consensus is reached by designated validator nodes. There are only a limited number of validators on the network.
At its core, Tendermint is a high-performance and scalable consensus engine. As a trade-off, it is also a weakly centralized solution; it is not completely decentralized like Bitcoin, as it requires designated validators and is somewhat less fault tolerant (Bitcoin allows 49 percent of nodes to fail while Tendermint allows one-third).
Because Tendermint is designed as a consensus engine, it attempts to separate the “application logic” and “consensus logic” of blockchain applications. That separation allows Tendermint software to be embedded in any other blockchains as a drop-in consensus engine replacement; the host blockchain just needs to implement the Tendermint API, known as the Application BlockChain Interface (ABCI), to use Tendermint’s delegated proof-of-style (DPoS) consensus.
The clean separation between application and consensus logic in Tendermint makes it possible to build custom logic into blockchain applications. Those applications go far beyond the traditional smart contracts. They can utilize full stacks of enterprise software to handle complex application scenarios.
Every node of a Tendermint blockchain needs to run two pieces of software: the consensus engine known as Tendermint Core and an ABCI application specifically written for the blockchain (see Figure 19.1).
The Tendermint Core software is responsible for building and synchronizing the blockchain across the network.
The ABCI application is responsible for processing and validating all transactions that get stored in the blockchain. Each blockchain could have a different ABCI application for a different application scenario or logic. For example, a blockchain that records cryptocurrency transactions will have a very different ABCI application than one that records real estate deeds.
An external application sends a transaction request to any node on the network. The request is received by the Tendermint Core software. Notice that here we do not define what exactly is a transaction, as there are many different blockchain applications, and they have different definitions for transactions. For instance, some applications might define transactions as straight token exchanges, while others would consider recording a real-world event as a transaction. For our purposes, a transaction is simply a series of bytes to be recorded on the blockchain.
Upon receiving the request, the Tendermint Core software immediately forwards the transaction request to the ABCI application running on the same node. The ABCI application parses the transaction data and makes a preliminary determination on whether it is a validate transaction. At this stage, the transaction will not result in any state change (i.e., nothing gets written to the database managed by the ABCI application).
If the ABCI application’s preliminary determination is valid, the Tendermint Core software will broadcast and synchronize the transaction to all nodes on the network.
At a fixed time interval, the network creates a new block with all the transactions that are validated during this time interval. Validator nodes will vote on the new block, and if at least two-thirds of validator nodes agree, the new block will be appended to the blockchain and broadcast to all nodes on the network.
Once a new block is added to the blockchain, each node will again rerun all the transactions included in the block to the node’s local ABCI application for processing. At this time, the ABCI application can update its database to store the application state changes caused by those transactions.
Figure 19.2 summarizes the workflow described.
In the next section, let’s go through the exercise to set up a single Tendermint node to see how the Tendermint Core software and ABCI app work together.
Let’s download the precompiled Tendermint binary applications from the following web page: https://tendermint.com/downloads.
You will need the tendermint
and abci
binaries for this step. Unpack the downloaded zip packages, and you will get the following executable binary files:
tendermint dummy counter abci-cli
Move the binary files to the $HOME/bin
directory so that they are accessible from the command line. You can now run them to check their versions.
$ tendermint version 0.10.3-'8d76408
The dummy
program is a simple ABCI application. Once running, it listens for transactions from Tendermint Core on TCP port 46658. Being a “dummy” program, it will simply approve and validate all transactions. You can run the dummy program in a command-line window.
$ dummy Starting ABCIServer Waiting for new connection...
Next, in another command-line window, initialize the Tendermint Core software on this machine. The init
command creates the configuration files for a network made up of a single validator node.
tendermint init
If you have initialized Tendermint Core on this computer before, you could either delete the $HOME/.tendermint
directory and init
again or use the following command:
tendermint unsafe_reset_all
Now, you can start the Tendermint node. The node immediately connects to the dummy
ABCI app through port 46658 and starts to create blocks.
$ tendermint node Executed block module=state height=1 validTxs=0 invalidTxs=0 Committed state module=state height=1 txs=0 hash= Executed block module=state height=2 validTxs=0 invalidTxs=0 Committed state module=state height=2 txs=0 hash=
The following is the output from the dummy
window, showing that a Tendermint node is connected:
$ dummy Starting ABCIServer Waiting for new connection... Accepted a new connection
The Tendermint node listens on port 46657 for new transactions. So, let’s now send a transaction to the network.
curl -s 'localhost:46657/broadcast_tx_commit?tx="hello"' { "jsonrpc": "2.0", "id": "", "result": { "check_tx": { "code": 0, "data": "", "log": "" }, "deliver_tx": { "code": 0, "data": "", "log": "" }, "hash": "995DE4D6FA43728945C235642E5DCCB64C08B4A2", "height": 30 }, "error": "" }
The transaction is received by Tendermint Core at port 46657, forwarded to the dummy ABCI app at port 46658, validated by dummy
, and then recorded in the blockchain by Tendermint Core. The dummy application stores the key-value pair in the transaction in its own database. The Tendermint console shows the following:
$ tendermint node ... ... Executed block module=state height=30 validTxs=1 invalidTxs=0 Committed state module=state height=30 txs=1 hash=EA4...934 ... ...
Finally, we can query the blockchain for the transaction we just sent. The query is passed to the dummy
ABCI application. Since the dummy
application saves the value in all transactions it validates, it will be able to interpret and respond to the query and pass the results via Tendermint Core.
curl -s 'localhost:46657/abci_query?data="hello"' { "jsonrpc": "2.0", "id": "", "result": { "response": { "code": 0, "index": 0, "key": "", "value": "68656C6C6F", "proof": "", "height": 0, "log": "exists" } }, "error": "" }
Of course, most blockchain networks have more than one node! To set up a network with multiple nodes, you can do the following.
First, run the tendermint init
commands on all node computers on the network. In the $HOME/.tendermint
directory, you will see the genesis.json
file, which contains this node’s public key. The node’s private key is in the priv_validator.json
file and should never be shared with anyone.
{ "genesis_time":"0001-01-01T00:00:00Z", "chain_id":"test-chain-dmpZNA", "validators":[ { "pub_key": { "type":"ed25519", "data":"F8...DC47D" }, "amount":10,"name":"" } ], "app_hash":"" }
Second, edit the genesis.json
file on each node to add all peer nodes’ public key into the validators
array. Those nodes are known as initial validators for a network. The network can add or remove validators dynamically once it is running.
Finally, on each node computer, you can start tendermint node
and the ABCI application (e.g., dummy
). The nodes will discover each other by their public keys and then form a network. Notice that nodes on a network must run the same ABCI app since all nodes must process and validate transactions the same way.
Now you have a private Tendermint blockchain network. You can make it validate and record any transaction you like by writing your own ABCI applications, which you will see in Chapter 20. The Cosmos foundation also runs public test networks for developers and validators. For now, let’s review how the Tendermint blockchain network works.
A new transaction is received and preliminarily validated on a single node.
At a fixed time interval, validator nodes package all transactions since the last block and propose a new block.
Once validators agree on a new block, it is broadcast to all nodes.
All nodes process all transactions in the same order when a new block is added to the blockchain.
As a result, the application state of the blockchain (databases managed by the ABCI application) on all nodes are in sync.
In this chapter, I discussed how the Tendermint blockchain works by separating the consensus logic and application logic. The application logic, encapsulated in an ABCI application, allows developers to write versatile blockchain applications. I also demonstrated how to set up a Tendermint node and a network with a simple ABCI application.