Build Your First Blockchain with Salesforce Apex

Build Your First Blockchain with Salesforce Apex

Introduction of Blockchain

According to Wikipedia "A blockchain, originally blockchain is a growing list of records, called blocks, which are linked using cryptography."

Blockchain was first described in 1991 by Stuart Haber and W. Scott Stornetta. But it got into the limelight after Bitcoin.

Blockchain has nodes, and these nodes are called Blocks. Each block contains the hash, hash of the previous block, timestamp, and the data. Tempering with blockchain is not easy. If a block has been corrupted then the chain gets corrupted.

The Concept of Blockchain

A Block is pretty similar to the linked list but with more complexity. A block's hash is generated by the data from the block. But it is simple to generate the hash from data. To prevent this it also contains the hash of the previous block. so, if any data is touched then block get invalid and the chain as well.If someone wants to hack the blockchain then hacker needs to update all the blocks. It is not that simple and it is time-consuming as well. In Bitcoin, each block can be updated or created in the gap of 10 minutes. so it can take one person's beautiful life to change all the blocks.

2

Above image was taken from the Web.

Basic Implementation of Blockchain with Salesforce Apex

I have been seeing a lot of buzz about blockchain. I have gone through few of the blogs and basic programmes in NodeJs. Truly, I still know about it very less. But my interest of salesforce brings me to write the Basic blockchain programme at the apex. The blockchain is, still Interstellar and Inception for me.

3

Let's Code:

1. Create a class called Block https://github.com/TheVishnuKumar/Blockchain-with-Salesforce-Apex/blob/master/Block.cls

This class will be used to create new blocks in the chain.

1.1) 

public Block(integer index, string data, string prevHash)

The constructor of the class will have three parameters.

  • Index: Index of the block.
  • Data: Data for the Block.
  • prevHash: Hash code of the previous block.

1.2) 

private long generateTimeStamp()

This method will generate a timestamp for the block.

1.3)

public string getHash() {
    Blob dataToEncrypt = Blob.valueOf( this.data + this.prevHash + this.index + this.timestamp ); 
    Blob encrypted = crypto.generateMac('HmacSHA256', dataToEncrypt, Blob.valueOf('key')); 
    return EncodingUtil.base64Encode(encrypted); 
}
  • This method creates hash code from data + prevHash + index + timestamp.
  • I am using the generateMac method from Crypto class.
  • I am selecting HmacSHA256 in the algorithm.
  • You can choose any Private key to generate a message authentication code (Mac).

2. Create a Class called Blockchain https://github.com/TheVishnuKumar/Blockchain-with-Salesforce-Apex/blob/master/BlockChain.cls

This class will be used to create the new blocks in the chain and Validate chain.

2.1)

public void addBlock(string data) {
    // Defining Index from chain size
    integer index = chain.size();

    // Checking for previous block's hash, If it is a the first block then it set previous block as '0'
    string prevHash = chain.isEmpty()==true ? '0' : chain.get(chain.size()-1).hash;

    // Creating a block from index, data and previous block's hash
    Block newBlock = new Block(index, data, prevHash);
    
    // Adding the new block in the chain
    chain.add(newBlock);
}

This method will add a new block to the chain with the given data.

2.2)

public boolean isChainValid()

This method is checking for the valid chain.

  • if the chain is not valid then it will return false
  • if it is valid then it will return true.

2.3)

public boolean isBlockValid(integer index) {
    //Checking block's hash with run time calculated a hash from the block
    //If someone has changed the block data then getHash will return a new data
    //This will not be same as the block's Hash
    if(chain[index].hash != chain[index].getHash() ){
        return false;
    }
 
    //If the index is greater than zero then it is also checking the block's prevHash from previous block's hash.
    //If someone changed the data and but still he needs to change the hash as well
    //Hash is generated by the combination of data+index+timestap+prevHash.
    //If someone wants to make the hash correct, he has to change the prevHash as well
    //Now the block seems good as all the needed values are changed
    //But now this line will check prevHash from previous index's block hash.
    //It will not be the same. Now it sends the false in return.
    if(index > 0 && chain[index].prevHash != chain[index-1].hash ) {
        return false;
    } 
    return true;
}

This method is checking for the valid block.

  • if the block is not valid then it will return false,
  • if it is valid then it will return true.

As you have to see that if someone wants to change a block then the person needs to change the entire chain.

Testing Time:

@isTest
public class BlockChainTest{ 
    //Testing Blockchain 
    @isTest
    public static void testBlockChain() {
        /** Data Setup **/    
        //Creating Instance of Blockchain
        BlockChain bChain = new BlockChain();

        //addBlock method take data as the string
        //Changing data to the string with the JSON format
        //Adding the first block to the chain
        bChain.addBlock( json.serialize( new BCTestDataWrapper('Iron Man', '2334343434') ) );
        
        //Adding the second block to the chain
        bChain.addBlock( json.serialize( new BCTestDataWrapper('Thor', '34343434') ) );
        
        /** Positive Testing **/
        //isChainValid will return true, as no data has been modified from block
        system.assertEquals(true, bChain.isChainValid() );
        
        //Print Blockchain
        system.debug('-Blockchain Data Before Modifying--'+Json.serialize( bChain.chain) );
        
        /** Negative Testing **/
        //Now updating the 0 index's block
        BCTestDataWrapper tData = (BCTestDataWrapper)JSON.deserialize(bChain.chain[0].data, BCTestDataWrapper.class);
        tData.name = 'Thanos';
        bChain.chain[0].data = json.serialize(tData);
        
        //isChainValid will return false, as the data has been modified from block
        system.assertEquals(false, bChain.isChainValid() );
        
        //Print Blockchain
        system.debug('-Blockchain Data After Modifying--'+Json.serialize( bChain.chain) );
    }
}

I hope it cleared the basic concept of Blockchain.

Happy Blockchain

Popular Salesforce Blogs