Back

Creating a blockchain network

MD Rashid Hussain
MD Rashid Hussain
Dec-2022  -  5 minutes to read

Starting with the most basic question "What is Block Chain ?"

The blockchain is another revolutionary technology that can change the ways of the internet just like open sourced software did. Just like them, blockchain will take up some time to cool off and get reasonably priced for everyone to use in modern developments.

It could take years to reach the real potential that lies within. As blockchain is a distributed P2P ledger system, anyone can see other users’ entries, but undoubtedly no one can alter it.

You can only update blockchain using consensus algorithm. So, when a new set of information gets uploaded on the system, no one can alter it. The blockchain will contain accurate and reliable information on the ledger.

The core idea behind blockchains is its decentralized nature. You will be fascinated by the fact of how it all works inside. Blockchain might sound simple, but inside there are a lot of protocols and algorithms that make it happen.

For more info, refer this BlockChain Technology Guide

Picture Taken from 101blockchains

Below I attach my code on How I created my own blockchain network in flask (python) and nodejs (javascript)

# blockchain.py
import json
from hashlib import sha256
from time import time
 
 
class Blockchain(object):
    def __init__(self):
        self.chain = []
        self.current_transactions = []
        self.new_block(previous_hash=1, proof=100)
 
    def proof_of_work(self, last_proof):
        # This method is where you the consensus algorithm is implemented.
        # It takes two parameters including self and last_proof
        proof = 0
        while self.valid_proof(last_proof, proof) is False:
            proof += 1
        return proof
 
    @staticmethod
    def valid_proof(last_proof, proof):
        # This method validates the block
        guess = f'{last_proof}{proof}'.encode()
        guess_hash = sha256(guess).hexdigest()
        return guess_hash[:4] == "0000"
 
    def new_block(self, proof, previous_hash=None):
        # This function creates new blocks and then adds to the existing chain
        # This method will contain two parameters proof, previous hash
        block = {
            'index': len(self.chain) + 1,
            'timestamp': time(),
            'proof': proof,
            previous_hash: previous_hash or self.hash(self.chain[-1]),
        }
        # Set the current transaction list to empty.
        self.current_transactions = []
        self.chain.append(block)
        return block
 
    def new_transaction(self, sender, recipient, amount):
        # This function adds a new transaction to already existing transactions
        # This will create a new transaction which will be sent to the next block.
        # It will contain three variables including sender, recipient and amount
        self.current_transactions.append(
            {
                'sender': sender,
                'recipient': recipient,
                'amount': amount,
            }
        )
        return self.last_block['index'] + 1
 
    @staticmethod
    def hash(block):
        # Used for hashing a block
        # The follow code will create a SHA - 256 block hash
        # and also ensure that the dictionary is ordered
        block_string = json.dumps(block, sort_keys=True).encode()
        return sha256(block_string).hexdigest()
 
    @property
    def last_block(self):
        # Calls and returns the last block of the chain
        return self.chain[-1]
# main.py
from uuid import uuid4
from flask import Flask, request, jsonify
from blockchain import Blockchain
 
app = Flask(__name__)
node_identifier = str(uuid4()).replace('-', '')
 
# Initializing blockchain
blockchain = Blockchain()
 
 
@app.route('/mine', methods=['GET'])
def mine():
    # Here we make the proof of work algorithm work
    last_block = blockchain.last_block
    last_proof = last_block['proof']
    proof = blockchain.proof_of_work(last_proof)
 
    # rewarding the miner for his contribution. 0 specifies new coin has been mined
    blockchain.new_transaction(
        sender="0",
        recipient=node_identifier,
        amount=1,
    )
 
    # now create the new block and add it to the chain
    previous_hash = blockchain.hash(last_block)
    block = blockchain.new_block(proof, previous_hash)
    response = {
        'message': 'The new block has been forged',
        'index': block['index'],
        'transactions': block['transactions'],
        'proof': block['proof'],
        'previous_hash': block['previous_hash']
    }
    return jsonify(response), 200
 
 
@app.route('/transactions/new', methods=['POST'])
def new_transaction():
    values = request.get_json()
    # Checking if the required data is there or not
    required = ['sender', 'recipient', 'amount']
    if not all(k in values for k in required):
        return 'Missing values', 400
 
    # creating a new transaction
    index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
    response = {'message': f'Transaction is scheduled to be added to Block No. {index}'}
    return jsonify(response), 201
 
 
@app.route('/chain', methods=['GET'])
def full_chain():
    response = {
        'chain': blockchain.chain,
        'length': len(blockchain.chain)
    }
    return jsonify(response), 200
 
 
if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000)
// blockchain.js
 
const uuid = require('uuid');
const crypto = require('crypto');
 
class BlockChain {
  constructor() {
    this.chain = [];
    this.currentTransactions = [];
    this.newBlock(1, 100);
  }
 
  proofOfWork(lastProof) {
    let proof = 0;
    while (this.validProof(lastProof, proof) === false) {
      proof++;
    }
    return proof;
  }
 
  validProof(lastProof, proof) {
    const guess = `${lastProof}${proof}`.toString();
    const hash = crypto.createHash('sha256').update(guess).digest('hex');
    return hash.startsWith('0000');
  }
 
  newBlock(proof, previousHash = null) {
    const block = {
      index: this.chain.length + 1,
      timestamp: Date.now(),
      proof: proof,
      previousHash: previousHash,
    };
    this.currentTransactions = [];
    this.chain.push(block);
    return block;
  }
 
  newTransaction(sender, recipient, amount) {
    this.currentTransactions.push({
      sender,
      recipient,
      amount,
    });
    return this.lastBlock().index + 1;
  }
 
  hash(block) {
    return crypto
      .createHash('sha256')
      .update(JSON.stringify(block))
      .digest('hex');
  }
 
  lastBlock() {
    return this.chain[this.chain.length - 1];
  }
}
 
module.exports = {
  blockChain: new BlockChain(),
  nodeIdentifier: uuid.v4().toString().replaceAll('-', ''),
};
// controllers.js
 
const { blockChain, nodeIdentifier } = require('./blockchain');
 
const mine = (req, res) => {
  const lastBlock = blockChain.lastBlock();
  const lastProof = lastBlock.proof;
  const proof = blockChain.proofOfWork(lastProof);
 
  blockChain.newTransaction(0, nodeIdentifier, 1);
 
  const prevhash = blockChain.hash(lastBlock);
  const block = blockChain.newBlock(proof, prevhash);
  return res.status(200).json({
    ...block,
    message: 'The new block has been forged',
  });
};
 
const newTransaction = (req, res) => {
  const { sender, recipient, amount } = req.body;
  if (!sender || !recipient || !amount) throw new Error('Invalid transaction');
 
  const index = blockChain.newTransaction(sender, recipient, amount);
  return res.status(201).json({
    message: 'Transaction is scheduled to be added to Block No. ' + index,
  });
};
 
const chain = (req, res) => {
  return res.status(200).json({
    chain: blockChain.chain,
    length: blockChain.chain.length,
  });
};
 
const makeSafe = (check) => (req, res, next) => {
  Promise.resolve(check(req, res, next)).catch(next);
};
 
module.exports = {
  mineRouter: makeSafe(mine),
  newTransactionRouter: makeSafe(newTransaction),
  chainRouter: makeSafe(chain),
};
// index.js
 
const express = require('express');
const cors = require('cors');
 
const {
  chainRouter,
  mineRouter,
  newTransactionRouter,
} = require('./controllers');
 
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
  cors({
    credentials: true,
    origin: 'http://localhost:3000',
    optionsSuccessStatus: 200,
  })
);
 
app.get('/mine', mineRouter);
app.post('/transactions/new', newTransactionRouter);
app.get('/chain', chainRouter);
 
app.all('/', (_, res) => {
  return res.json({ message: 'Server is OK' });
});
 
// Global error handler
app.use((err, req, res, _) => {
  console.error(err);
  return res.status(500).json({
    message: err.message || 'INTERNAL SERVER ERROR',
  });
});
 
process.on('uncaughtException', (error) => {
  console.error(error);
  process.exit(1);
});
 
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Listening on port ${port}`));

Here is the complete repository on github https://github.com/m3rashid/blocked-chain. Please give it a star and contribute for improvements