Why Blockchain Is Too Big To Ignore Or Build A Blockchain With JavaScript – Part 2

Prerequisites: Basic knowledge of JavaScript

Outline

  1. Intro
  2. Block class
  3. USDevBlockchain
  4. Mining
  5. Transactions and rewards
  6. Transaction signature

Intro

In the first part of the blog, we have introduced the notion of blockchain and covered the basic concepts. You could dig a lot deeper if you want, but that is the minimum knowledge we need to move on to the next step of the blockchain system of our own. In this part, we will make a blockchain system called USDevCoin. With the help of our system, users will be able to exchange USDev coins and every transaction will be securely stored as blocks in the chain. Now, by no means the system will be secure enough actually to perform the role of a blockchain, but it will be enough to demonstrate the infrastructure. There is a lot to do, so let’s dive right in!

Environment setup

Before getting started, we need to ensure that we have the latest version of Node installed on our machine. Once you confirm it, go ahead and create the main JavaScript file.

We will call the file chain.js and write the first class Block.

Block class

// chain.js
class Block {
	constructor(index, payload, timestamp, previousHash = ""){
		this.index = index;
		this.payload = payload;
		this.timestamp = timestamp;
		this.previousHash = previousHash;
		this.hash = "";
	}
}

The are four arguments given in the constructor of the class Block. They have the following purposes:

index – it will be the index of the block in the chain

payload – data that the block holds. It could be anything. In our case, we will store the number of coins being transferred in this parameter

timestamp – date and time of the record when it was created

previousHash – since we are going to be chaining the blocks, this argument will refer to the hash of the previous block

If you have noticed, we initially set the hash value of the class to an empty string. Now we need a way to calculate the hash value of the block. Hash value entails taking a range of arguments for a digital record, and creating a unique signature. The important thing about this hash is that it always should return the exact same value when we provide identical parameters.
In JavaScript however, the hashing function is not included by default. So we have to use a third-party library called crypto-js.

So we need to run npm install --save crypto-js in our project folder and import the hashing function from the node module. We will specifically use the SHA256 algorithm for hashing.

// chain.js
const  SHA256 = require("crypto-js/sha256");

class Block {
	constructor(index, payload, timestamp, previousHash = ""){
		this.index = index;
		this.payload = payload;
		this.timestamp = timestamp;
		this.previousHash = previousHash;
		this.hash = this.getHashValue;
	}
	getHashValue() {
		return SHA256(
		  this.index + 
		  this.previousHash + 
		  this.timestamp + 
		  JSON.stringify(this.payload)
		).toString();
	}
}

SHA256 algorithm processes the values and returns the hash value as a string. We also need to update the constructor with the new function, so that the hash automatically gets calculated upon creation of a block.

USDevBlockchain class

The next step is to add the USDevBlockchain class.

class USDevBlockchain {
  constructor(){
    // Chain is an array of blocks
    this.chain = [this.getFirstBlock()];
  }

  // We have to create the first block manually
  getFirstBlock() {
    return new Block(0, "First Block (Genesis Block)", new Date(), "0");
  }

  // Returns the latest block in the array
  getLastBlock(){
    return this.chain[this.chain.length - 1];
  }

  // Adds new block
  addNewBlock(newBlock){
    newBlock.previousHash = this.getLastBlock().hash;
    newBlock.hash = newBlock.getHashValue();
    this.chain.push(newBlock);
  }

  // It checks if the blocks are chained properly and valid
  validateChain(){
    for(let i = 1; i < this.chain.length; i++){
      let prevBlock = this.chain[i-1];
      let currBlock = this.chain[i]

      // Check if each block's hash value was not modified
      if(currBlock.hash !== currBlock.getHashValue()){
        return false;
      }
      
      // Check if the blocks are chained correctly
      if(currBlock.previousHash !== prevBlock.hash){
        return false;
      }
    }
    return true;
  }
}

Let’s go through all of the features of this class.

  • constructor defines the chain as an array
  • getFirstBlock creates the initial block in the chain. This first block is usually called the Genesisblock. We need to create it at the beginning manually
  • getLastBlock returns the latest block in the chain. We need to know this to connect the new block to the chain
  • addNewBlock is self-explanatory. It adds a new block to the chain
  • validaChain checks if the chain is valid

We can test our classes to make sure that we are not missing anything

const USDevCoin = new USDevBlockchain();
USDevCoin.addNewBlock(new  Block(1, {amount:  2}, new  Date()));
USDevCoin.addNewBlock(new  Block(2, {amount:  5}, new  Date()));
console.log(JSON.stringify(USDevCoin))

We can test the validation function as well.

const  USDevCoin  =  new  USDevBlockchain();
USDevCoin.addNewBlock(new  Block(1, {amount:  2}, new  Date()));
USDevCoin.addNewBlock(new  Block(2, {amount:  5}, new  Date()));

console.log(USDevCoin.validateChain()); // Prints "true"

USDevCoin.chain[1].payload  = {amount:  290}; // Someone tampers with the chain

console.log(USDevCoin.validateChain()); // Prints "false"

Mining

The current state of the application is not only incomplete but also fragile. Because it allows us to add new blocks to the chain very quickly, spammers can take advantage of this weakness and try to add a huge number of blocks at the same time and eventually break the system. Or the whole chain could be overwritten with a powerful machine. To prevent all of these from happening, we need to implement a method to enforce the system to wait for a certain amount of time before adding a new block to the chain.

For example, Bitcoin requires the hashes to have a specific number of zeros at the beginning. That number is also called the difficulty. It is hard for the machines to find the hash value with the exact amount of zeros at the beginning. So it will take time and tremendous computational power to come up with that value. Since the whole system is distributed, there are a bunch of networks competing against each other to find the correct value. The good thing about mining is that even though it takes a long time to process, it is swift and easy to verify if the work was completed correctly. The entire step is called proof-of-work. Now let us implement it in our code.

In order to add the proof of work step to the system, we need to add a new function to the Block class. This function basically has a while loop which does not stop until it matches the requirement we specify in the arguments.

class Block {
	constructor(index, payload, timestamp, previousHash = ""){
		this.index = index;
		this.payload = payload;
		this.timestamp = timestamp;
		this.previousHash = previousHash;
		this.hash = this.getHashValue;
		this.nonce = 0;
	}
	// .........
	mineNewBlock(difficulty){
		 while(this.hash.substr(0, difficulty) !== Array(difficulty + 1).join("0")){
		   this.nonce++;
		   this.hash = this.getHashValue();
		 }
	}
}

mineNewBlock function takes difficulty as a parameter. The difficulty is another term used in the blockchain world. In simple terms, it defines the level of difficulty to mine new blocks. Bitcoin for example is designed to take about 10 minutes to mine a new block. That timeframe could be increased or decreased by manipulating the difficulty parameter.

The while loop waits until the hash generated has the specified number of zeros at the beginning given in the difficulty property.

Then we have to modify the addNewBlock function to include the newly created function in the Block class. While calling the mineNewBlock function, we send the difficulty defined in the constructor.

class USDevBlockchain {
  constructor(){
    // Chain is an array of blocks
    this.chain = [this.getFirstBlock()];
    this.difficulty = 3;
  }
  // .....
  // Adds new block
  addNewBlock(newBlock){
    newBlock.previousHash = this.getLastBlock().hash;
    newBlock.mineNewBlock(this.difficulty);
    this.chain.push(newBlock);
  }
  // ....
}

Transactions and Rewards

As the name of our blockchain USDevCoin indicates, we are going to use our system for making a cryptocurrency. The most critical part of the cryptocurrencies is the ledger of transactions. Coins get transferred from one user to another, and that action gets recorded as a single transaction. However, one transaction alone cannot be stored as a whole block in the chain. Because of the proof-of-work security layer we have in place.

Again, going back to Bitcoin. We earlier mentioned that it takes about 10 minutes to mine a single block. But in 10 minutes we cannot process only one transaction. That would be an incredibly useless system. So there are thousands of transactions happening within that timeframe. While the network waits for about 10 minutes, those transactions get added to a queue and stay as pending transactions. Once a new block gets mined, all of the pending transactions will be included in that new block and the block is added to the chain.

It means that we have to modify our Block class to include an array of transactions, instead of just a random data object.

// chain.js
const SHA256 = require("crypto-js/sha256");

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

class Block {
  constructor(transactions, timestamp, previousHash = ""){
    this.previousHash = previousHash;
    this.timestamp = timestamp;
    this.transactions = transactions; // Data -> Transactions
    this.hash = this.getHashValue();
    this.nonce = 0;
  }

  getHashValue() {
    return SHA256(
      this.previousHash + 
      this.timestamp + 
      JSON.stringify(this.transactions) +
      this.nonce
    ).toString();
  }
  //...
}

Then in our USDevBlockchain class we need to make some drastic modifications. Let’s write the code first and then we will go through each addition on by one.

class USDevBlockchain {
  constructor(){
    // Chain is an array of blocks
    this.chain = [this.getFirstBlock()];
    this.difficulty = 3;
    this.pendingTransactions = [];
    this.rewardForMiners = 20;
  }
  //....
  mineBlockForPendingTransactions(minerAddress){
    let newBlock = new Block(this.pendingTransactions, new Date(), this.getLastBlock().hash);
    newBlock.mineNewBlock(this.difficulty);
    this.chain.push(newBlock);

    // When a new block is mined, reward the miner
    // But the reward will be available with the next block
    this.pendingTransactions = [
      new Transaction(null, minerAddress, this.rewardForMiners)
    ];
  }

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

  getWalletBalance(address){
    let bal = 0;
    for(let block of this.chain){
      for(let t of block.transactions){
        if(t.fromAddress === address){
          bal -+ t.amount;
        }
        if(t.toAddress === address){
          bal += t.amount;
        }
      }
    }
    return bal;
  }
  // .....
}
  1. We added the pendingTransactions property, which will store an array of transactions that are still waiting to be included in a new block
  2. rewardForMiners property defines the number of coins that will be given as a reward for mining the blocks. Since mining requires a lot of computations and machine power, the miners must be compensated for their work.
  3. addTransactionToList function takes a transaction record and adds it to the list of pending transactions
  4. mineBlockForPendingTransactions function grabs the list of pending transactions and adds them into the newly mined block when it is completed. Also, once the block is mined, the reward coin for the miner will be stored as a pending transaction. Which means is not available right away. It will be given to the miner on the next completion of mining a new block.
  5. getWalletBalance returns the current balance of an address

Transaction signature

Currently, there is a massive problem with our cryptocurrency system: anyone can use any coin in the network. In other words, people can spend the coins that are not even theirs.

To fix this issue, we need to sign each transaction with a private key. By signing I mean adding a signature property to each transaction. So that when we do the calculations to get the wallet balance, we know whom that transaction belongs to. We can get the private key by utilizing the elliptic module.

Let’s get the public and private keys first. In the main project folder run npm i --save elliptic, create a new file called key.js and add the following code.

const EC = require("elliptic").ec;
const ec = new EC("secp256k1");

const keyPair = ec.genKeyPair();
const publicKey = keyPair.getPublic("hex");
const privateKey = keyPair.getPrivate("hex");

console.log("Public: " + publicKey); // Wallet address
console.log("Private: " + privateKey); // Used to sign

secp256k1 algorithm is actually used in Bitcoin to generate keys. Once we run node key.js we will see two keys on the console: one private and one public.

Public: 0419034253dc7f431983904da1adba98fb766a1669f7b8c55d03fb4d2381a1340b88d52c4f26936cab7ee6473285b2d891ad0552ceb1431fd7fab36ca4bfbf4769
Private: c6e9fb1a2b8954e3af2f92ba4ddfb7f8328f6288f4c53f93e7c6aca0a29148b9

Private key should never be shared with others because it is used to sign transactions. Public key serves as a wallet address, so it can be shared with the public.

Next we need to add a few modifications to the chain.js file.

First we need to change the Transaction class to reflect the signing process.

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

  getHashValue(){
    return SHA256(
      this.fromAddress + 
      this.toAddress + 
      this.amount
    ).toString();
  }

  signTransaction(key){
    if(key.getPublic("hex") !== this.fromAddress){
      throw new Error("Invalid signature");
    }
    this.signature = key.sign(this.getHashValue(), "base64").toDER("hex");
  }

  isTransactionValid(){
    if(this.fromAddress === null) return true;
    if(!this.signature ||  this.signature.length === 0){
      throw new Error("No signature was found.");
    }

    const publicKey = ec.keyFromPublic(this.fromAddress, "hex");
    return publicKey.verify(this.getHashValue(), this.signature);
  }
}

signTransaction and isTransactionValid functions add a signature to each transaction, and verify the existing ones with the help of elliptic node module.

And in the Block class, we can add a new function to validate all the transactions that block holds.

class Block {
  // ......
  hasValidTransactions(){
    for(const t of this.transactions){
      if(!t.isTransactionValid){
        return false;
      }
    }
    return true;
  }
}

Now, let’s create an index file to test all of the code.

Make sure to export the classes from the chain.js file.

const EC = require("elliptic").ec;
const ec = new EC("secp256k1");
const { USDevBlockchain, Transaction } = require("./chain");

const key = ec.keyFromPrivate("c6e9fb1a2b8954e3af2f92ba4ddfb7f8328f6288f4c53f93e7c6aca0a29148b9");
const walletAddress = key.getPublic("hex");

const USDevCoin = new USDevBlockchain();
const t1 = new Transaction(walletAddress, "someone else's wallet address", 2);
t1.signTransaction(key);
USDevCoin.addTransactionToList(t1);

USDevCoin.mineBlockForPendingTransactions(walletAddress);

const t2 = new Transaction(walletAddress, "someone else's wallet address", 2);
t2.signTransaction(key);
USDevCoin.addTransactionToList(t2);

USDevCoin.mineBlockForPendingTransactions(walletAddress);

console.log("My balance: " + USDevCoin.getWalletBalance(walletAddress));

//Prints: My balance: 96

Link to GitHub

In the next and last part of this blog, we will create a neat user interface that will implement the blockchain system we have built.

Cheers!

Why Blockchain Is Too Big To Ignore Or Build A Blockchain With JavaScript – Part 1

Prerequisites: Basic knowledge of JavaScript

You might be thinking, why would you even want to build a “Blockchain” system with JavaScript. Isn’t it a language to make websites? Well, it is. But it can also be used to explain the concepts of blockchain in a simple way. Blockchain is already way to big to ignore. Some people still think that blockchain is the same as Bitcoin. Although it may have started with cryptocurrencies, blockchain could be applied in many other areas of our lives, beyond the cryptos, that can change the way our societies function today. In this article, let us clear out the fog before the notion of blockchain and create a simple blockchain system of our own to see how it works under the hood.

A simple explanation of blockchain

In 1440, humanity invented one of the most essential tools in the history – printing press. The printing press allowed us to distribute knowledge to ordinary people, which was only available to a tiny percentage of the population before. Unlike carving or handwriting, printing machines copied and created educational materials much faster. This invention filled a massive gap in the development of human history. Let’s call that gap the “Knowledge Gap.”

Then, towards the end of the 1800s, we invented the first engine. It enabled us to run most of the devices and machines without the use of human labor. It was one of the reasons for abandoning slavery. We could say that this invention filled the “Power Gap

In the 1980s, there was another invention, that changed the way we communicate, interact, and socialize today – the internet. It was the stepping stones of building the world where the meaning of distance would change completely. The Internet brought everyone closer regardless of their locations. This revolution filled one more gap in history, which is the Distance Gap

Now, you probably guessed where I am going with this. The blockchain technology is going to fill another gap – the Trust Gap. It may seem like people do not care that much about trust for it to be called a “gap in history”, but in many areas, such as business, trust is everything. Success in business heavily depends on trust. People are naturally inclined not to trust businesses. It is a normal thing to do. However, there is an underlying reason for that. The way transact today is not totally transparent. Exchange of goods and services relies on many layers of intermediaries (middlemen). Those middlemen differ from one another with they way keep records, conduct business, etc.

Let’s take buying a used car as an example. There are multiple ways to buy a used car: we could buy it from a dealership or from an individual. Either way, it can be really challenging to get the full history of the car, from the time it was manufactured, to the time it was put on the market for resale. People always try to sell their cars at the highest price. Even if that means hiding an accident or lying about some damages, it may not be possible to see the mechanical issues of the car at the time of testing or negotiation.

What if there was a system of records, where every single event in a car’s history would be captured and visible to everyone? What if it had a secure authentication process and ensured that the records could not be modified once it was added? This is where the blockchain comes in. A blockchain is a distributed, decentralized and immutable public ledger. It uses a reliable set of algorithms to add and keep records of anything we want and make them available to the public.

Before continuing with the article, we need to clarify the meaning of some words.

The first one is decentralized.

Decentralized – means power is delegated from a central authority to regional and local authorities. There is no single point for decision making. For example, look at the fast food franchise chains. Even though they have a parent restaurant that monitors the overall progress, chains are responsible for their own operations. Centralized refers to placing the power and authority in a center. For example, when you want to send a funny picture through Gmail, you log in to your Gmail account, upload the image and send it to a receiver. In this case, you have to trust that Google keeps your message private. You have to trust that they don’t decide to sell your data to someone one day. Also, if the Gmail servers are down, all of your data is gone.

A – Centralized | B – Decentralized

Distributed – refers to the differences of locations. In a non-distributed environment, all the parts of a system are in a single physical location. In a distributed environment, parts of the system are placed in separate locations. For example, say you create a powerpoint presentation and save it your computer. Currently, that document is stored only on your local machine and it is not distributed. Now, say you take a copy of the exact same material and send it to a few of your peers as a backup. Then your document would be stored in a distributed environment.

Immutable – means once a record is created, it can never be modified.

Ledger – is another name for a book or digital system that contains a list of records. For example, a financial accounts book of a company where they track debits and credits.

By the way, actually there are some services, such as Carfax, that keep track of changes to motor vehicles. However, they lack critical components of a trustworthy system: they can be tampered with, and only the company profits from selling information gathered by the community.

Technical details of blockchain

So a blockchain is a chain of information blocks stored in a distributed database that maintains a continuously increasing list of records (ledger).

There are three main components of a block:

  1. data
  2. hash of the current block
  3. hash of the previous block

The type of data in a block depends on the kind of blockchain system. Bitcoin for example stores the history of a transaction between the receiver and sender and the number of coins in a block.

Hash – is just like a digital signature of a block. Each block would have a unique hash value. In technical terms, a hash is a result of turning an arbitrarily large amount of data into a fixed-length key by running it through a hashing algorithm. Bitcoin, for example, uses SHA-256 hashing algorithm.

Furthermore, each block must be linked to the previous block by its hash key. It is critical to keep the chains connected; otherwise the whole system collapses. That is also one of the main advantages of blockchain technology. Even a small change in the chaining invalidates all of the previous blocks.

In order to prevent attacks or tampering on the chains, blockchains implement a mechanism called Proof-Of-Work. It basically slows down the process of adding new blocks. In bitcoin’s case, it takes about 10 minutes to add a new block.

Another vital element of a blockchain system is the Consensus. It means validating each new block by more 50% of the peers before adding it to the chain.

Summary

Blockchain is the next revolution that will change the foundation of trust in business. Even though it started out with the popular cryptocurrency – Bitcoin, people have realized that it can be applied in almost any field where the exchange of value occurs. Blockchain is a distributed, decentralized and immutable public ledger that is available for the public. It uses complex cryptographic algorithms to secure and maintain the system.

In the second part of the article, we will be building a simple blockchain system using JavaScript.