How to create your blockchain with JavaScript

How to create your blockchain with JavaScript

A blockchain is essentially a network of computer systems that duplicate and distribute a digital ledger of transactions. Every new transaction on the blockchain contributes a record of that transaction to every participant's ledger, and each block in the chain contains many transactions.

You will learn how blockchain technology functions by following along as we create a fully functional blockchain from scratch in this article using the JavaScript programming language.

So let’s dive in

What is Blockchain?

Imagine living in a society where you can send money to someone without the use of a bank in seconds as opposed to days and without having to pay expensive bank fees, or where you control your money completely and store your money in an online wallet that is not connected to a bank, making you your bank. You don't need a bank's consent to move or access it, and you never have to be concerned about a third party seizing it or a government's economic policies influencing it.

Blockchain technology makes cryptocurrencies (digital currencies secured by cryptography) like Bitcoin work just like the internet makes email possible.

The blockchain is an immutable (unchangeable, meaning a transaction or file recorded cannot be changed) distributed digital ledger (digital record of transactions or data stored in multiple places on a computer network) with many use cases beyond cryptocurrencies.

Every transaction in this blockchain ledger is validated and protected against fraud by the owner's digital signature, which also serves to authenticate the transaction. As a result, the data in the digital ledger is quite safe.

Why is JavaScript used in blockchain?

JavaScript is a programming language that was used initially by Netscape Communications in 1995 to provide enhancements for web pages. The popularity of JavaScript has increased over recent years as more developers have learned how it can be utilized across numerous projects.

Because of its adaptability and simplicity for beginners, the language is recognized as one of the most useful programming languages. Java Programming language was influenced by JavaScript.

You can now explore the blockchain as a JavaScript developer. It's possible to build the applications you want without having to learn a new programming language using a straightforward method. The distinctions between web2 applications and blockchain applications are numerous and distinct.

Building your Blockchain cryptocurrency using JavaScript?

We'll create a decentralized blockchain network to store our whole blockchain.

Our blockchain will be able to perform

  1. A proof-of-work

  2. Create new blocks through mining process

  3. Create new Immutable transactions

  4. Validate the blockchain and all block data

  5. Retrieve Address |Transaction | Block data

Requirements

You can always refer to the GitHub repository if you want to have a look at the code.

Getting started

Let’s get started by creating a Node project. Navigate to a safe directory and enter the following command to create a new project:

Create a directory named Blockchain and cd into the project by running the following commands

cd Blockchain

Let's create another folder inside the Blockchain directory with two files

mkdir dev
cd dev
touch blockchain.js test.js
dir

Now we have two files blockchain.js andtest.js

Now, let's move back to the Blockchain directory and run

cd ..
npm init

Press enter throughout the installation to set up your project.

And it should generate a package.json file for you. If the file is created, then the project is created. package.json will contain

{
  "name": "blockchain",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "sha256": "^0.2.0"
  }
}

Let's create a constructor function and newBlock inside our blockchain.js and exporting our blockchain.js

function Blockchain(){
    this.chain = [];
    this.pendingTransactions = [];
}


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

    return newBlock
}

module.exports = Blockchain;

Let's test our function inside test.js by importing our blockchain.js and create an instance of our blockchain constructor function with random numbers.

const Blockchain = require ('./Blockchain');
const bitcoin = new Blockchain();

bitcoin.createNewBlock(23654, "09OIWDDYFGFSJJN", "264736S7SHHGAJJSH")
bitcoin.createNewBlock(23654, "34SDD67SUHASJJN", "023436S7SHHGAJJSH")
bitcoin.createNewBlock(23654, "376FGSDDYFGSJJN", "233363S7SHHGAJJSH")

console.log(bitcoin);

run this command to test your project to display our entire block

 node dev/test.js
Blockchain {
  chain: [
    {
      index: 1,
      timestamp: 1676328677814,
      transactions: [],
      nonce: 23654,
      hash: '264736S7SHHGAJJSH',
      previousBlockHash: '09OIWDDYFGFSJJN'
    },
    {
      index: 2,
      timestamp: 1676328677814,
      transactions: [],
      nonce: 23654,
      hash: '023436S7SHHGAJJSH',
      previousBlockHash: '34SDD67SUHASJJN'
    },
    {
      index: 3,
      timestamp: 1676328677814,
      transactions: [],
      nonce: 23654,
      hash: '233363S7SHHGAJJSH',
      previousBlockHash: '376FGSDDYFGSJJN'
    }
  ],
  pendingTransactions: []

Let's add getLastBlock to our blockchain.js

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

    return newBlock
}

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

module.exports = Blockchain;

Let's add createNewTransaction method to our blockchain.js and push it to our newTransaction

function Blockchain(){
    this.chain = [];
    this.pendingTransactions = [];
}


Blockchain.prototype.createNewBlock = function(nonce, previousBlockHash, hash) {
    const newBlock = {
        index: this.chain.length + 1,
        timestamp: Date.now(),
        transactions: this.pendingTransactions,
        nonce: nonce,
        hash: hash,
        previousBlockHash: previousBlockHash,
    };
    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;
}

module.exports = Blockchain;

Let's test our createNewTransaction method in test.js

    const Blockchain = require ('./Blockchain');
    const bitcoin = new Blockchain();

    bitcoin.createNewBlock(23654, "09OIWDDYFGFSJJN", "264736S7SHHGAJJSH")
    bitcoin.createNewTransaction(23654, "ALEX6FGSDDYFGSJJN",                          "233TRESHHGAJJSH")

    console.log(bitcoin);

Save your file and test your new method by running node command and also display our pendingTransaction

node dev/test.js
Blockchain {
  chain: [
    {
      index: 1,
      timestamp: 1676331576916,
      transactions: [],
      nonce: 23654,
      hash: '264736S7SHHGAJJSH',
      previousBlockHash: '09OIWDDYFGFSJJN'
    }
  ],
  pendingTransactions: [
    {
      amount: 23654,
      sender: 'ALEX6FGSDDYFGSJJN',
      recipient: '233TRESHHGAJJSH'
    }
  ]
}

Let's install sha256 to our project as an NPM Library by running this command in our terminal to save it as a dependency for us

npm i sha256 --save

Now import sha256 at the top of our blockchain.js file and use it in our new hashBlock method

const { copyFileSync } = require('fs');
const sha256 = require('sha256');

function Blockchain(){
    this.chain = [];
    this.pendingTransactions = [];
}


Blockchain.prototype.createNewBlock = function(nonce, previousBlockHash, hash) {
    const newBlock = {
        index: this.chain.length + 1,
        timestamp: Date.now(),
        transactions: this.pendingTransactions,
        nonce: nonce,
        hash: hash,
        previousBlockHash: previousBlockHash,
    };
    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(previousBlockHash, currentBlockData, nonce){
    const dataAsString = previousBlockHash + nonce.toString() + JSON.stringify(currentBlockData);
    const hash = sha256(dataAsString);
    return hash;
}


module.exports = Blockchain;

Let's test hashBlock method in our test.js file

const Blockchain = require ('./Blockchain');
const bitcoin = new Blockchain();

// console.log(bitcoin);
const previousBlockHash = '334HHDYRU7SSKFHRRJRH';
const currentBlockData = [
    {
        amount: 10,
        sender: 'NSHFKA19HDU73819',
        recipient: '282HUUJA829AJA01'
    },
    {
        amount: 20,
        sender: 'JHGHGFKA19HDU73819',
        recipient: '299O9HUUJA829AJA01'
    },
    {
        amount: 30,
        sender: 'GJHJGKA19HDU73819',
        recipient: '9Y872HUUJA829AJA01'
    }
];
const nonce = 100;

console.log(bitcoin.hashBlock(previousBlockHash, currentBlockData, 17659));

Let's get our hash log out to our terminal by running this command

node dev/test.js   
0000d48f3a6d615651779c145adf1a88229b4986fd26dd75f362a7fd9078ef35

Let's add our last method called proofOfWork in blockchain.js to generate the correct hash different from pseudorandom hash

const { copyFileSync } = require('fs');
const sha256 = require('sha256');

function Blockchain(){
    this.chain = [];
    this.pendingTransactions = [];
}


Blockchain.prototype.createNewBlock = function(nonce, previousBlockHash, hash) {
    const newBlock = {
        index: this.chain.length + 1,
        timestamp: Date.now(),
        transactions: this.pendingTransactions,
        nonce: nonce,
        hash: hash,
        previousBlockHash: previousBlockHash,
    };
    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(previousBlockHash, currentBlockData, nonce){
    const dataAsString = previousBlockHash + nonce.toString() + JSON.stringify(currentBlockData);
    const hash = sha256(dataAsString);
    return hash;
}
// Proof Of Work
Blockchain.prototype.proofOfWork = function(previousBlockHash, currentBlockData){
    let nonce = 0;
    let hash = this.hashBlock(previousBlockHash, currentBlockData, nonce);
    while (hash.substring(0, 4) !== '0000') {
        nonce++; 
        hash = this.hashBlock(previousBlockHash, currentBlockData,  nonce);
        console.log(hash);
    }

    return nonce;
}



module.exports = Blockchain;

Let's open our test.js file to test our proofOfWork method to see the correct nonce value

const Blockchain = require ('./Blockchain');
const bitcoin = new Blockchain();

const previousBlockHash = '334HHDYRU7SSKFHRRJRH';
const currentBlockData = [
    {
        amount: 10,
        sender: 'NSHFKA19HDU73819',
        recipient: '282HUUJA829AJA01'
    },
    {
        amount: 20,
        sender: 'JHGHGFKA19HDU73819',
        recipient: '299O9HUUJA829AJA01'
    },
    {
        amount: 30,
        sender: 'GJHJGKA19HDU73819',
        recipient: '9Y872HUUJA829AJA01'
    }
];

console.log(bitcoin.proofOfWork(previousBlockHash, currentBlockData, 17659));

Let's test our proofOfWork by running the command till the code generate a final hash value

node dev/test.js
d2b9226a4292938e7ace62703c6004c10632b20c04875135921328022df19cb8
20c5b6616996f6e18c6c2b0c08a811b56edc2cab703735a41b7d5b5bb2c17177
c992b97192cd191c1ed3f31a7f496510c602648d09bd7c3409b9ae0ea57a8eb2
987ab4efd0735cafaa4b9aefd4896e652b67f08e78e58cefd7cc7fce1f628a94
539000433dc212c0397b625a475e57cc2f83008967c03b4f34d2665310a87780...
17659

Let's use our hashBlock method in test.js file

const Blockchain = require ('./Blockchain');
const bitcoin = new Blockchain();

// console.log(bitcoin);
const previousBlockHash = '334HHDYRU7SSKFHRRJRH';
const currentBlockData = [
    {
        amount: 10,
        sender: 'NSHFKA19HDU73819',
        recipient: '282HUUJA829AJA01'
    },
    {
        amount: 20,
        sender: 'JHGHGFKA19HDU73819',
        recipient: '299O9HUUJA829AJA01'
    },
    {
        amount: 30,
        sender: 'GJHJGKA19HDU73819',
        recipient: '9Y872HUUJA829AJA01'
    }
];

console.log(bitcoin.hashBlock(previousBlockHash, currentBlockData, 17659));

Let's test our hashBlock to generate a hash with 0000

node dev/test.js
0000d48f3a6d615651779c145adf1a88229b4986fd26dd75f362a7fd9078ef35

Let's create our last block which is genesisBlock method in blockchain.js file

const { copyFileSync } = require('fs');
const sha256 = require('sha256');

function Blockchain(){
    this.chain = [];
    this.pendingTransactions = [];


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

}


Blockchain.prototype.createNewBlock = function(nonce, previousBlockHash, hash) {
    const newBlock = {
        index: this.chain.length + 1,
        timestamp: Date.now(),
        transactions: this.pendingTransactions,
        nonce: nonce,
        hash: hash,
        previousBlockHash: previousBlockHash,
    };
    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(previousBlockHash, currentBlockData, nonce){
    const dataAsString = previousBlockHash + nonce.toString() + JSON.stringify(currentBlockData);
    const hash = sha256(dataAsString);
    return hash;
}  

// Proof Of Work
Blockchain.prototype.proofOfWork = function(previousBlockHash, currentBlockData){
    let nonce = 0;
    let hash = this.hashBlock(previousBlockHash, currentBlockData, nonce);
    while (hash.substring(0, 4) !== '0000') {
        nonce++; 
        hash = this.hashBlock(previousBlockHash, currentBlockData,  nonce);
        console.log(hash);
    }

    return nonce;
}


module.exports = Blockchain;

Let's test our genesisBlock method in test.js file

const Blockchain = require ('./Blockchain');
const bitcoin = new Blockchain();

console.log(bitcoin);

Let's run our test command

node dev/test.js
Blockchain {
  chain: [
    {
      index: 1,
      timestamp: 1676380482340,
      transactions: [],
      nonce: 100,
      hash: '0',
      previousBlockHash: '0'
    }
  ],
  pendingTransactions: []
}

Congratulations!!!

We've been able to build a blockchain using JavaScript.

If you are stuck somewhere, you can always visit my GitHub repository to have a look at the code.

Thanks for reading.

Don’t forget to share, like, and comment.

I will see you in the next article.

Credit @Forward School