A 1024 Tribute: The Simple Chain
Two weeks ago we brought CyberMiles’ supernode online. Because the CyberMiles mainnet runs on Tendermint, I spent last week digging into Tendermint, learning as I went and putting together a slide deck to introduce it.
Tendermint is a consensus engine born out of PBFT, and on top of it sits an Application Blockchain Interface (ABCI) that lets blockchain developers focus on what services to offer and how to maintain the state of those services — leaving the tedium of reaching consensus, managing the mempool, and running secure p2p communication to Tendermint itself. Tendermint is written in Go; its ABCI interface is defined in protobuf and talks to the application layer over raw TCP or http2 (gRPC).

Sunday rolled around with nothing to do, and I felt like building something with Tendermint. Alas, Tendermint offers no Elixir ABCI implementation, the community Erlang one is missing a few pieces, and I really dislike describing protobuf with Records in Erlang — so I used Tony’s protobuf library to write an Elixir ABCI implementation, published at github.com/arcblock/ex_abci, and then implemented the counter example app that Tendermint itself ships — using the blockchain’s immutability to maintain a single, network-wide counter.
With ex_abci, the core of the counter app is only a few dozen lines: implement the info, check_tx, and deliver_tx interfaces, and that’s it:

Such an app is fine as a hello world, a sanity check on whether Tendermint is trustworthy — but it isn’t trustworthy itself. Tendermint also ships a kv store example, which still doesn’t get at the core elements of a blockchain, so I got the urge to build something simple enough — ideally demonstrable within a few hundred lines — called Simple Chain. So what counts as the core element of a blockchain? I think it’s this diagram — the Merkle Patricia Tree (MPT):

This is the heart of how Ethereum stores its World State. I trust my readers know the Patricia tree (prefix tree, radix tree, or trie), and readers with some blockchain knowledge should know the Merkle tree; MPT combines the two into a self-verifying persistent data structure (the way functional programming languages store lists and maps). On MPT and the diagram above, our engineer Peiling Ding gave an excellent talk at the last Beijing Hackathon — those interested can find it on the ArcBlock YouTube channel: “ArcBlock’s Introduction to Blockchain,” where the MPT segment starts around minute 37 and runs about 10 minutes, remarkably clear and accessible. Space is limited, so I won’t expand on it here.
As for Simple Chain, here’s how I thought about the product:
- Account system compatible with Ethereum
- Make full use of all of Tendermint’s interfaces, and explore what they mean
- The chain’s state is stored in an MPT, with the state root after each block commit submitted to Tendermint
- The chain should have basic fault tolerance — e.g., if a tx crashes halfway through execution, it can recover to the previous block’s state and continue from there
- Transactions use a simplified version of the Ethereum tx: a TX contains only from, to, nonce, total, and pub key
- The MPT stores Ethereum-like accounts, each with its own balance, nonce, and num_txs
- The client RPC is integrated directly into the Wallet module, for easy demonstration
It took two days of work for a rough version — untested across multiple nodes — to finally come together; source code at: ex_abci/examples/simple_chain. Let’s talk about its main public interfaces:
- Wallet.new: generate an offline account
- Wallet.declare: each Wallet can, on first use, have the system credit it with 10,000 tokens — mainly for convenience in testing
- Wallet.transfer: one account sends money to another. The accounts corresponding to both addresses get updated in the chain’s MPT; after each block commits, the MPT root — that is, the app state — is written into the block header.
- Wallet.info / Wallet.chain_info: query account info / chain info
Below is the whole runtime process.
Initialization:

Wallet state:

Transfer:



Tendermint block:

State after the transfer completes:

The main technologies this Simple Chain uses:
- Tendermint and ex_abci, naturally
- The MPT implementation in Elixir: merkle_patricia_tree
- Tony’s protobuf implementation. We store accounts in the MPT, and their values are also defined with protobuf
- keccakf1600: the implementation of Ethereum’s sha3, used to generate account addresses and anywhere else a hash is needed (note: we do not use double hashing here)
- libsecp256k1: the ECDSA implementation, used mainly to generate wallets and to sign and verify transactions
The code currently sits under 400 lines, essentially transparent end to end — perfect for understanding Tendermint and the basic logic of blockchain technology.
I’d originally meant to publish this before 1024 Day (Programmer’s Day) — last night I botched the crash recovery, and this morning, driving through the fog on Highway 90, the idea suddenly came to me, so the article is late. Those interested in these technologies can sign up for our future Tech Talks at https://hack.arcblock.io/learning/, and follow the ArcBlock YouTube channel for our past knowledge-sharing sessions.
Happy 1024 Day, everyone!