[erlang-questions] Writing a cryptocurrency in Erlang
Fri Jul 28 14:46:32 CEST 2017
I’ve been writing a new cryptocurrency in Erlang. In this post I’m going to
describe design goals, current status etc., in order to get some Erlang
community feedback, merge it with other feedback, estimate potential community
involvement and decide what to do next. No detailed cryptocurrency knowledge is
assumed; please ask questions in case something is hard to understand. Comments
Below is a plain text version of the post. For other formats, with hyperlinks,
see dat://0284a58ef3a03bd6628720934e3628b3ea748384f98a8c76006a67264d3de00d/ or
Table of contents:
1. Why Erlang for a new cryptocurrency?
2. Why a new cryptocurrency at all?
3. Current status, design goals and challenges
4. Initial coin distribution
5. Development model
Why Erlang for a new cryptocurrency?
Erlang has features that make it apparently a perfect match for writing
cryptocurrencies. Among them are:
- Great support for concurrency. A cryptocurrency network is a set of many
nodes that send themselves messages asynchronously. This can be naturally
modelled in Erlang.
- Libraries for creating state machines. A cryptocurrency is basically a
decentralized state machine.
- Bit syntax, making it easy to handle protocol messages.
Personally I’m a bit amazed that Erlang has not yet been used as a
Why a new cryptocurrency at all?
According to coinmarketcap.com, there are at least 831 cryptocurrencies in
existence and new ones are coming (in many cases containing new features).
However they usually suffer from a number of deficiencies. Let’s list some of
Energy inefficiency of proof of work cryptocurrencies
Bitcoin groups transactions into blocks which form a chain and the actual
problem it solves is: given there may be many alternative valid block chains,
which one is binding? The answer is: binding is the block chain with the most
work invested. How is it implemented? To create a block, (simplifying) you have
to find a nonce which, when hashed with some given data, yields a hash low
enough (“enough” is adjusted so that blocks are created every 10 minutes on
average). Therefore one could say that Bitcoin “miners” participate in a
lottery and each nonce is one lottery ticket; the more computational power you
have, the more nonces you are able to check and therefore the more lottery
tickets you have.
This is a solution both elegant and inefficient, as there are no limits on how
many nonces can be tried, hence many computational resources are invested to
meet economic incentives given. On the other hand, if there are little
incentives, it would be relatively cheap to attack the cryptocurrency.
Low entropy of proof of stake cryptocurrencies
To not perform “wasteful” computations, a simple restriction has been proposed:
instead of freely chosen nonces, money addresses (simplifying) are used in that
role and hash threshold values are proportional to the amount of coins an
address holds. Therefore the set of lottery tickets is very limited, with the
currency itself playing the role of a scarce resource instead of computational
power. A side effect is that attacking the currency is much more expensive and
generally unprofitable (as it would ruin the value of coins used to perform the
attack). The first free, fairly distributed (i.e. with no privileged entities)
cryptocurrency which has been using this algorithm is Peercoin. The first such
cryptocurrency using proof of stake in 100% is BlackCoin.
The problem here is the following: how is the common hashed data chosen? It
turns out it is usually generated deterministically from the data stored in the
blockchain in some obfuscated way. However, since block creators can choose
data which is put in the blocks, they can possibly try to manipulate that data
in their favor. In other words, if we want to draw addresses that are entitled
to generate blocks, we need a good source of entropy and getting entropy bits
from non-random data over which people have some degree of control raises many
Inflexible economic models
Bitcoin creates one 1MB block around every 10 minutes, therefore transaction
volume is limited to around 100 KB/minute. Currently it means that high fees
need to be paid to get a transaction confirmed, but in case of low demand it
would mean that fees too low would be paid (as fee income is given totally to
the block creator, but transaction-induced costs are distributed on the network
To make things worse, there is a portion, lowering in time, of newly-created
coins in every Bitcoin block which are also given to the miner. Currently this
causes more mining power to be used and when it diminishes, it may happen that
there is many unused mining power left, creating some security threat.
Bitcoin is not as simple as sending money from address A to address B. Instead,
each transaction creates at least one so-called unspent transaction output with
an associated script (written in a stack-based language). To spend an output,
one needs to provide an input to its script so that the script returns true.
Usually it means just proving that one is an owner of an address, but using a
programming language adds some complexity with not so much benefits.
There are also more ambitious cryptocurrencies like Ethereum which aim to
generalize cryptocurrencies to allow performing arbitrary, decentralized
computations in Turing-complete environments.
Currently one can create an unspent transaction output in Bitcoin which
contains just one satoshi (0.00000001 BTC) and it will stay in the blockchain
Bitcoin has been distributed fairly, i.e. proportionally to the computational
power invested; no entity has been privileged. However this does not apply to
all cryptocurrencies. Some of them are premined (the developer grants some
amount of coins to himself) and in some the developer sells some amount of
coins during a so called Initial Coin Offering (ICO). As an extreme example of
the former, consider a situation where developer premines 99% of coins. He then
has powerful means to manipulate the price. The latter seems to be problematic
in particular because it is hard to determine whether the developer is not
“buying from himself”. To create a big community supporting a cryptocurrency,
fair distribution seems to be an important issue.
Current status, design goals and challenges
I’ve written a (mostly functional) cryptocurrency prototype using Tendermint.
Tendermint (written in Go) is a consensus engine, i.e. it handles order of
transactions, gossiping and creating blocks, while a programmer can focus on
writing a state machine. State machine is bridged with Tendermint by
abci_server using Protocol Buffers. Besides other advantages, every block in
Tendermint needs to be signed by at least 2/3 of the so-called validators,
hence there are no possible forks from main chain. Therefore a transaction is
either confirmed or not, instead of Bitcoin’s “a transaction has n
confirmations”. This allows some significant simplifications to be made.
The state machine is written using gen_statem and tested using Triq. Its code
is currently nearly 2000 lines, with tests being about 2 times longer than the
implementation. Small part (calculation of quantiles) is written in LFE.
gb_merkle_trees library acts as a primary database and there is currently no
cache, which makes the application easy to test (as there is no hidden state),
but may eventually lead to scalability problems. I hope that it won’t happen
sooner than before gaining significant popularity though; a general balanced
Merkle tree consisting of 100,000 random 32-byte keys and 32-byte values takes
about 18 megabytes when serialized to binary and it took about 15 ms to find
the biggest value using Intel Core i5-5200U.
State transition logic aims to be simple, as there is nothing inherently
complicated in money sending. Therefore there is no scripting language.
Instead, a few types of transactions are present which do the most needed tasks
and money is associated with addresses/accounts, similarly as in a banking
system. In some cases it may be necessary to create addresses managed not by a
single key, but by an arbitrary combination of keys. For example, a company may
want to allow its balance to be spent either by its chairman or by at least two
board members. This, in non-complex cases, can be achieved by allowing
addresses to be not only public keys, but also root hashes of Merkle trees
containing all authorized public keys, combined with Schnorr signatures’
feature of combining multiple public keys and signatures.
A simple wallet is written as a separate EScript (production wallet can be
written in another language). Tendermint acts as a bridge between the wallet
and a node holding the state.
To make the economic structure adaptive, dynamic transaction fees decided by
consensus are going to be used. Fees from blocks should not be distributed only
to block creators, so they cannot service themselves for free. The topic of
economic incentives is already covered in the implementation, but it needs to
The problem with Tendermint is that it doesn’t solve the entropy problem. This
can be solved using publicly verifiable secret sharing; the repository
pvss-haskell used in Cardano has few lines of code, so (assuming it contains
complete implementations) it should not be very difficult to implement. However
in the initial phase the problem can be bypassed by using the NIST Randomness
Beacon. Later a source of verifiable entropy can be picked, maybe outside of
the cryptocurrency itself. See the paper “A random zoo: sloth, unicorn, and
trx” for a discussion of some possible options.
Solving the entropy problem will need some changes in Tendermint. The same
applies to implementing an incentive model (see the last release note for 0.10
version). In general, a question can be asked whether a custom consensus engine
written in Erlang would not be better in the long term.
To achieve fair distribution (i.e. a distribution with no entity privileged), I
propose to use proof of burn, that is, people will get a portion of the initial
distribution of coins proportional to the amount of another cryptocurrency they
destroyed in a selected period. I propose to burn BlackCoin, as it has been
fairly distributed and is the first free and 100% proof of stake coin (besides
that, it already has a command for burning coins). I’ve written a simple
program that can be used to list burnt outputs.
Nothing fascinating in this topic, but some choices have to be made. I propose
- Apache 2.0 as the license.
- GitLab for repository hosting and issue tracking. GitHub is more popular,
but GitLab is free, functional, has a praised CI and seems to be more
neutral as a company, so why not give it a try (maybe with a GitHub
- IRC for eventual chat. Slack is proprietary and has an official web client
available only for a few selected browsers, making it an unfortunate choice
for a free project. Perhaps Mattermost can be considered as an alternative.
Ercoin? KJCoin? Any other ideas?
More information about the erlang-questions