Blockchain is a decentralized, tamper-resistant technology for recording data. It consists of a chain of data blocks, where each block contains transaction records and metadata. Every block connects to its predecessor through cryptographic hash functions, forming an ever-growing chain.
This article walks through blockchain fundamentals via implementation. First, define the block structure:
public class Block {
private String currentHash;
private String previousHash;
private String payload;
private long timestamp;
private int nonce = 0;
public Block(String payload, String previousHash) {
this.payload = payload;
this.previousHash = previousHash;
this.timestamp = System.currentTimeMillis();
this.currentHash = computeHash();
}
public String computeHash() {
String input = this.previousHash
+ Long.toString(this.timestamp)
+ Integer.toString(this.nonce)
+ this.payload;
return HashUtil.sha256(input);
}
public void proofOfWork(int difficulty) {
String target = "0".repeat(difficulty);
while (!currentHash.substring(0, difficulty).equals(target)) {
nonce++;
currentHash = computeHash();
}
}
}
Each block stores a hash computed from its data and the previous block's hash. Tampering with any block changes its hash, which breaks the chain for all subsequent blocks. This mechanism ensures data integrity.
Next, implement the hash generation utility using SHA-256:
import java.security.MessageDigest;
public class HashUtil {
public static String sha256(String input) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] rawBytes = digest.digest(input.getBytes());
StringBuilder hexBuilder = new StringBuilder();
for (byte b : rawBytes) {
hexBuilder.append(String.format("%02x", b));
}
return hexBuilder.toString();
} catch (Exception e) {
throw new RuntimeException("Hash computation failed", e);
}
}
}
The blockchain class manages the chain and validation:
import java.util.ArrayList;
import java.util.List;
public class Blockchain {
private List<Block> chain = new ArrayList<>();
private int miningDifficulty = 4;
public Blockchain() {
// Genesis block
chain.add(new Block("Genesis Block", "0"));
}
public void addBlock(String data) {
Block newBlock = new Block(data, getLatestBlock().getCurrentHash());
newBlock.proofOfWork(miningDifficulty);
chain.add(newBlock);
}
public Block getLatestBlock() {
return chain.get(chain.size() - 1);
}
public boolean validateChain() {
String target = "0".repeat(miningDifficulty);
for (int i = 1; i < chain.size(); i++) {
Block current = chain.get(i);
Block previous = chain.get(i - 1);
// Verify stored hash matches computed hash
if (!current.getCurrentHash().equals(current.computeHash())) {
System.out.println("Block " + i + ": Hash mismatch detected");
return false;
}
// Verify chain linkage
if (!previous.getCurrentHash().equals(current.getPreviousHash())) {
System.out.println("Block " + i + ": Invalid link to previous block");
return false;
}
// Verify proof-of-work completion
if (!current.getCurrentHash().substring(0, miningDifficulty).equals(target)) {
System.out.println("Block " + i + ": Mining requirement not met");
return false;
}
}
return true;
}
public static void main(String[] args) {
Blockchain myChain = new Blockchain();
myChain.addBlock("Transfer 100 coins to Alice");
myChain.addBlock("Transfer 50 coins to Bob");
System.out.println("Chain validity: " + myChain.validateChain());
}
}
The validation logic performs three checks: whether the block's stored hash matches its recomputed hash, whether the previous hash field correctly references the prior block, and whether the hash satisfies the difficulty requirement.
Running this code produces blocks with cryptographic hashes forming an unbroken chain. Any modification to historical data invalidates the chain, demonstrating how blockchain maintains immutability through distributed consensus and cryptographic linking.