Select Page

How to build a blockchain with Rust?

build-blockchain-with-Rust

Rust is the perfect language for blockchains, where dependability and performance are crucial. It is user-friendly, quick, dependable and memory-efficient. Due to the advantages of blockchain technology and the rising demand for it, this article attempts to guide you step-by-step on how to build a blockchain with Rust. The Rust blockchain implemented in this article is the most generic and basic.

What is Rust?

Rust is a dynamically compiled language with a comprehensive type system and ownership concept that is incredibly quick and memory-efficient. It enables developers to debug at compile time and can be used to power performance-critical services while ensuring memory and thread-safety. Additionally, Rust has excellent documentation, an easy-to-use compiler, and premium tools like integrated package managers and multi-editors with capabilities like type inspection and auto-completion.

Rust stops all crashes, and it’s fascinating because it comes preconfigured as being secure, just like JavaScript, Ruby, and Python. Because we cannot write incorrect parallel code and you can never see a flaw in Rust, this is far more powerful than C/C++. It represents many different programming paradigms quickly and accurately.

How to build blockchain with Rust?

Before proceeding with the steps of blockchain development, ensure you have installed Rust in your system.

Implement the block struct

First create source files, namely, “main.rs” and “block.rs”.

In the block.rs file, define the following properties we need within the block struct.

pub struct Block {   pub index: u32,    pub timestamp: u128,    pub hash: Hash,    pub prev_block_hash: Hash,    pub nonce: u64,    pub transactions: Vec,    pub difficulty: u128,}

Implement block constructor and debug

Write the following codes to implement block constructor.

impl Block {   pub fn new (index: u32, timestamp: u128, prev_block_hash: Hash,  transactions: Vec, difficulty: u128) -> Self {          Block {            index,            timestamp,            hash: vec![0; 32],            prev_block_hash,            nonce: 0,            transactions,            difficulty,        }    }

Next, implement the debug formatter for the block using the following codes:

impl Debug for Block {    fn fmt (&self, f: &mut Formatter) -> fmt::Result {        write!(f, "Block[{}]: {} at: {} with: {} nonce: {}",           &self.index,            &hex::encode(&self.hash),            &self.timestamp,            &self.transactions.len(),            &self.nonce,        )    }}

Now, go to the “main.rs” file and write the following codes:

fn main () {    let difficulty = 0x000fffffffffffffffffffffffffffff;    let mut genesis_block = Block::new(0, now(), vec![0; 32], vec![        Transaction {            inputs: vec![ ],            outputs: vec![                transaction::Output {                   to_addr: "Alice".to_owned(),                    value: 50,                },                transaction::Output {                    to_addr: "Bob".to_owned(),                    value: 7,                },           ],        },    ], difficulty);

Create a trait named hashable in a new file, hashable.rs and run the following codes:

use super::*;pub trait Hashable {      fn bytes (&self) -> Vec;  fn hash (&self) -> Hash {            crypto_hash::digest(crypto_hash::Algorithm::SHA256, &self.bytes())      }}

Implement Hashable on block

Now, let us implement the bytes function on the already created block struct by writing a new “impl” implementation block.

impl Hashable for Block {      fn bytes (&self) -> Vec {            let mut bytes = vec![];        bytes.extend(&u32_bytes(&self.index));                bytes.extend(&u128_bytes(&self.timestamp));                bytes.extend(&self.prev_block_hash);                bytes.extend(&u64_bytes(&self.nonce));                bytes.extend(                      self.transactions                            .iter()                            .flat_map(|transaction| transaction.bytes())                .collect::<Vec>()                );                bytes.extend(&u128_bytes(&self.difficulty));        bytes        }}

Create a blockchain struct

Create a new file and name it “blockchain.rs”, within which you have to create your new blockchain struct.

pub struct Blockchain {

Now, add its field, which is a vector of blocks.

pub blocks: Vec,

Mining

Go to the file, “main.rs” to mine the genesis block and a set of blocks up to, for example, 10. Make sure that each block has its own hash along with the previous hash. Write the following codes:

fn main () {      let difficulty = 0x000fffffffffffffffffffffffffffff;  let mut block = Block::new(0, 0, vec![0; 32], 0, "Genesis block!".to_owned(), difficulty);  block.mine();  println!("Mined genesis block {:?}", &block);  let mut last_hash = block.hash.clone();  let mut blockchain = Blockchain{    block: vec![block],  };  for i in 1..=10 {  let mut block = Block::new(i, 0, last_hash, 0, "Another block!".to_owned(), difficulty);   block.mine();  println!("Mined block {:?}", &block);  last_hash = block.hash.clone();  blockchain.blocks.push(block);

Run the above codes and a blockchain struct is created which has 10 blocks.

Blockchain verification

Add the following function to the blockchain struct within blockchain.rs to verify the blockchain.

impl Blockchain {    pub fn new () -> Self {        Blockchain {            blocks: vec![],            unspent_outputs: HashSet::new(),        }    }pub fn update_with_block (&mut self, block: Block) -> Result<(), BlockValidationErr> {    let i = self.blocks.len();    if block.index != i as u32 {        return Err(BlockValidationErr::MismatchedIndex);    } else if !block::check_difficulty(&block.hash(), block.difficulty) {        return Err(BlockValidationErr::InvalidHash);    } else if i != 0 {        // Not genesis block        let prev_block = &self.blocks[i - 1];        if block.timestamp <= prev_block.timestamp {            return Err(BlockValidationErr::AchronologicalTimestamp);        } else if block.prev_block_hash != prev_block.hash {            return Err(BlockValidationErr::MismatchedPreviousHash);        }    } else {        // Genesis block        if block.prev_block_hash != vec![0; 32] {            return Err(BlockValidationErr::InvalidGenesisBlockFormat);        }    }

Why use Rust for blockchain development?

Since the emergence of blockchain as a decentralized digital ledger, its use cases and real-life applications have been on the rise. From supply chains to digital voting systems and asset management, blockchain is a technology that can be integrated into various aspects of our life. The potential it holds is immense, thanks to which many businesses are adopting blockchain-based applications and software to make themselves ready for a web3-compatible future. As a result, newer blockchain protocols are also emerging.

Rust provides free abstractions and, by default, adheres to best practice development and design principles. It is interoperable with C and C++ and is a user-friendly programming language. Rust is, hence, incredibly dependable, memory-efficient, and quick. Additionally, Rust lacks a trash collector. Therefore there won’t be any runtime indeterminism brought on by the language.

Due to these qualities, Rust is the perfect language for blockchains, where dependability and performance are crucial.

If you want to develop a Rust-based custom blockchain for your business, consult our team of blockchain experts to kickstart your blockchain development journey.

Webinar Details

Author’s Bio

Akash Takyar
Akash Takyar
CEO LeewayHertz
Akash Takyar is the founder and CEO at LeewayHertz. The experience of building over 100+ platforms for startups and enterprises allows Akash to rapidly architect and design solutions that are scalable and beautiful.
Akash's ability to build enterprise-grade technology solutions has attracted over 30 Fortune 500 companies, including Siemens, 3M, P&G and Hershey’s. Akash is an early adopter of new technology, a passionate technology enthusiast, and an investor in AI and IoT startups.

Start a conversation by filling the form

Once you let us know your requirement, our technical expert will schedule a call and discuss your idea in detail post sign of an NDA.

All information will be kept confidential.

 

Insights