Thilan Dissanayaka Web3 Development Nov 06

Blockchain 0x100 – Developing the Core Blockchain Structure

If you are into Web3 development, the term blockchain is not a new thing to you. In the last blog post of this series, I explained most of the core concepts behind how a blockchain works. Learning the theory is a good start. But it only gets you so far. To really understand blockchains, you have to build one yourself.

So guys, in this tutorial, I’m starting a long journey. Yes, as the title says, we’re going to build a blockchain. No Ganache, no external networks. We’re building one completely from scratch, in Java.

Creating the Block Class

We learned a lot of deep concepts in the previous tutorial, but for now, let’s keep things simple. The most basic element of a blockchain is the block. The entire chain is just a sequence of these blocks linked together.

So, what kind of data does a block need to hold?

From our previous discussion, a block needs to store a timestamp, data, nonce, and hashes. Recall the following diagram.

ndkofzyvxllkuijfe7ha.png

Let’s start by creating a Block class in Java. Here’s the structure of it:

public class Block {
    private String data;
    private int nonce;
    private int difficulty;
    private long timestamp;
    private String hash;
    private String prevHash;
}

So what's going on here? Each block needs to store a few key pieces of information.

  • data - holds whatever information we want to record (transactions, messages, anything!)
  • timestamp - tells us when the block was created
  • prevHash - stores the hash of the previous block (this creates the "chain" in blockchain)
  • hash - this block's unique fingerprint
  • nonce and difficulty - work together to make mining possible (we'll explain this soon)

Now properties are done. We need some methods for the class. Please not that I'm not going to show the getters for these properties as the code gets much larger if I do so. When you are implementing this from your own you might need to add them.

We need a way to calculate a block’s unique hash. The hash acts as an immutable fingerprint for the block.

public String calculateHash() { 
    String dataToHash =  data + nonce + difficulty + timestamp + prevHash;
    this.hashString = StringUtil.applySha256(dataToHash);
    return hashString;
}

What’s happening here? We’re taking all the block’s properties, combining them into one long string, and then running it through a SHA-256 hashing algorithm.

If even one character of data changes, the resulting hash will be completely different. This is what gives blockchains their immutability. If anyone tries to modify a block, its hash won’t match anymore, and the entire chain becomes invalid.

Now let's talk about mining. Mining is what makes blockchain secure. It requires computational work to add a new block, which makes it really hard for attackers to mess with the chain. Here's our mining method:

public void mineBlock() {
    String target = "0".repeat(difficulty);
    nonce = 0;
    hashString = calculateHash();

    while (!hashString.startsWith(target)) {
        nonce++;
        hashString = calculateHash();
    }

System.out.println("Block Mined! Hash: " + hashString);
}

What’s happening?

We’re searching for a hash that starts with a certain number of leading zeros. this is our Proof of Work. The number of zeros is determined by the difficulty.

Each time we change the nonce and recalculate the hash until it matches the target. Once it does, the block is considered “mined.”

rikd2hv84opuhvr2nwah.jpg

Block Constructor

Here’s the constructor that ties everything together.

    public Block(String data, int difficulty, String prevHash) {

        this.data = data;
        this.difficulty = difficulty;

        this.prevHash = prevHash;

        this.timestamp = Instant.now().toEpochMilli();

        mineBlock(); // Mine the block
    }

Every time a new block is created, we mine it before it gets added to the chain.

Mining ensures that adding a block requires computational effort, making the blockchain expensive to tamper with — you’d have to re-mine every block after the modified one to fake the chain successfully.

Building the Blockchain Class

Now that our Block class is ready, it’s time to build the Blockchain itself. The system that manages and connects all blocks.

We’ll store all blocks in an ArrayList, starting with a Genesis Block, which is the very first block in the chain.

public class Chain {
    private final int difficulty = 4;
    private final ArrayList<Block> blockchain = new ArrayList<>();

    public Chain() {
        blockchain.add(new Block(0, "Genesis Block", difficulty, "0"));
    }
}

That’s our starting point. The Genesis Block is created manually and doesn’t link to any previous block.

Now, let’s add a method to create and append new blocks to our chain.

vgonz8ekxjyker4jzh2k.png

This method takes new data, links it to the last block using the previous hash, and mines it before adding it to the chain.

    public Block getLatestBlock() {
        return blockchain.get(blockchain.size() - 1);
    }

    public void addBlock(String data) {
        Block newBlock = new Block(blockchain.size(), data, difficulty, getLatestBlock().getHashString());
        blockchain.add(newBlock);
    }

clv1kzdbi7w696ijukpr.png

https://github.com/thil4n/distributed-blockchain/tree/0x100

ALSO READ
Factory Pattern explained simply
Apr 26 Software Architecture

# Factory Pattern Imagine you want to create objects — but you don't want to expose the creation logic to the client and instead ask a factory class to **create objects for you**. That's....

Template Pattern explained simply
Apr 26 Software Architecture

Ever found yourself writing similar logic over and over, only to change a few steps each time? That’s exactly what the **Template Pattern** helps you solve. The **Template Pattern** is a....

Common Web Application Technologies
Feb 11 Application Security

# JWT - JSON Web Tokens JWT is short for JSON Web Token. It is a compact and secure way to send information between two parties – like a client (browser) and a server. We usually use JWTs....

Introduction to Edge Computing
Mar 23 Computing Concepts

Edge computing is a distributed computing paradigm where computation and data storage are performed closer to the location where it is needed. Instead of relying solely on a centralized data center,....

Building a Web3 CLI Tool for the Ballerina Language: From Idea to Reality
Apr 26 WSO2

🚀 Excited to finally share my journey of building a web3 CLI tool for Ballerina! This tool bridges the gap between Ethereum smart contracts and the Ballerina programming language by automatically....

The Stack architecture explained
Mar 23 Application Security

The stack is an important concept in computer science. If you are planning to learn reverse engineering, malware analyzing, exploitation, etc., this concept is a must to learn. After learning about....