Let’s implement a cryptocurrency in Kotlin. Part 1: Blockchain
Inspired by Daniel Stefanovic’s build-your-own-x I decided it’s time to stop reading and start building.
What I cannot create, I do not understand. Richard Feynman
In this two posts series I’m going to explain how you can build a very simple, yet functional, cryptocurrency. It’s based on Bitcoin and I hope by the end of the series you’ll be to tell what’s the difference between a blockchain and a cryptoasset.
I assume a reader has some programming experience, but you should be fine even if you’re a beginner. I’m going to use Kotlin, since I’ve been tinkering with it for a while, but it can be implemented in any language, actually, go ahead and implement it in your favourite language!
This is probably going to be the easiest part: head to IntelliJ website, download the community edition and create a new project.
A little bit of theory
There are two way to organize communication between parties:
- Centralized, there all communication goes through an intermediary. For example, in traditional banking, if you were to transfer a money to your friend you’ll do so through a banking UI and bank might take a commission for that.
- Decentralized or distributed, there every party can communicate one another without an intermediary. For example, BitTorrent there you download files directly from the users, instead of a server.
Either way there’s a need to store an information somewhere, be it a list of transactions made on your account or a list of users to download the files from.
In the first case the information is centrally stored somewhere on a Bank’s servers in the second — it’s distributed among users.
Blockchain is a storage solution for a distributed system.
Think of it as of Amazon’s S3, but owned by everybody and not Amazon.
Blockchain is made of a list of blocks where each block has its own hash, previous or parent block hash and an auxiliary data like timestamp and, for example, a list of transactions included in that block. Essentially one block captures system’s state at particular moment.
It’s important to see what the block’s hash is made out of:
Block hash = hash(parent hash + aux data)
Having parent hash included means it’s not possible to change parent’s data without affecting the children blocks down the chain, thus Blockchain.
Since 2/3 of the block’s data contains hashes we’re going to write a small utility function to get hash from a String.
Blockhains use special types of hashes which are called cryptographic hashes. Bitcoin uses
SHA-256 and we’re going to use the same. The actual implementation is done as Extension Function to the existing String class.
It’s pretty straightforward: convert
String into a
ByteArray update MessageDigest with it and convert the digest into the
It’s easy to model blocks using Data Classes. They generate all java boilerplate and enforce immutability during compile time.
As I mentioned before hash includes
data, which is empty in our case and the
timestamp. Bitcoin has a very similar structure with some other extra fields, which we can ignore for now.
Let’s create a couple blocks!
And possible output:
Block(previousHash=0, data=I'm the first, timestamp=1530024961908, hash=dc5e733f548bc8240d04f02884ead8c2ddb4a2add0606277bd8ec7c75983d793)Block(previousHash=dc5e733f548bc8240d04f02884ead8c2ddb4a2add0606277bd8ec7c75983d793, data=I'm the second, timestamp=1530024961935, hash=1621970956c63d89e077a9122e122fa45ba86d5f478f4fa2b4d7b6cf3f39efa7)Block(previousHash=1621970956c63d89e077a9122e122fa45ba86d5f478f4fa2b4d7b6cf3f39efa7, data=I'm the third, timestamp=1530024961936, hash=d5a1d82930d157013adb2f8bfb90449dbae66b768c211a207202a80f478d4f64)
So far we only created blocks, let’s add a container to store them — Blockchain.
Right now there’s no limit on how many and how fast we can add blocks to Blockchain. In a centralized system the central authority controls that process, but since we’re dealing with a distributed system we can’t afford that.
As it turned out to be the problem isn’t new and your
Inbox is dealing with it every day in the form of spam: a lot of spammers want to write (send) to you.
About 20 years ago Adam Back proposed HashCash as a solution. Adam’s idea was to add a cost to every email being sent so that mass emailing would become costly, but he didn’t want to take money and instead his idea was to ask a sender to do a CPU intensive task, for example, finding a specially formatted hash. The cool part about this solution is that there’s no easy way to find such hash without doing a brutforce.
Bitcoin uses the idea and expects a block’s hash to be
special in order to be valid:
For Block to be valid its hash has to start with a certain number of
As I mentioned before this can only be achieved by the brutforce, but our current Block model is immutable and doesn’t allow any change. Let’s add a new field called
nonce which we’ll be able to change:
Once we have that field actual mining algorithm is quite simple: in the loop, we change increate
nonce by one, until we found the
Again, Kotlin’s Data Class removes boilerplate with its Copying. I also changed
add function to mine block, if it’s not already mined.
Difficulty allows to control how fast we can find a cache. Bitcoin adjusts this parameter every couple of weeks based on the average time it took to mine the blocks during that time. I have MacBook Pro 2015 model and with difficulty more than
10 it already takes significant amount of time to mine a block.
Now that we can create, mine and add blocks let’s add a function to validate Blockchain.
For our Blockchain to be valid:
- Blockchain is valid if it’s empty
- Blockchain contains a single block with a valid hash
- All blocks are mined
- For every block in blockchain:
- Current block hash is valid
- Previous block’s hash is valid
I used when construction and it looks kind of neat:
We just implemented a very basic, but functional Blockchain in less than 100 lines of code, congrats!🎉
I hope, you, like me, now have a better understanding of how Blockchains work and in the part two I’m going to write about we can store transactions on Blockchain and finally make a cryptocurrency out of it, so, stay tuned.
Source code on GitHub.