Kepler Release Announcement

Martin Allen
FOAM
Published in
7 min readFeb 19, 2020

--

Today we are happy to publicly announce the release of Kepler, the official Haskell language SDK for building blockchain applications backed by the Tendermint consensus engine. There are two parts to this post: section one gives a brief overview of what Tendermint is and why you might care about Kepler, section two gives some architecture highlights of Kepler.

Tendermint

An Extremely Brief Summary of Tendermint

Tendermint BFT is a proof-of-stake consensus algorithm designed and implemented around 2014/2015, before proof-of-stake consensus was even cool. The authors then started a company called Tendermint Inc. oriented around use cases and integrations, ultimately culminating in the Cosmos blockchain network. For those of you who don’t know, Cosmos positions itself as a “blockchain 3.0” solution, meaning that it is built to address the scalability and interoperability limitations of networks like Ethereum (a 2.0 solution) and Bitcoin (a 1.0 solution).

I am not an expert on what makes Tenermint-BFT a better or worse proof-of-stake consensus algorithm than others, you can find this kind of information on their website. The below is also a great introductory article:

How do Tendermint Backed Applications Work?

Tendermint-BFT is paired with a socket protocol called ABCI (Application BlockChain Interface). Tendermint-BFT by itself is a message ordering algorithm for a distributed system trying to process state-updating messages in the same order on every node. But this algorithm can’t tell what messages are valid or invalid for your custom application, or how to determine if a node is in a valid state after updating itself with a message. This is where ABCI comes in; ABCI is the hook that allows the consensus algorithm to pass the responsibility of message validation and state validation to your custom application. Any application that receives and responds to ABCI messages from Tendermint core is called an ABCI application.

Since ABCI is a socket protocol, it is itself language agnostic and is defined by a set of protobuf files. This means that in principle you can implement an ABCI application in whatever language you want to.

Why Tendermint and Not Some Other Thing?

If you’re a Haskell or Rust developer, you may have heard of competing platforms like Cardano or Substrate that offer similar “blockchain 3.0” solutions. Cardano has a portion of their network in production (cardano-sl) and they seem optimistic about delivering an application layer in the future. The first production instances of Substrate blockchains have just begun to appear. I think that both of these projects have the engineering skills and resources to do what they’re trying to do, so it’s worth saying at least one word on why we made Kelper in light of these other upcoming solutions.

Why not Cardano? Cardano is seemingly the obvious choice for people who care about static types and formal verification since that’s essentially half of their M.O., but there are also some problems with what you can do with it today. First is that there is a lot of work in progress but very little you can currently do application-wise. Secondly, application development is meant to be written in their custom smart-contract language Plutus. Although Plutus is Haskell-like and probably really sweet and type safe, ̶i̶t̶’̶s̶ ̶s̶t̶i̶l̶l̶ ̶a̶ ̶c̶u̶s̶t̶o̶m̶ ̶l̶a̶n̶g̶u̶a̶g̶e̶ ̶a̶n̶d̶ ̶l̶i̶k̶e̶ ̶a̶l̶l̶ ̶c̶u̶s̶t̶o̶m̶ ̶l̶a̶n̶g̶u̶a̶g̶e̶s̶ ̶i̶t̶ ̶s̶t̶a̶r̶t̶s̶ ̶o̶f̶f̶ ̶w̶i̶t̶h̶ ̶z̶e̶r̶o̶ ̶s̶t̶a̶n̶d̶a̶r̶d̶ ̶l̶i̶b̶r̶a̶r̶y̶,̶ ̶e̶d̶i̶t̶o̶r̶ ̶s̶u̶p̶p̶o̶r̶t̶,̶ ̶d̶e̶v̶e̶l̶o̶p̶e̶r̶ ̶m̶i̶n̶d̶s̶h̶a̶r̶e̶,̶ ̶e̶t̶c̶.̶ ( CORRECTION: The situation is apparently more nuanced and has diverged from what’s in the main Cardano docs. The current situation seems to be explained in this documentation. Plutus looks like an impressive project from a language design standpoint, but it is still correct to say that Plutus’s core is not the intended target of GHC, and future developments in GHC are not guaranteed to benefit Plutus core without additional effort. To understand the level of divergence and any benefits gained, you would probably need to be a Plutus developer, which I am not). Personally if I’m going to write something Haskell-like, I’d rather just write Haskell.

Why not Substrate? Substrate is somewhere between a framework and template for writing custom blockchains in Rust. Like Tendermint, these blockchains are supposed to be application-specific and interoperable with other Substrate chains. T̶h̶e̶y̶ ̶p̶r̶o̶v̶i̶d̶e̶ ̶s̶o̶m̶e̶t̶h̶i̶n̶g̶ ̶l̶i̶k̶e̶ ̶a̶ ̶s̶t̶a̶n̶d̶a̶r̶d̶ ̶l̶i̶b̶r̶a̶r̶y̶ ̶(̶c̶a̶l̶l̶e̶d̶ ̶t̶h̶e̶ ̶R̶u̶n̶t̶i̶m̶e̶)̶ ̶w̶h̶e̶r̶e̶ ̶y̶o̶u̶ ̶c̶a̶n̶ ̶p̶i̶c̶k̶ ̶a̶n̶d̶ ̶c̶h̶o̶o̶s̶e̶ ̶c̶o̶m̶p̶o̶n̶e̶n̶t̶s̶ ̶o̶f̶ ̶y̶o̶u̶r̶ ̶a̶p̶p̶l̶i̶c̶a̶t̶i̶o̶n̶.̶ (CORRECTION: They provide a system called the runtime where you can plug in custom defined components (runtime modules) of your application and configure execution options of basically any part of your blockchain you want. As I’ve learned, it’s worth keeping the glossary open when reading the documentation, there is a non-trivial taxonomy of lingo and acronyms (e.g. FRAME, pallets, SRML, STF, primatives, runtime, runtime-modules).)

The downside is that to start developing a blockchain you essentially have to fork the substrate repo and extend from there. This means that you must develop the application in Rust, and that pulling in upstream changes from Substrate improvements is at best case a nerve-racking git merge. (NOTE: I stand by this as a metaphor in the face of criticism, the operative word is essentially — see “substrate is somewhere between a template and a framework” above. I’ve actually attended a live substrate workshop and followed the collectable tutorial online. The amount of boilerplate, included files, and dependencies required to run example projects is a real. Every tutorial I’ve seen geared toward building chains with minimal interesting customizations starts with “to get started, clone the substrate-node-template repository and edit these files”. If what’s in these templated files is actually required, I seriously doubt many people outside the substrate team could produce a customized substrate node project without a template. Granted, this might be the reality of the situation if you want to be able to customize literally any aspect of a blockchain, which is certainly valuable but is neither possible nor intended with Tendermint chains, hence Kepler)

Why Kepler?

Since Tendermint allows you to write blockchain applications in whatever language you want, you’re only limited to the languages that implement an ABCI server and ideally a framework for abstracting away the more esoteric internals. As of today, the language that by far has the most support is golang with the official cosmos-sdk, with options in Javascript and some support in Rust. We believe that blockchain application development is the most secure and robust when backed by statically typed languages like Haskell and PureScript, so we decided to build out a general purpose Tendermint SDK in Haskell. Hence Kepler.

Kepler Architecture Overview

For a full gist of how applications are made using Kepler, we recommend you check out the official tutorial. We just mention some highlights here.

Overview

The basic component of a Kepler application is the Module. This module declares a few pieces of information:

  1. The router that the module uses to process transactions.
  2. The router that the module uses to process state queries.
  3. The custom effects and interpretation that the module introduces (more on effects later or see the tutorial).

There is a standard library of modules that you can plug into your application, things like bank for managing token balances, or auth for managing basic account information. You can also create your own modules for managing whatever it is that your application does.

You can easily create dependencies between modules using the type system, so that for example if your module will execute token transfers during a transaction, you can explicitly state a dependence on the bank module. In fact you can even be more granular if you want and state a dependence on only the effect that allows for token transfers.

Applications are defined by simply listing the modules that you want to use. In a servantlike fashion, it will compose the routers for transactions and state queries from the individual modules, and will also automatically interpret your custom application effects to a lower level system that the SDK knows about.

Effects Systems

Sometimes called Algebraic Effects, an Effects system provides a way to strictly segment the capabilities of one section of code from another using the type system. It also allows you to abstract the code from its runtime execution. Kepler is written using the polysemy higher order effects library. In a nutshell, this has a few main benefits:

  1. The SDK clearly segments different responsibilities to different sections of code. For example, although handlers for querying state and processing transactions both have access to the database, the type system does not allow write access during state query execution.
  2. Application developers can define custom effects (e.g. for dealing with tokens, or managing other custom application state) and can seamlessly integrate them with the effects defined by the SDK.
  3. We can change the runtime of the SDK by simply providing a different interpretation for core the effects. Do you want an in memory database for testing or a production database? Do you want to log to the console or Elasticsearch? Do you want to run metrics via Prometheus or simply print them to the console? These kinds of decisions can be made effortlessly with the SDK.

Your Application has a Type

When your application has a type, you can use this type to derive all kinds of other useful tools for your application. Using the same kind of combinator logic found in servant, we are able to generate client libraries from your application type that contain functions for submitting any kind of transaction or querying any state in your application for free. This means for example that if you change the type of even a single message that your application uses for transactions, you will get a compile time error that your tests or client application are broken.

If you’re a developer and want to get involved, join us on gitter and github. You can also find FOAM developer resources below.

Check out our website and join our Discourse. Updates will be posted on Reddit and Twitter.

--

--