Creating Simple Cryptocurrency Blockchain Using JavaScript and Node.js

In this article, we will create a simple Cryptocurrency Blockchain Using JavaScript and Node.js. Before moving further you have to make sure you have installed vs code and node.js in your system.

What is Blockchain?

Blockchain, at its foundation, is a distributed digital ledger that holds data of any form. The blockchains can keep track of bitcoin transactionsNFT ownership, and DeFi smart contracts.

While any traditional database may hold this type of data, blockchains are special in that it is completely decentralized. Rather than being maintained in a single location by a centralized administrator (as in an Excel spreadsheet or a bank database), several identical copies of a blockchain database are stored on several computers distributed over a network. These individual computers are known as nodes.

Directory Structure for Cryptocurrency Blockchain

  1. We need to create a blockchain directory. Inside this, we are doing all of our programs.
  2. Now in the next step, We are going to create a sub folder in this directory. You guys can give any name to this sub folder.
  3. Then, We will create two files in this sub folder.
    • blockchain. js
    • test.js
  4. The directory structure will look like this.
directory structure for Cryptocurrency Blockchain

Next, we have to run one command from the terminal and make it an NPM project.

init command

Note: You should be in the same directory and then enter this command “npm init” without quotation mark.

We will get some options after this command you just need to press enter to set up your project and it will create a package.json file. And your Project directory structure looks like this.

package.json for Cryptocurrency Blockchain

Building Cryptocurrency Blockchain DataStructure

We are going to make our blockchain data structure by using a Constructor Function in JavaScript. We are going to give our blockchain certain functionalities, such as the ability to create new blocks, the ability to create transactions, the ability to hash data and hash blocks, the ability to do proof of work, and many other functionalities.

There are two important concepts that we should understand first before moving forward.

  1. JS Constructor Function: A constructor function is simply a function that creates an object and allows you to create multiple objects or instances from a constructor function.
  2. Protoype Object: You can also add properties and methods to a constructor function using a prototype.

Getting Started with Cryptocurrency Blockchain

Creating Constructor

First, we need to create a constructor for our blockchain which contains two empty arrays.

// In the Blockchain.js
function Blockchain() {
    this.chain = [];   //stores our blocks
    this.pendingTransactions = []; //this contains our pending transaction before create a new block

}

Creating New Block

Now, after introducing blockchain technology let’s see how we can apply the concepts in creating a block. Blocks are what interlink with each other to form a blockchain.

Blockchain.prototype.createNewBlock = function(nonce, prevBlockHash, hash){
    const newBlock = {
        index : this.chain.length + 1,
        timestamp : Date.now(),
        transactions : this.pendingTransactions,
        nonce : nonce,
        prevBlockHash : prevBlockHash,
        hash : hash
    };

    this.pendingTransactions = [];
    this.chain.push(newBlock);

    return newBlock;
}

Before testing the above program export the blockchain.js file to test.js.

// In the blockchain.js file
module.exports = Blockchain;
// In the test.js file
const Blockchain = require("./Blockchain");

Creating New Transaction Object

Before creating a new transaction object we need to create another object which is “getLastBlock“. Because we need the “hash” of the last block for secure transactions.

Blockchain.prototype.getLastBlock = function() {
    return this.chain[this.chain.length - 1];
}

Now Let’s create our new transaction object.

Blockchain.prototype.createNewTransaction = function(amount, sender, recipient) {
    const NewTransaction = {
        amount : amount,
        sender : sender,
        recipient : recipient
    };

    this.pendingTransactions.push(NewTransaction);

    return this.getLastBlock()['index'] +1;
}

Adding SHA256 Hashing Algorithm

The hashing algorithm is used to generate a unique string for different users to secure their blockchain and their transactions.

Use the below command in your terminal to install the sha256 hashing algorithm.

npm i sha256 --save

After installing this your directory structure will be looks like this.

directory

Now import the sha256 hashing algorithm in your blockchain.js file.

const sha256 = require('sha256');

Now we create a hash block method that creates different hashes for different blocks.

Blockchain.prototype.hashBlock = function(prevBlockHash, currentBlockData, nonce) {
    const dataString  = prevBlockHash + nonce.toString() + JSON.stringify(currentBlockData);
    const hash = sha256(dataString);

    return hash;
}

Adding Proof of Work

Proof of work is the concept applied to increase the difficulty entailed in mining or adding new blocks to the blockchain. Now let’s create a method for proof of work

Blockchain.prototype.proofOfWork = function(prevBlockHash, currentBlockData) {
    let nonce = 0;
    let hash = this.hashBlock(prevBlockHash, currentBlockData, nonce);

    while (hash.substring(0,4) !== '0000') {
        nonce++;
        hash = this.hashBlock(prevBlockHash, currentBlockData, nonce);
    }

    return nonce;
}

Creating Genesis Block

In a blockchain, the genesis block refers to the first-ever block created on the network. Whenever a block is integrated with the rest of the chain, it should reference the preceding block.

Conversely, in the case of this initial block, it does not have any preceding block to point to. Therefore, a genesis block is usually hardcoded into the blockchain. This way, subsequent blocks can be created on it. It usually has an index of 0.

Put below code in Blockchain constructor function after Pending transaction array.

this.createNewBlock(100, '0', '0');

Now we have created our blockchain it’s time to test it. Before testing, we need to install express.js to access the blockchain data structure through a local server.

Accessing Blockchain Through Local Server

As earlier mentioned to access the blockchain data structure through a local server we need to install express.js. Run the below command in your terminal

npm install express

Now create another js file in your directory which runs on our local server say api.js. And put the following code in this.

const express = require('express')
// respond with "hello world" when a GET request is made to the homepage
app.get('/', (req, res) => {
  res.send("Hello World")
})
app.listen(3000)

Now test this server by typing npm start in your terminal.

After all this setup we need to make an interface for our blockchain so create an HTML file in your directory say index.html. And put the following code in your HTML file.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Wallet</title>
</head>
<body>
    <p>This is Simple Test Wallet</p>
    <form action="/wallet" method="POST">
    <div>
        <label>Amount:</label>
        <input type="number", class="form-control", placeholder="Amount to Send", name="amount", required>
    </div>
    <div>
        <label>Recipient Address:</label>
        <input type="text", class="form-control", name="senderAddress", required>
    </div>
    <div>
        <label>Sender Address:</label>
        <input type="text", class="form-control", name="recipientAddress">
    </div>
    <button type="submit", class="button">Submit</button>
</form>
</body>
</html>

After this, your directory and the local interface look like this

directory Cryptocurrency Blockchain
interface Cryptocurrency Blockchain

Wrapping up All the Codes for Cryptocurrency Blockchain

Blockchain.js

const sha256 = require('sha256');

function Blockchain() {
    this.chain = [];   //stores our blocks
    this.pendingTransactions = []; //this contains our pending transaction before create a new block
    this.createNewBlock(100, '0', '0');
}

Blockchain.prototype.createNewBlock = function(nonce, prevBlockHash, hash){
    const newBlock = {
        index : this.chain.length + 1,
        timestamp : Date.now(),
        transactions : this.pendingTransactions,
        nonce : nonce,
        prevBlockHash : prevBlockHash,
        hash : hash
    };

    this.pendingTransactions = [];
    this.chain.push(newBlock);

    return newBlock;
}

Blockchain.prototype.getLastBlock = function() {
    return this.chain[this.chain.length - 1];
}

Blockchain.prototype.createNewTransaction = function(amount, sender, recipient) {
    const NewTransaction = {
        amount : amount,
        sender : sender,
        recipient : recipient
    };

    this.pendingTransactions.push(NewTransaction);

    return this.getLastBlock()['index'] +1;
}

Blockchain.prototype.hashBlock = function(prevBlockHash, currentBlockData, nonce) {
    const dataString  = prevBlockHash + nonce.toString() + JSON.stringify(currentBlockData);
    const hash = sha256(dataString);

    return hash;
}

Blockchain.prototype.proofOfWork = function(prevBlockHash, currentBlockData) {
    let nonce = 0;
    let hash = this.hashBlock(prevBlockHash, currentBlockData, nonce);

    while (hash.substring(0,4) !== '0000') {
        nonce++;
        hash = this.hashBlock(prevBlockHash, currentBlockData, nonce);
    }

    return nonce;
}

module.exports = Blockchain;

test.js

const Blockchain = require("./Blockchain");

const bitcoin = new Blockchain();

const prevBlockHash = "hello";
const currentBlockData = [
    {
        amount : 10,
        sender : "ranjeer",
        recipient : "waqar"
    }
]

console.log(bitcoin.proofOfWork(prevBlockHash, currentBlockData));

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Wallet</title>
</head>
<body>
    <p>This is Simple Test Wallet</p>
    <form action="/wallet" method="POST">
    <div>
        <label>Amount:</label>
        <input type="number", class="form-control", placeholder="Amount to Send", name="amount", required>
    </div>
    <div>
        <label>Recipient Address:</label>
        <input type="text", class="form-control", name="senderAddress", required>
    </div>
    <div>
        <label>Sender Address:</label>
        <input type="text", class="form-control", name="recipientAddress">
    </div>
    <button type="submit", class="button">Submit</button>
</form>
</body>
</html>

api.js

const express = require('express')
const app = express()
const bodyParser = require('body-parser');
const Blockchain = require("./Blockchain");
const {v4: uuidv4} = require('uuid');
const bitcoin = new Blockchain();

const port = process.argv[2];

const nodeAddress = uuidv4().split("-").join('');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));

// respond with "hello world" when a GET request is made to the homepage
app.get('/blockchain', (req, res) => {
  res.send(bitcoin)
})

// app.post('/transaction', (req, res) => {
//   const blockIndex = bitcoin.createNewTransaction(req.body.amount, req.body.sender, req.body.recipient);
//   res.json({note: `this transaction will be added in block ${blockIndex}`})
// })

app.get('/mine', (req, res) => {
  const lastBlock = bitcoin.getLastBlock();
  const prevBlockHash = lastBlock['hash'];
  const currentBlockData = {
    transaction : bitcoin.pendingTransactions,
    index : lastBlock['index'] + 1
  }
  const nonce = bitcoin.proofOfWork(prevBlockHash, currentBlockData);
  const blockHash = bitcoin.hashBlock(prevBlockHash, currentBlockData, nonce);

  const newBlock = bitcoin.createNewBlock(nonce, prevBlockHash, blockHash);

  bitcoin.createNewTransaction(100, '0', nodeAddress);

  res.json({
    note : "New block mined Successfully",
    block : newBlock
  })
})

app.get('/wallet', (req, res) => {
  res.sendFile(__dirname + "/index.html");
})

app.post('/wallet', (req, res) => {
  const blockIndex = bitcoin.createNewTransaction(req.body.amount, req.body.senderAddress, req.body.recipientAddress);
  res.json({note: `this transaction will be added in block ${blockIndex}`})
})


app.listen(port, function(){
  console.log(`Server is Running on ${port}`);
});

Some settings in package.json file

{
  "name": "blockchain",
  "version": "1.0.0",
  "description": "Learning Purpose",
  "main": "api.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "node_1": "nodemon --watch dev -e js dev/api.js 3001",
    "node_2": "nodemon --watch dev -e js dev/api.js 3002",
    "node_3": "nodemon --watch dev -e js dev/api.js 3003",
    "node_4": "nodemon --watch dev -e js dev/api.js 3004",
    "node_5": "nodemon --watch dev -e js dev/api.js 3005"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.20.0",
    "express": "^4.18.1",
    "nodemon": "^2.0.16",
    "sha256": "^0.2.0",
    "uuid": "^8.3.2"
  }
}

Outputs:

localserver:3000/wallet:

wallet for Cryptocurrency Blockchain

After Submitting:

After Submitting

localserver:3000/blockchain:

blockchain

localserver:3000/mine:

mine

Conclusion

That’s all for this article, if you have any confusion contact us through our website or email us at [email protected] or by using LinkedIn

Suggested Articles:

  1. What is Blockchain and How Does it Work?

Leave a Comment