That’s probably the most intriguing question you might want to ask. In this article, we’ll answer it and more questions too:
- Why have we chosen Haskell for Enecuum blockchain?
- What achievements were made?
- What’s next?
Why have we chosen Haskell for Enecuum blockchain?
Haskell has a long story as a programming language. It has been proved that programs in Haskell have many advantages over other languages, and all of them came from the nature of the language: high level, statically and strongly typed, functional, nearly mathematical, with very powerful and safe idioms inside.
- High stability. It’s much more easy to achieve stability in Haskell comparing to all the mainstream languages.
- High correctness. It’s possible to get any level of correctness of programs lifting more logic to the type level.
- Very high security. Haskell doesn’t allow a programmer to make silly mistakes like buffer overflows or type mismatch. All the primitives we have in libraries are known to be safe or not safe directly from the type definitions.
- Great parallel and concurrent possibilities. Haskell is probably the best language in this class. It has a lot of nicely designed approaches to parallel programming. Some of them are coming from its functional nature, some of them are made with math accuracy (for example, Software Transactional Memory or Par monad). With these approaches, many subtle parallel bugs can be eliminated at start. And, of course, with monads, parallel and concurrent code can be surprisingly simple.
- Very good project maintenance. Due to Haskell’s powerful type system (more powerful and way better designed than C++ or C# have), refactoring becomes a walk in the forest because the compiler will point to more errors and mismatches than you might expect.
- Greatest abstractions to build a good code. Monads, functional programming idioms, combinators, declarativity, domain-specific languages, — all these and many other things allow to write a concise, correct and safe code.
- Nice testability of the code due to such concepts of functional programming as purity, immutability and side effects control.
What achievements were made?
In Haskell, we have developed a framework, a domain-specific language to build our blockchain project. Designing this eDSL, we were pursuing several goals:
- Make implementing of blockchain business logic as simple as it can be (reduce accidental complexity of the project).
- Nodes behavior should be described as some kind of script that can be written separately from the implementation details.
- These node scripts should be easily testable with both real and test environments.
- Allow to tune blockchain business logic separately from tuning its performance. Thus, when we optimize our framework (from technical point of view), the scripts stay the same.
- Remove all the unnecessary implementation details to the background and allow them to be changed independently from logic (this is also known as Inversion of Control made as Interfaces and Implementation).
So let me present you some test node script that deals with transactions in the graph. As long as this script for test aiming to show some graph work, it only contains transactions organized as linked list. The script also works with node’s specific state.
Notice several things here.
- First of all, this is a part of node behavior serving some RPC call. That said, when the acceptBalanceChange handler is called, it attempts to update the graph checking if it’s even possible to add such transaction on top of others. It might be the new change makes the balance negative, so the transaction is invalid and will be rejected.
- Also, the script works in concurrent environment. This means, all the graph and variables work will be made safely (atomically), and none other call can ruin the data correctness. This is achieved by using Software Transactional Memory inside, which also provides a lock-free way to work with concurrent data.
- The script doesn’t look too complex or verbose. It’s certainly true that one needs to get some ability to read (a simple) Haskell code, but when it’s done, the script can be understood easily.
- The script has several levels of nesting. Every level is denoted by its own domain-specific language and every language allows only the operations valid in place. Thus, you cannot make any side effects in the “transaction” block (inside the atomically block), because any time you evaluate an effect iside a transaction you risk to invalidate your data. Our languages structure is designed to prevent problems before they can even occur.
- This is an implementation-free script. It only declares the behavior but doesn’t evaluate it actually although you might think it’s something imperative and immediately evaluatable. However, the script is a pure declaration that we can either start evaluating in the real runtime (and thus make it accept RPC requests from the network), or we can send the script to the test environment and see how it behaves before we bring it to production.
Our next goal is to create Enecuum blockchain v2 on top of this framework. We have a clear view how to create blockchain network nodes with configurable behavior, and we expect the business logic code to be highly accessible and provably error-free from the start.