As we know blockchains are designed to be immutable. Here we will design a simple blockchain that will help you understand how hashing makes a blockchain immutable with just a few lines of Java Code.
Note: This is just a demo blockchain, real blockchain involves a lot of other things such as consensus mechanisms, digital signatures, Merkle Tree, etc.. This code sample will be beneficial for an ideal purpose.
The first Block in a blockchain is a Genesis block. The genesis block is almost always hard coded into the software of the applications that utilize its blockchain.
For every new block that is generated afterward, we are going to use the previous block’s hash, as well as its own transactions, as input to determine its block hash.
As;
Object[] contents ={Arrays.hashCode(transactions),previousHash};
blockHash = Arrays.hashCode(contents);
A hash function is a mathematical function that takes the input of arbitrary length numerical data and converts it into fixed-length numerical data.
Different hash functions use different algorithms to produce hash values.
Moreover, a hash function will always give same output for any particular input always. But if you make even a small change in the input the hash value produced will be completely different as compared to the previous one.
Remember hashing is not encryption.
In encryption, once you encrypt the data you can get it back by decrypting it, unlike in hashing you cannot get the input back by any method.
You might have wondered sometime about why is there a need for hashing algorithms such as SHA256(SECURE HASH ALGORITHM)?
The most important reason is that these algorithms help us avoid collisions(similar hash values for different inputs).
Now let's see-through code how blockchain makes it impossible to change the hash of a block so that once a block is written to a blockchain, it cannot change.
We will create a Block class. Each block will have:
After applying getter setter methods to the variables block class look like this:
import java.util.Arrays;
public class Block
{
private int previousHash;
private String[] transactions;
private int blockHash;
public Block(int previousHash, String[] transactions) {
this.previousHash = previousHash;
this.transactions = transactions;
Object[] contents = {Arrays.hashCode(transactions),previousHash};
this.blockHash = Arrays.hashCode(contents);
}
public int getPreviousHash() {
return previousHash;
}
public String[] getTransactions() {
return transactions;
}
public int getBlockHash() {
return blockHash;
}
public void setPreviousHash(int previousHash) {
this.previousHash = previousHash;
}
public void setTransactions(String[] transactions) {
this.transactions = transactions;
}
public void setBlockHash(int blockHash) {
this.blockHash = blockHash;
}
}
Now let's create a blockchain.
We will start by creating a Genesis Block. As Genesis block is the first block in the chain we will hard-code the transactions and previous hash value.
Transactions in real blockchain are definitely going be some transaction class and different data structures will be used. For simplicity, I am writing them as strings.
So the Main class looks like this:
import java.util.ArrayList;
public class Blockchain {
ArrayList<Block> blockchain = new ArrayList<>();
public static void main(String[] args) {
String[] genesisTransactions = {"Suraj sent Ruja 1542 Bitcoins","Ruja sent 10 Bitcoins to John"};
Block genesisBlock = new Block(0,genesisTransactions);
System.out.println("Genesis Block Hash:"+genesisBlock.getBlockHash());
String[] block2Transactions = {"John sent 10 bitcoins to Suraj","Suraj sent 10 bitcoins to Alex"};
Block block2= new Block(genesisBlock.getBlockHash(), block2Transactions);
System.out.println("Block2 Hash:"+block2.getBlockHash());
String[] block3Transactions = {"Alex sent 999 bitcoins to non"};
Block block3 = new Block(block2.getBlockHash(), block3Transactions);
System.out.println("Block3 Hash:"+block3.getBlockHash());
}
}
Output:
Genesis Block Hash:-1106827926
Block2 Hash:957910147
Block3 Hash:-716750945
You can output the HashCode of genesis block change it and see the changes you will see the output differs from the previous output a lot even if you change the case of a single alphabet in the string of transaction.
Output after changing "S" of "Suraj" in genesis block transaction to "s":
Genesis Block Hash:1528835466
Block2 Hash:-701393757
Block3 Hash:1918912447
This is how a chain of blocks is formed, each new block hash pointing to the block hash that came before it. This system of hashing guarantees that no transaction in the history can be tampered with because if any single part of the transaction changes, so does the hash of the block to which it belongs, and any following blocks’ hashes as a result.
It would be fairly easy to catch any tampering as a result because you can just compare the hashes.