Harsh Vishwakarma

Mar 10, 2021

5 min read

Blockchain in Rust

How to build a blockchain in Rust

The source code is available here. Feel free to dive in.

We should have a fair understanding of Rust programming language and have Rust installed on our system. It’s also good to know, how HTTP requests and HTTP Client like Postman or cURL work.

The best way to follow this blog is to read it to the end and then replicating it as you see best. As, the code is divided into different modules, you may have to take a look into the source code directory.

Now let’s get started.

What is a blockchain?

A blockchain is a distributed and decentralized way of storing data, such as transactions publicly shared across multiple nodes. As the name suggests, Block-Chain, in a blockchain multiple such blocks of transactions are linked(chained) together using hashes. The hash of a “Block” is dependent on the hash of the previous block in the chain.

What is “distributed”? Suppose you have five kids and they want to eat ice-cream. Instead of giving all money to the oldest one, you give 50 cents to each of them.

What is “decentralized”? Now what you did above was not just sharing the money. You also shared the responsibility among them equally. This shared responsibility is the process of decentralizing.

Now, trying to understand this in terms of blockchain. Each member in the system has a copy of the chain. Not everyone can lose the chain all at once. Thus, by not storing data at one central place, the blockchain eliminates several risks. (Imagine the big brother who has all the money gets robbed. No one will get an ice-cream).

However, there are ways in which blockchain is vulnerable. Like “51% attack”. The kids and ice-cream is not a good example as it does not give you an exact picture but I hope it helps you understand the concept behind it.

The Setup

If you do not have Rust installed, you can follow the steps here.

To generate the project structure, run cargo new blockchain in the terminal. This shall generate a new directory called blockchain with the following files:

|- Cargo.toml
|- src
|__- main.rs

Cargo.toml is the manifest file for Rust. It’s where you keep metadata for your project, as well as dependencies. We will be using a few dependencies in our project. You can learn more about adding dependencies and “crates” here.

Your Cargo.toml file should look similar to this:

Cargo.toml for ‘Blockchain in Rust’

Finally, we will use cargo run command to run our code.

If you are facing any issues setting up the project, you can follow the official Rust-lang page. From here onward, we will only focus on the blockchain part.

Building the Blockchain

An implementation of “Block”(block.rs) will store the transactions, a “proof of work” and a hash from the previously mined “Block”. So, each block in the blockchain will have an index, a timestamp, list of transactions, a proof, and a hash.

Another implementation of Chain(chain.rs) will be responsible for

  • Creating a chain.
  • Adding transactions.
  • Mining a new block.
  • Calculating “proof of work”.
  • Validating the proof.
  • Calculating a hash and a few more methods.

The first block of the chain is called the “Genesis Block”. The pub fn new() in chain.rs takes care of creating this one. The pub fn new_block(...) creates a new block.

Below is the basic structure of our Block & Chain implementations.

Mining

Mining, in the context of blockchain technology, is the process of adding transactions. The fn new_transaction(&mut self, sender: String, recipient: String, amount: u64) -> u64 in chain.rs creates a new transaction and appends it to the list of existing transactions.

Calculating “proof of work (PoW)” andHash”

A proof of work is a piece of data that is difficult (costly, time-consuming) to produce but easy for others to verify. Proof of Work (PoW) confirms transactions and adds new blocks to the chain. With PoW, miners compete against each other to complete transactions on the network and get rewarded.

You can find the `sha` in source code.

Our PoW algorithm was quite simple for the sake of understanding the concept. Find a number p such that, when it is hashed with the previous block’s solution, a new hash with 4 leading 0s is produced.

Bitcoin uses the Hashcash proof of work system.

REST API

Our blockchain fundamentals are now complete. It’s time to deploy it over a network. We’ll be using external libraries such as Rocket for handling the incoming HTTP requests and Reqwest for making HTTP requests.

Create a new file server.rs inside the server module.

server.rs

API Endpoints

# Create new transactions………..…………….………./transactions/new
# Mine new blocks..….…………………………….……/mine
# See the blockchain…….….….….….….……..…...…./chain
# Register new nodes in the network…………………../nodes/register
# See existing nodes in the network…….…..….…….../nodes
# Verify the valid chain……….….…..….….…….……./nodes/resolve

At this point, our server is running on http://localhost:5000 (using cargo run).

See the blockchain

[
{
"index": 1,
"previous_hash": "1",
"proof": 100,
"timestamp": "2021-03-09T07:22:39.503836Z",
"transactions": []
}
]

Add a new Transaction

{
"message": "Transaction added to the block",
"transaction": {
"amount": 5,
"recipient": "4as226eee1514743e92c6cd394edd974f",
"sender": "d4ee26eee15148ee92c6cd394edd974e"
}
}

Mine a block

{
"message": "New block forged",
"proof": 33575,
"previous_hash": "0201d60f8d9227e99b52465254dceaf3487d5f829e9a4c72633b327684aaa308",
"transactions": [
{
"amount": 5,
"recipient": "4as226eee1514743e92c6cd394edd974f",
"sender": "d4ee26eee15148ee92c6cd394edd974e"
},
{
"amount": 1,
"recipient": "792DC096423E4D289CE73510A66751872631800001087BEA56B12",
"sender": "0"
}
],
"index": 2
}

Register a new Node in the Network

{
"message": "New nodes have been added",
"total_nodes": [
"127.0.0.104"
]
}

Verify the Blockchain

{
"chain": [
{
"index": 1,
"previous_hash": "1",
"proof": 100,
"timestamp": "2021-03-09T07:22:39.503836Z",
"transactions": []
},
{
"index": 2,
"previous_hash": "8e3cccb856e49ec262b822e5200786a6af48393799f30e7735b62c906e71528d",
"proof": 33575,
"timestamp": "2021-03-09T07:24:11.504608Z",
"transactions": [
{
"amount": 5,
"recipient": "4as226eee1514743e92c6cd394edd974f",
"sender": "d4ee26eee15148ee92c6cd394edd974e"
}
]
}
],
"message": "Our chain is authoritative"
}

That is all for the REST API implementation. You can download the postman collection here.

Our final project structure shall look something like this.

|- Cargo.toml
|- Cargo.lock
|____src
| |____server
| | |____response.rs
| | |____server.rs
| | |____mod.rs
| |____blockchain
| | |____transaction.rs
| | |____chain.rs
| | |____mod.rs
| | |____block.rs
| |____sha
| | |____mod.rs
| | |____sha.rs
| |____main.rs

The code snippets shown here do not contain the full implementation. The entire source code is available here. I hope, you guys enjoyed reading this article. As always, I look forward to your suggestions and queries.

This article is a Rust-lang port to “Blockchain in Swift”.