How to create your own blockchain-based Cryptocurrency from Scratch!

Antreev Singh Brar
11 min readMay 10, 2021

What is a Blockchain?

Blockchain is a decentralized, distributed, and public ledger that contains records of transactions between parties. So, what do these heavy terms mean?! The Blockchain is ‘Decentralized’ because several ‘authorities’ have the power to make additions to Ledger. The Blockchain is ‘Distributed’ since anyone can take a look at its contents. Upon first glance, the whole concept seems absurd violating the very meaning of privacy. But after reading the blog you’ll agree that with a bit of Cryptographic magic this system is indeed quite interesting.

Working of BlockChain

Here is a simple model of the Blockchain we implemented.

Hereon, we shall refer to the ‘authorities’ as Nodes. We’ll draw analogies to real-life currency to elucidate our points.
Suppose Alice wants to transfer X amount of money to Bob. The transaction is only considered when it appears in the ledger. To add the transaction, Alice will have to send the transaction to a Node that holds the power to edit the ledger. This is exactly what Alice will do.

Let’s see how a transaction looks like. The Transaction has 2 fields ‘Input’ and ‘Output’.
Alice must have at least X amount of money with her. This X that Alice has can be attributed to Transactions made earlier to her which are present in the ledger. Therefore, ‘Input’ contains references to Transactions that have been made to Alice. The Transaction is said to be spent if it is referenced in the ‘Input’ of any Transaction present in the ledger.

The ‘Output’ contains recipients and the amount sent to the recipient. Here, we have a single recipient but the implementation allows us to transfer money to multiple accounts.
A quick note on the implementation details: After Alice references some transactions in the ‘Input’ and creates the ‘Outputs’, she might have some money left over. So she sends the remaining amount to herself.

Once a Transaction has been made in the required format, it can be sent to a Node.

We mentioned a distributed ledger; what it means is that each Node has a copy of the ledger and it makes the changes in its own copy. Had we talked about a central ledger then we would’ve had to deal with numerous issues. Who creates the rules for editing a ledger? Who verifies if an edit is correct? So everyone keeps a copy. We’ll see later how everything fits in.

Since the ledger must conform, a Node must forward any Transaction it receives or creates to other Nodes in the Network. The Node can have a limited number of peers and those peers will further propagate the message to their peers. So, the Transaction gets propagated throughout the network.

This seems pretty straightforward until now, right? Let’s turn our attention to problems that might arise.

->What if someone sends a fake Transaction?
->What if a Node puts an invalid transaction into its ledger?
-> Why should anyone become a Node?

For verification, we shall now bring in Cryptographic magic. We’ll not delve into those right now, but we’ll assume that there is a verifyTransaction() function that uses these primitives to ascertain whether a Transaction is valid or not.
There are some other aspects of the verifyTransaction() too: verifying whether Transactions referenced in the Inputs are unspent, Outputs are valid and the sender doesn’t spend more than he has.

To help integrate this, let’s define a Block. A Block is a group of Transactions along with some other data of its own which aids us in verification.

The ledger we referred to earlier is actually just a chain of Blocks. Each Block is linked to the previous one by a parent hash. This in fact starts resembling a Linked List in a sense and it’s helpful to keep that picture in mind for better visualization.

When is a Block added to the Blockchain?
Now we’ll introduce a term that is ubiquitous to Blockchains and Cryptocurrencies: ‘Mining’.
After a Node receives some Transactions, it verifies them and groups it in a Block. Mining is a race in which each Node tries to create a Block to add it to the Blockchain.

Now we’ll talk about the cryptographic aspects of the Blockchain model and why Mining is a race.
After setting all the relevant data for the Block, we convert it into Binary Data of a specific format. We also append some bits at the end. These bits represent a number which is known as the ‘Nonce’.
Now for the juicy part. SHA-256 is a one-way cryptographic hash function which when operated on binary data returns a 256-bit output between 0 and 2^(256). What does one-way mean? The function is deterministic, i.e., it will always produce the same output for a given input. So for a given input, we can always find the output. But it’s infeasible to figure out the input given only the output. Even small changes in the input make drastic changes in the output. So the only feasible way to find the input is by Brute-force logic, tediously checking every possible input by guesswork.
For a Block to be considered valid, we require that the SHA-256 of the Binary Data of the Block be below a certain Target Value. If the nonce doesn’t satisfy this condition, we try a different nonce. There are some other elements of randomness too, like the incorporation of the timestamp at which the Node starts mining the Block. This ensures that it’s not just about exhausting all the values of the nonce. This gives small Nodes with less computational power a fair chance. The Node that first finds such a Nonce wins and gets to add the Block to the Blockchain and forward it to all its peers. Now, the Transactions present in a mined Block are valid. Only now can these Transactions be referenced in Inputs.

These computations are referred to as Proof of Work. But why were these methods chosen? Suppose our Target Value is T. Assuming random numbers corresponding to nonce values, what is the probability of our output being less than T? It’s T/ 2^(256). So, the expected number of attempts before we find our nonce is 2^(256)/T. Try to work around with numbers and you’ll appreciate the sheer amount of computations required for this task. This aspect helps us tackle a number of issues.

What if someone tries to edit previously mined Blocks?
Any small change will result in drastic changes in the SHA-256 hash. Since each block also contains the hash of the parent Block, it will also get changed. Hence, all the subsequent Blocks will also get changed. This means that the malicious party must do those expensive computations to find the nonce all over again.

Another concept generally talked about, is that the Blockchain with the most computational work is considered the correct one in case someone has to select one chain to build on top of. This also prevents Nodes from maliciously propagating wrong chains. Suppose Alice wants to misdirect Bob into using the wrong Chain. She might’ve gotten lucky in winning the Mining race a few times, but ultimately all the other Nodes will catch up and they will produce a longer Chain. Then Bob will shift to that one since it has more computational work done. Such attacks are possible only when someone can gather 51% of the total computational power and take over the chain. But the computational power is so huge that it’s almost infeasible and useless to spend that amount only to destroy it.

Why Mine??

The Node to win the race in finding a suitable nonce gets a certain amount accredited to his account. This amount comes out of thin air and is the source of new currency in the system. This incentivizes the Nodes to use their Computational Power to mine the Blocks.
Another source of income for the nodes is that senders who want to make an urgent transaction can set aside some money for the Nodes which first mines the transaction. This encourages miners to put the transaction in the most recent Block to be mined.

Implementation

Let's dive deep into the code to understand how various segments of it come together.

Starting with frontend, you can do 4 things>

  • Register an account
  • Check account balance
  • Make an alias
  • Transfer coins to another account

Generate Key function uses generateKeyPair() method which is an inbuilt application programming interface of crypto module to generate a new asymmetric key pair of the specified type. In this code, I used RSA2048 encryption ( 2048 is the key size in bits ). The returned public key would be used as an Account ID.

Let’s say if someone wants to transfer money to another account, the money gotta come from somewhere, therefore every node keeps a list of UnusedOutputs. These are basically a list of transactions in which someone transferred their money to you. Every such transaction can be used just once. So let's say you received 100,200,50 from your friends and you wanna transfer 250 to me :), so the code will combine use all these transactions (getting you 350 as input) and make two outputs — one to me: 250, one back to yourself: 100 -transaction fees(this is the incentive to the miner to mine your block). Note that the money you transferred back to yourself would be added in UnusedOutputs list, thus you can make further transactions with it later.

Output = {"recipient":public key,"amount": money_transferred }

SHA256 Hash of the blob [number of outputs][Output1][Output2][…] is calculated as the number of outputs can vary but the SHA256 hash will give a hexadecimal value of 32 bytes

.

To maintain authenticity of transaction we have to calculate signature (padding:crypto.constants.RSA_PKCS1_PSS_PADDING,saltLength:32 using private key) of the the blob >

[transaction ID][index][SHA256 hash]

Signatures verify that the person who owns the account has made the transaction. In layman's terms, let's say you have a message you want to broadcast to a large number of people, but there are a large number of imposters in the city. Therefore you need to devise a way to prove that you are the one who wrote the letter. Ronald, Adi, and Leonard come to your rescue and show you the possibility of an RSA cryptosystem. In this system everyone gets two keys — private and public, now every time you write a letter — you encrypt it using your private key and post the original letter, encrypted letter, and your public key on the billboard. If any person is able to decrypt the encrypted message using the public key and obtains the original message then the person can surely state that the owner of the public key is the one who wrote that letter as the letter couldn’t be decrypted with any other private key.

Input > {"transactionId": transaction id ,"index": index , "signature": signature}

Furthermore this functions makes a json object of input array , output array and makes a POST API call to /newTransaction endpoint.

Public keys are nice but they are way too impractical to be used by the general population. Imagine someone enquiring about your account detail and you have to tell him a 32 alphanumeric code (with capital and small letters :\/ ). It would be way easier if usernames were mapped to public keys. This function enables the user to map an alias to a public key (in utf-8 encoding)by sending a POST API call to /addAlias .

Other than these — there are some miscellaneous functions like outputbuffer() which take output object and returns an output buffer, checkBalance() , getUnusedOutputs() that are pretty trivial.

Now let’s check out the backend

We know that how money gets transferred but here is an important aspect “Where does the initial money come from ?”, the answer is pretty straightforward — Someone would have to transfer money to you when you register yourself as a user.

The backend code is about 1000 lines long, so no point in explaining which function does what, instead here is the general flow of how the algorithm would work.

Let’s say you wanna join the network as a miner and earn some bucks.

  • Start off by adding a peer list, basically you already have some peers and you ask them about their peers ( if they are already in your peer list, you leave them otherwise append them in your list). Sort of like asking your friends to introduce you to more of their friends at some party.

NOTE — This is important to understand that the nature of this network is such that all information is relayed to all peers. Let’s say you (as a miner ) got information that some account has added an alias or received some transaction, block, or mined a block yourself then all of this would also be sent to all the peers in your peer list.

NOTE 2 — Another important aspect of blockchain is that its highly secure(provided you don't have some large evil organization trying to control more than 50% of the network, in that case, you are doomed. Apart from these minor hiccups, it's pretty secure)and one of the reason is that everything is verified at all ends. I won't go into the specifics details but we will see soon. Keep reading.

  • From the rest of the peers get the pendingTransactionList ( transactions which are yet to be mined into a block and then appended to the blockchain ) and obviously, the blocks mined so far. We process every block and check for its authenticity like if its parent’s hash is correct if all transactions are valid. Basically, we start from scratch and keep tabs on who paid whom (from the beginning of time), check if any person had enough amount in his wallet to make that transaction, etc. If there is any mismatch in accounts, we would raise a flag. If all goes well, at the end of block processing, we would have obtained the unusedOutputsList which would be used by users to make further transactions.
  • So with the essential ingredients at hand, you are all ready to mine a block. Now it's all just a race to see which node is able to mine the block the fastest. You take a bunch of pending transactions, check if they are valid and bundle them together, give them a partial blockhead(just some fields like a hash of parent block, index, target, hash ) and start mining. I called it partial as we would obtain two more fields after mining( timestamp and nonce). In the end, we would combine the complete blockhead to the block, process it (the tedious job we did while receiving blocks from peers), and send it to the rest of our peers.

I guess I should explain what mining is —

In layman's terms, we have a hash function that takes an input and always gives the same output (no random weird stuff) but we can't predict what its output would be. Like I can’t say that for this output I can have this input (just one way), and the output is some number in hexadecimal format.

We have a predefined string with us and we need to find another string such after appending with this one would give the output smaller than our desired target. The best method is just to keep trying all the strings till we find the one we are looking for. This is the crux of mining — it is basically shooting in the dark and depends on luck if you are the first one to find that string. No one has any clear advantage (unless your computation power is very large and can shoot a lot of shots).

NOTE — If while mining you receive some mined block then you would have to kill the miner, update unusedOutputList , pendingTransactions and start all over again.

That’s it. Your mined block would propagate the rest of the network and every node would perform the same steps (check for validity, update the lists and append to their blockchains).

Here is the main code for the backend

Here is the code for the miner

I am sort of proud of this project 👻. Hope to see you all doing crazy awesome stuff as well.

--

--

Antreev Singh Brar

I love to meet amazing people, share ideas and collaborate for revolutionary projects. Well , I am smart as well