Building a Simple Cryptocurrency Blockchain in Node.js

Introduction

In this blog post, we’re going to dive into the fascinating world of blockchain technology. We’ll build a simple cryptocurrency blockchain using Node.js, a popular JavaScript runtime built on Chrome’s V8 JavaScript engine. By the end of this guide, you’ll have a working prototype of a basic blockchain that can create transactions and mine new blocks.

Prerequisites

Before we begin, you need to have a basic understanding of JavaScript and Node.js. You should also have Node.js and npm (Node Package Manager) installed on your computer.

node blockchain

Understanding Blockchain

What is a Blockchain?

A blockchain is a growing list of records, called blocks, that are linked using cryptography. Each block contains a cryptographic hash of the previous block, a timestamp, and transaction data.

Why Use Node.js for Blockchain?

Node.js is an excellent choice for implementing a blockchain due to its asynchronous nature and efficiency in handling I/O operations, which are crucial in a blockchain’s operation.

Setting Up Our Project

First, let’s create a new directory for our project and initialize a new Node.js project:

mkdir cryptocurrency
cd cryptocurrency
npm init -y

Next, we need to install crypto-js, a library we’ll use for hashing blocks:

npm install crypto-js

Creating a Block

Let’s start by creating a Block class. In a new file called block.js, write the following code:

const SHA256 = require('crypto-js/sha256');

class Block {
    constructor(index, timestamp, data, previousHash = '') {
        this.index = index;
        this.timestamp = timestamp;
        this.data = data;
        this.previousHash = previousHash;
        this.hash = this.calculateHash();
    }

    calculateHash() {
        return SHA256(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)).toString();
    }
}

module.exports = Block;<code>
</code>
<code>
</code>

In this code, we’ve defined a Block class with a constructor that accepts index, timestamp, data, and the previous block’s hash. The calculateHash method uses the SHA-256 algorithm from the crypto-js library to generate a unique hash for each block.

Creating the Blockchain

Next, we’ll create a Blockchain class to manage the chain of blocks. In a new file called blockchain.js, write the following code:

const Block = require('./block');

class Blockchain {
    constructor() {
        this.chain = [this.createGenesisBlock()];
    }

    createGenesisBlock() {
        return new Block(0, "01/01/2020", "Genesis block", "0");
    }

    getLatestBlock() {
        return this.chain[this.chain.length - 1];
    }

    addBlock(newBlock) {
        newBlock.previousHash = this.getLatestBlock().hash;
        newBlock.hash = newBlock.calculateHash();
        this.chain.push(newBlock);
    }
}

module.exports = Blockchain;

In this code, we’ve defined a Blockchain class with methods to create the genesis block, get the latest block, and add a new block to the chain.

This is a good start, but there’s more to creating a blockchain. In the next part, we’ll add validation methods to our Blockchain class, create a transaction class, and add a proof-of-work mechanism to secure our blockchain.

Validating the Blockchain

A crucial aspect of blockchains is ensuring the integrity of the data. Let’s add a method to our Blockchain class to validate the chain:

<code>validateChain() {
    for(let i = 1; i < this.chain.length; i++) {
        const currentBlock = this.chain[i];
        const previousBlock = this.chain[i - 1];

        if(currentBlock.hash !== currentBlock.calculateHash()) {
            return false;
        }

        if(currentBlock.previousHash !== previousBlock.hash) {
            return false;
        }
    }

    return true;
}
</code>

This method checks each block to ensure that the hash is valid and the previousHash property correctly points to the hash of the previous block.

Creating a Transaction Class

In a real-world blockchain, blocks contain transactions, not just arbitrary data. Let’s create a Transaction class:

<code>class Transaction {
    constructor(fromAddress, toAddress, amount) {
        this.fromAddress = fromAddress;
        this.toAddress = toAddress;
        this.amount = amount;
    }
}

module.exports = Transaction;
</code>

Each transaction has a fromAddress and toAddress, representing the sender and recipient of the transaction, and an amount, representing the amount of cryptocurrency being transferred.

Adding Transactions to Blocks

We need to update our Block class to contain a list of transactions instead of a data property. We also need to update the calculateHash method to include these transactions in the hash calculation:

<code>class Block {
    constructor(timestamp, transactions, previousHash = '') {
        this.timestamp = timestamp;
        this.transactions = transactions;
        this.previousHash = previousHash;
        this.hash = this.calculateHash();
    }

    calculateHash() {
        return SHA256(this.previousHash + this.timestamp + JSON.stringify(this.transactions)).toString();
    }
}
</code>

We also need to update our Blockchain class to create new blocks from pending transactions instead of manually creating blocks:

<code>class Blockchain {
    constructor() {
        this.chain = [this.createGenesisBlock()];
        this.difficulty = 2;
        this.pendingTransactions = [];
        this.miningReward = 100;
    }

    createGenesisBlock() {
        return new Block("01/01/2020", "Genesis block", "0");
    }

    getLatestBlock() {
        return this.chain[this.chain.length - 1];
    }

    minePendingTransactions(miningRewardAddress) {
        let block = new Block(Date.now(), this.pendingTransactions);
        block.mineBlock(this.difficulty);

        console.log('Block successfully mined!');
        this.chain.push(block);

        this.pendingTransactions = [
            new Transaction(null, miningRewardAddress, this.miningReward)
        ];
    }

    createTransaction(transaction) {
        this.pendingTransactions.push(transaction);
    }

    getBalanceOfAddress(address) {
        let balance = 0;

        for(const block of this.chain) {
            for(const trans of block.transactions) {
                if(trans.fromAddress === address) {
                    balance -= trans.amount;
                }

                if(trans.toAddress === address) {
                    balance += trans.amount;
                }
            }
        }

        return balance;
    }
}
</code>

Now, our blockchain can accept new transactions, add them to blocks, and reward miners for their work.

Conclusion

Congratulations, you’ve built a simple cryptocurrency blockchain using Node.js! While this is a basic implementation, it provides a solid foundation for understanding how blockchains work. You can expand upon this by adding more features, such as transaction signatures, peer-to-peer networking, and more sophisticated consensus algorithms.

Remember, blockchain technology is still evolving, and there’s always more to learn. Keep experimenting, keep coding, and most importantly, have fun!