Implementation of Blockchain in Java


Blockchain is the foundational technology behind cryptocurrencies like Bitcoin and Ethereum, but its potential extends far beyond digital currency. From supply chain management to secure voting systems, blockchain is revolutionizing various industries. In this blog post, we’ll explore how to implement a basic blockchain in Java, step by step. This guide will cover the essential concepts, including creating blocks, the chain, and a simple consensus mechanism.


Introduction to Blockchain

A blockchain is a distributed, decentralized ledger that records transactions across multiple computers so that the recorded transactions are permanent and immutable. Each block in a blockchain contains a set of transactions and is linked to the previous block, forming a chain.

Key Concepts:

  • Block: A block contains a list of transactions and some additional metadata like a timestamp, previous block hash, and a nonce (for Proof of Work).
  • Chain: The chain is a sequence of blocks, with each block cryptographically linked to the previous one using a hash.
  • Hashing: Hashing is used to uniquely identify each block and ensure its integrity. If any data within a block changes, the hash changes as well.

What We Will Build

In this tutorial, we’ll implement a basic blockchain that:

  • Creates blocks containing transaction data.
  • Links blocks using hashes to form a chain.
  • Verifies the integrity of the blockchain by ensuring that the hash of the current block matches the hash of the previous block.

Step-by-Step Guide to Implementing Blockchain in Java

Step 1: Set Up Your Java Project

Start by setting up your Java development environment. You can use an IDE like IntelliJ IDEA or Eclipse, or simply use Maven or Gradle for dependency management.

Step 2: Create the Block Class

A block in a blockchain contains several pieces of information: a timestamp, a hash of the current block, the hash of the previous block, and the data (transactions).

Let’s create the Block class:

import java.util.Date;

public class Block {
    private String previousHash;
    private String hash;
    private String data;  // Transaction or any data
    private long timeStamp;

    // Constructor
    public Block(String data, String previousHash) {
        this.previousHash = previousHash;
        this.data = data;
        this.timeStamp = new Date().getTime();
        this.hash = calculateHash(); // Calculating the hash of this block
    }

    // Method to calculate the hash of the block using previous hash, timestamp, and data
    public String calculateHash() {
        String calculatedhash = StringUtil.applySha256(previousHash + Long.toString(timeStamp) + data);
        return calculatedhash;
    }

    // Getter methods for block details
    public String getHash() {
        return hash;
    }

    public String getPreviousHash() {
        return previousHash;
    }

    public String getData() {
        return data;
    }

    public long getTimeStamp() {
        return timeStamp;
    }
}

Explanation:

  • previousHash: The hash of the previous block.
  • hash: The hash of the current block.
  • data: The content of the block (for simplicity, this is just a string, but you could make it more complex for real-world applications).
  • timeStamp: The time when the block was created.
  • calculateHash(): This method creates a hash using the SHA-256 algorithm by combining the previous hash, timestamp, and data.

Step 3: Create the Blockchain Class

Now, let's create the Blockchain class. This class will contain a list of blocks, starting with a "genesis block" (the first block), and then any additional blocks added to the chain.

import java.util.ArrayList;

public class Blockchain {
    private ArrayList<Block> blockchain;

    // Constructor
    public Blockchain() {
        blockchain = new ArrayList<>();
        // Create the first block (genesis block)
        blockchain.add(createGenesisBlock());
    }

    // Create the first block of the blockchain
    private Block createGenesisBlock() {
        return new Block("Genesis Block", "0");
    }

    // Add a block to the blockchain
    public void addBlock(String data) {
        Block lastBlock = blockchain.get(blockchain.size() - 1);
        blockchain.add(new Block(data, lastBlock.getHash()));
    }

    // Verify the blockchain (check if the chain is valid)
    public boolean isBlockchainValid() {
        Block currentBlock;
        Block previousBlock;

        // Loop through the blockchain to check for integrity
        for (int i = 1; i < blockchain.size(); i++) {
            currentBlock = blockchain.get(i);
            previousBlock = blockchain.get(i - 1);

            // Compare the current block's hash with the calculated hash
            if (!currentBlock.getHash().equals(currentBlock.calculateHash())) {
                System.out.println("Current Hashes are not equal");
                return false;
            }

            // Compare previous block's hash with the current block's previousHash
            if (!previousBlock.getHash().equals(currentBlock.getPreviousHash())) {
                System.out.println("Previous Hashes are not equal");
                return false;
            }
        }
        return true;
    }

    // Print out the blockchain details
    public void printBlockchain() {
        for (Block block : blockchain) {
            System.out.println("Block Data: " + block.getData());
            System.out.println("Block Hash: " + block.getHash());
            System.out.println("Previous Hash: " + block.getPreviousHash());
            System.out.println("Timestamp: " + block.getTimeStamp());
            System.out.println("===========================================");
        }
    }
}

Explanation:

  • The constructor initializes the blockchain and creates the genesis block.
  • The addBlock method adds a new block to the chain using the hash of the last block.
  • The isBlockchainValid method verifies that each block’s hash matches the data it contains and that the previous hash matches the previous block’s hash. This ensures the integrity of the blockchain.
  • The printBlockchain method outputs the details of each block.

Step 4: Utility Class for Hashing

We will need a utility class to generate SHA-256 hashes. Create a StringUtil class with a method for applying SHA-256:

import java.security.MessageDigest;

public class StringUtil {
    // Apply SHA-256 to a string and return the resulting hash
    public static String applySha256(String input) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(input.getBytes("UTF-8"));
            StringBuilder hexString = new StringBuilder();

            // Convert byte array to hexadecimal format
            for (byte b : hash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }

            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Explanation:

  • This class provides a method to apply the SHA-256 hashing algorithm to a string and return the resulting hash.

Step 5: Testing the Blockchain

Now that we have the necessary classes, we can test our blockchain implementation. Here's how you can create a simple application to test the blockchain:

public class BlockchainDemo {
    public static void main(String[] args) {
        Blockchain myBlockchain = new Blockchain();
        
        System.out.println("Mining block 1...");
        myBlockchain.addBlock("Block #1: Data for Block 1");
        
        System.out.println("Mining block 2...");
        myBlockchain.addBlock("Block #2: Data for Block 2");
        
        System.out.println("Mining block 3...");
        myBlockchain.addBlock("Block #3: Data for Block 3");
        
        // Print the blockchain
        myBlockchain.printBlockchain();
        
        // Verify the blockchain
        System.out.println("Blockchain is valid: " + myBlockchain.isBlockchainValid());
    }
}

Step 6: Running the Code

When you run the code, it will create a blockchain, mine three blocks, and verify if the blockchain is valid.

Expected Output:

Mining block 1...
Mining block 2...
Mining block 3...
Block Data: Genesis Block
Block Hash: 63d0f8a9c7c6f94d8f2a0f244720d1b3c69c6bfc1d8e5c95b3762e1e421dba6d
Previous Hash: 0
Timestamp: 1632021948000
===========================================
Block Data: Block #1: Data for Block 1
Block Hash: 56b89b3e9d9ef855a4d68b85c799d63542c6ca8b4b94f42499a6e64cc6c4421b
Previous Hash: 63d0f8a9c7c6f94d8f2a0f244720d1b3c69c6bfc1d8e5c95b3762e1e421dba6d
Timestamp: 1632021951000
===========================================
Block Data: Block #2: Data for Block 2
Block Hash: 5bdaaf17354e379245064a38b938cf33fcf0324c9c778fb07ffb387ba5863131
Previous Hash: 56b89b3e9d9ef855a4d68b85c799d63542c6ca8b4b94f42499a6e64cc6c4421b
Timestamp: 1632021953000
===========================================
Block Data: Block #3: Data for Block 3
Block Hash: 8f1fc973cfa7500ad6ad5355d43737b49fd7a70fe4aeeaeb2d33cdcfb8f03a72
Previous Hash: 5bdaaf17354e379245064a38b938cf33fcf0324c9c778fb07ffb387ba5863131
Timestamp: 1632021955000
===========================================
Blockchain is valid: true