Implementing blockchain using Java

The Blockchain is a secure transaction ledger database that is shared by all parties participating in an established, distributed network of computers. It records every transaction between peers and eliminates the need of a middleman. Blockchain proponents often describe the innovation as a “transfer of trust in a trustless world”.

Problems

Considering irregularities in the financial systems, people started questioning the trustworthiness of the Banking technologies. The banking system needs a single source of truth and data-driven decisions. So in this blog, we are building a simple wallet application implemented in Java using Blockchain.

Solution

First, we should know why Blockchain?

  • Blockchain is the first radical technology innovation of the 21st century.
  • Blockchain assets provide an enhanced level of security, increasing the security of the system from hacking and fraud.
  • It provides an easy mechanism to allow users to securely transfer the assets between parties and facilitates an easy audit of user accounts.
  • The system may remain totally private if desirable.

What is Blockchain?

The blockchain is an incorruptible digital ledger of economic transactions that can be programmed to record not just financial transactions but virtually everything of value.

A blockchain, originally block chain, is a continuously growing list of records, called blocks, which are linked and secured using cryptography. Each block typically contains a cryptographic hash of the previous block, a timestamp and transaction data.

Blockchain

Fig: Block representation

Blockchain Network:

There are three types of networks.

  • Centralize
  • Decentralize
  • Distributed

Differentiation between networks

Fig: Differentiation between the networks

Business Use Cases

There are many business use cases where blockchain can be applied. We are focusing few of them here.

Blockchain Financial Services – A lot of people saying that blockchain will change the whole digital currency in the world. Currently, there are various currencies developed like Bitcoin, Etherium, Litecoin and so on.

Blockchain IIOT – It can be applicable in Industrial Internet of Things (IIOT) where real-time processing is done. Any material object is a ‘thing.’ It becomes an internet of things when it has an on/off switch that connects it to the internet and to each other. How does the IoT affect you?  Your printer can automatically order cartridges from Amazon when it runs low. Your alarm clock will change your time for brewing coffee, while your oven will produce an immaculately timed turkey for Thanksgiving. These are just some examples. On a larger scale, cities and governments can use IoT to develop cleaner environments, more efficient energy use and so-called ‘smart cities,’ to improve how we live and work.

Blockchain Health Care  – In the medical field, Personal health records could be encoded and stored on the blockchain with a private key which would grant access only to specific individuals. Receipts of surgeries could be stored on a blockchain and automatically sent to insurance providers as proof-of-delivery.  

Blockchain Music World – Key problems in the music industry include ownership rights, royalty distribution, and transparency. The digital music industry focuses on monetizing productions, while ownership rights are often overlooked. The blockchain and smart contracts technology can circuit this problem by creating a comprehensive and accurate decentralized database of music rights. At the same time, the ledger and provide transparent transmission of artist royalties and real-time distributions to all involved with the labels. Players would be paid with digital currency according to the specified terms of the contract.

Blockchain Personal Identification – We carry a range of identifications: Our driver’s license, computer password, identity cards, keys, social security ID, and so forth. Blockchain ID is a digital form of ID that’s engineered to replace all these forms of physical identification. In the future, fintech scientists say you’ll be able to use the one digital ID for signing up at any registrar. It is open source, secured by the blockchain, and protected by a ledger of transparent account.

As far as we have seen a lot of theory about block & blockchain. Now it’s time to see what it contains and how it works?

Concept

Consider a scenario where bank transaction is happening between two parties. Each party having there own digital wallet named as wallet A and wallet B. Party A wants to send few $ amount to party B. On the similar way wallet B can send the amount to wallet A. Both these transactions will perform when both parties having sufficient balance into their respective wallets. So basically after transaction both wallets values should get updated with digital crypto security.

Transaction from walletsFig: Transaction between two parties.

Setting Up

Blockchain can be implemented by any OOP language. So we are using Java here.

Making the blockchain:

Have a look on below implementation. At first, you don’t understand all the methods and the variables. But don’t Worry!!! Very soon you will get everything perfect.

Step 1 – Create project

Create simple spring-boot maven project. Add following dependencies in pom.xml file that will be required in our project.

https://mvnrepository.com/artifact/com.google.code.gson/gson

https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on

Step 2 – Create a controller

BlockChainController.java

public class BlockChainController {

public static void main(String[] args) {

//Setup Bouncey castle as a Security Provider
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 
   
//Create the new wallets
    walletA = new Wallet();
    walletB = new Wallet();
    Wallet coinbase = new Wallet();

//create genesis transaction, which sends 100$ to walletA:
 genesisTransaction = new Transaction(coinbase.publicKey, walletA.publicKey, Global.accountBalance, null);

//manually sign the genesis transaction
 genesisTransaction.generateSignature(coinbase.privateKey);	

//manually set the transaction id
 genesisTransaction.transactionId = "0";  

//manually add the Transactions Output
genesisTransaction.outputs.add(new TransactionOutput(genesisTransaction.reciepient,    genesisTransaction.value, genesisTransaction.transactionId));    
 // It’s important to store our first transaction in the UTXOs list.
UTXOs.put(genesisTransaction.outputs.get(0).id, genesisTransaction.outputs.get(0)); 

    System.out.println("Creating and Mining Genesis block... ");
    Block genesis = new Block("0");
    genesis.addTransaction(genesisTransaction);
    addBlock(genesis);

    //testing
    Block block1 = new Block(genesis.hash);
    System.out.println("\nWalletA's balance is: " + walletA.getBalance());
    System.out.println("\nWalletA is Attempting to send funds (400) to WalletB...");
    block1.addTransaction(walletA.sendFunds(walletB.publicKey, 400f));
    addBlock(block1);
    System.out.println("\nWalletA's balance is: " + walletA.getBalance());
    System.out.println("WalletB's balance is: " + walletB.getBalance());

    Block block2 = new Block(block1.hash);
    System.out.println("\nWalletA Attempting to send more funds (2000) than it has...");
    block2.addTransaction(walletA.sendFunds(walletB.publicKey, 2000f));
    addBlock(block2);
    System.out.println("\nWalletA's balance is: " + walletA.getBalance());
    System.out.println("WalletB's balance is: " + walletB.getBalance());

    Block block3 = new Block(block2.hash);
    System.out.println("\nWalletB is Attempting to send funds (200) to WalletA...");
    block3.addTransaction(walletB.sendFunds( walletA.publicKey, 200));
    addBlock(block3);
    System.out.println("\nWalletA's balance is: " + walletA.getBalance());
    System.out.println("WalletB's balance is: " + walletB.getBalance());

    String blockchainJson = new GsonBuilder().setPrettyPrinting().create().toJson(blockchain);
    System.out.println(blockchainJson);
 }
}

Step 3 – Create Models

BlockModel.java

public class Block {
	//Block Constructor to store the previous hash, timestamp, current hash.
	public Block(String previousHash ) {
    	this.previousHash = previousHash;
    	this.timeStamp = new Date().getTime();
    	this.hash = calculateHash();      
	}
	
	//Calculate new hash based on blocks contents
	public String calculateHash() {
    		String calculatedhash = StringUtil.applySha256(
             	       previousHash
                     	    	+ Long.toString(timeStamp)
                    	        + Integer.toString(nonce)
                     	       	+ merkleRoot);
    return calculatedhash;
	}

	//Mine the block - Here we are creating a string with difficulty * "0". According to number of difficulty_level, 0's will be appended to strings. Ex. Diff = 5 then "00000"
	public void mineBlock(int difficulty) {
    		String target = new String(new char[difficulty]).replace('\0', '0');
  		while(!hash.substring( 0, difficulty).equals(target)) {
        			nonce ++;
        			hash = calculateHash();
    		}
   	 	System.out.println("Block Mined!!! : " + hash);
	}

	//Add transactions to this block
	public boolean addTransaction(Transaction transaction) {
    	//process transaction and check if valid, unless block is genesis block then ignore.
    	if(transaction == null) return false;
    	if((previousHash != "0")) {
        	if((transaction.processTransaction() != true)) {
            	System.out.println("Transaction failed to process. Discarded.");
            	return false;
      	  	}
    	}
   	 	transactions.add(transaction);
    		System.out.println("Transaction Successfully added to Block");
    		return true;
	}

TransactionModel.java

// Constructor:
public Transaction(PublicKey from, PublicKey to, float value,  ArrayList<TransactionInput> inputs) {
    this.sender = from;
    this.reciepient = to;
    this.value = value;
    this.inputs = inputs;
}

//Signs all the data we dont wish to be tampered with.
public void generateSignature(PrivateKey privateKey) {
    String data = StringUtil.getStringFromKey(sender) + StringUtil.getStringFromKey(reciepient) + Float.toString(value)	;
    signature = StringUtil.applyECDSASig(privateKey,data);
}
//Verifies the data we signed hasnt been tampered with
public boolean verifiySignature() {
    String data = StringUtil.getStringFromKey(sender) + StringUtil.getStringFromKey(reciepient) + Float.toString(value)	;
    return StringUtil.verifyECDSASig(sender, data, signature);
}

//Returns true if new transaction could be created.
public boolean processTransaction() {
    if(verifiySignature() == false) {
        System.out.println("#Transaction Signature failed to verify");
        return false;
    }

    //gather transaction inputs (Make sure they are unspent):
    for(TransactionInput i : inputs) {
        i.UTXO = BlockChainController.UTXOs.get(i.transactionOutputId);
    }

    
//check if transaction is valid:
    if(getInputsValue() < BlockChainController.minimumTransaction) {
        System.out.println("#Transaction Inputs to small: " + getInputsValue());
        return false;
    }

    //generate transaction outputs:
    float leftOver = getInputsValue() - value; //get value of inputs then the left over change:
    transactionId = calulateHash();
    outputs.add(new TransactionOutput( this.reciepient, value,transactionId)); //send value to recipient
    outputs.add(new TransactionOutput( this.sender, leftOver,transactionId)); //send the left over 'change' back to sender

    //add outputs to Unspent list
    for(TransactionOutput o : outputs) {
        BlockChainController.UTXOs.put(o.id , o);
    }

    //remove transaction inputs from UTXO lists as spent:
    for(TransactionInput i : inputs) {
        if(i.UTXO == null) continue; //if Transaction can't be found skip it
        BlockChainController.UTXOs.remove(i.UTXO.id);
    }
    return true;
}

//Tacks in array of transactions and returns a merkle root.
public static String getMerkleRoot(ArrayList<Transaction> transactions) {
    int count = transactions.size();
    ArrayList<String> previousTreeLayer = new ArrayList<String>();
    for(Transaction transaction : transactions) {
        previousTreeLayer.add(transaction.transactionId);
    }
    ArrayList<String> treeLayer = previousTreeLayer;
    while(count > 1) {
        treeLayer = new ArrayList<String>();
        for(int i=1; i < previousTreeLayer.size(); i++) {
            treeLayer.add(StringUtil.applySha256(previousTreeLayer.get(i-1) + previousTreeLayer.get(i)));
        }
        count = treeLayer.size();
        previousTreeLayer = treeLayer;
    }
    String merkleRoot = (treeLayer.size() == 1) ? treeLayer.get(0) : "";
    return merkleRoot;
}

Console Output:

Terminal Output

 

Submit a Comment

Your email address will not be published. Required fields are marked *