Thursday, 11 April 2019

Create simple Block chain using java


In this post, I am going to explain how to create a block chain and how to mine blocks from existing block chain.

This tutorial is divided like below.

         a. What is Block Chain and Block
         b. How to create a block chain in Java
         c. How to validate the block chain?

What is Block Chain and Block?
A block chain is a growing list of blocks that are linked using cryptography.



What exactly the block in block chain?
Each block contains a cryptographic hash of the previous block, a timestamp, transaction data and hash of current block.


Changing the data in any block of block chain leads to chain breaking
Since Each block hash code generated from the previous block hash code, if any one changes existing block data, then it affects hashes of the blocks thereafter. Which in turn leads to make the block chain in incorrect state.

How to create a block chain in Java?
I am going to use gson library to print all the blocks.

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.5</version>
</dependency>

Create a class Block that represents a block in the block chain.

Block.java
package com.sample.app.model;

public class Block {

 private String hashCode;
 private String previousBlockHashCode;
 private String transactionalData;
 private long timeStamp;

 private Block nextBlock;

 public String getHashCode() {
  return hashCode;
 }

 public void setHashCode(String hashCode) {
  this.hashCode = hashCode;
 }

 public String getPreviousBlockHashCode() {
  return previousBlockHashCode;
 }

 public void setPreviousBlockHashCode(String previousBlockHashCode) {
  this.previousBlockHashCode = previousBlockHashCode;
 }

 public String getTransactionalData() {
  return transactionalData;
 }

 public void setTransactionalData(String transactionalData) {
  this.transactionalData = transactionalData;
 }

 public long getTimeStamp() {
  return timeStamp;
 }

 public void setTimeStamp(long timeStamp) {
  this.timeStamp = timeStamp;
 }

 public Block getNextBlock() {
  return nextBlock;
 }

 public void setNextBlock(Block nextBlock) {
  this.nextBlock = nextBlock;
 }

}

Create HashUtil class, that takes a block and update the hash of the block.


HashUtil.java
package com.sample.app.crypt.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

import com.sample.app.model.Block;

public class HashUtil {
 private static final char[] HEXDIGITS = "0123456789ABCDEF".toCharArray();

 public static void update(Block block) {

  MessageDigest messageDigest = null;
  try {
   messageDigest = MessageDigest.getInstance("SHA-256");
  } catch (NoSuchAlgorithmException e) {
   throw new RuntimeException(e);
  }

  String hashCode = block.getPreviousBlockHashCode();

  Date date = new Date();
  block.setTimeStamp(date.getTime());
  long time = date.getTime();

  String transactionalData = block.getTransactionalData();

  String finalData = hashCode + transactionalData + time;

  messageDigest.update(finalData.getBytes());

  byte[] digest = messageDigest.digest();

  block.setHashCode(toHexString(digest));

 }

 private static String toHexString(byte[] bytes) {
  StringBuilder sb = new StringBuilder(bytes.length * 3);
  for (int b : bytes) {
   b &= 0xff;
   sb.append(HEXDIGITS[b >> 4]);
   sb.append(HEXDIGITS[b & 15]);
   // sb.append(' ');
  }
  return sb.toString();
 }

}

Create BlockChainGenerator class, that is responsible to start new block chain, create a block and validates the block for integrity.


BlockChainGenerator.java
package com.sample.app.block.util;

import com.sample.app.crypt.util.HashUtil;
import com.sample.app.json.util.JSONUtil;
import com.sample.app.model.Block;

public class BlockChainGenerator {

 private Block rootBlock = null;
 private Block lastBlock = null;

 public void startNewBlockChain() {
  rootBlock = new Block();

  rootBlock.setTransactionalData("Starting new Block Chain");
  rootBlock.setPreviousBlockHashCode("");

  HashUtil.update(rootBlock);

  lastBlock = rootBlock;

  System.out.println("Root block is created successfully");

 }

 public void createNewBlock(String transactionalData) {
  Block block = new Block();
  block.setTransactionalData(transactionalData);
  block.setPreviousBlockHashCode(lastBlock.getHashCode());
  lastBlock.setNextBlock(block);
  lastBlock = block;

  HashUtil.update(block);
 }

 public void printBlockChain() {
  System.out.println(JSONUtil.getPrettyJson(rootBlock));
 }

 public boolean isChainvalid() {
  if (rootBlock == null)
   return true;

  Block nextBlock = rootBlock.getNextBlock();

  if (nextBlock == null)
   return true;

  Block currentBlock = rootBlock;

  while (nextBlock != null) {
   if (!nextBlock.getPreviousBlockHashCode().equals(currentBlock.getHashCode())) {
    return false;
   }

   currentBlock = nextBlock;
   nextBlock = nextBlock.getNextBlock();
  }
  return true;

 }
}

Create JSONUtil class that takes a java object and prints the json.


JSONUtil.java
package com.sample.app.json.util;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class JSONUtil {
 private static Gson gson = new Gson();
 private static Gson exclusedGson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
 private static Gson prettyGson = new GsonBuilder().setPrettyPrinting().create();

 public static String getJson(Object obj) {
  return gson.toJson(obj);
 }

 public static String getOnlyExposedJson(Object obj) {
  return exclusedGson.toJson(obj);
 }

 public static String getPrettyJson(Object obj) {
  return prettyGson.toJson(obj);
 }

 public static <T> T getObject(String json, Class<T> clazz) {
  return gson.fromJson(json, clazz);
 }

} 


App.java
package com.sample.app;

import com.sample.app.block.util.BlockChainGenerator;

public class App {
 public static void main(String args[]) {
  BlockChainGenerator blockChainGenerator = new BlockChainGenerator();

  blockChainGenerator.startNewBlockChain();

  blockChainGenerator.createNewBlock("Krishna received 100 coins from Bikash");
  blockChainGenerator.createNewBlock("Bikash Received 1000 coins from Ram");
  blockChainGenerator.createNewBlock("Sunil Sent 19 coins to Anu");

  blockChainGenerator.printBlockChain();

  System.out.println("Is Block chain valid : " + blockChainGenerator.isChainvalid());

 }
}


Run App.java, you can see below kind of messages in console.

Root block is created successfully
{
  "hashCode": "5998BD00E8F9B76452DA99FCEF5368B22B2A4B28ABA9AFF8AF7A3B3E6C9F2222",
  "previousBlockHashCode": "",
  "transactionalData": "Starting new Block Chain",
  "timeStamp": 1554980586221,
  "nextBlock": {
    "hashCode": "E130F0D4DC1AAAAFBF302578A5D25F35DDF488AB251CD8FA0FBC20AFDDB11B5F",
    "previousBlockHashCode": "5998BD00E8F9B76452DA99FCEF5368B22B2A4B28ABA9AFF8AF7A3B3E6C9F2222",
    "transactionalData": "Krishna received 100 coins from Bikash",
    "timeStamp": 1554980586221,
    "nextBlock": {
      "hashCode": "30E1D83D88D95F8E690104BA81427AB29119D86ADF462C3D92692871BD9C623A",
      "previousBlockHashCode": "E130F0D4DC1AAAAFBF302578A5D25F35DDF488AB251CD8FA0FBC20AFDDB11B5F",
      "transactionalData": "Bikash Received 1000 coins from Ram",
      "timeStamp": 1554980586222,
      "nextBlock": {
        "hashCode": "31F211646379BB1BAABB1EAA3D50A60C19AAC2D8CB5C5407C9921D0E863B79ED",
        "previousBlockHashCode": "30E1D83D88D95F8E690104BA81427AB29119D86ADF462C3D92692871BD9C623A",
        "transactionalData": "Sunil Sent 19 coins to Anu",
        "timeStamp": 1554980586222
      }
    }
  }
}
Is Block chain valid : true

You can clone complete source code from below github location. 


You may like



No comments:

Post a Comment