Blockchain 0x100 – Developing the Core Blockchain Structure
If you are into Web3 development, the term blockchain is not a new thing to you. In the last blog post of this series, I explained most of the core concepts behind how a blockchain works. Learning the theory is a good start. But it only gets you so far. To really understand blockchains, you have to build one yourself.
So guys, in this tutorial, I’m starting a long journey. Yes, as the title says, we’re going to build a blockchain. No Ganache, no external networks. We’re building one completely from scratch, in Java.
Creating the Block Class
We learned a lot of deep concepts in the previous tutorial, but for now, let’s keep things simple. The most basic element of a blockchain is the block. The entire chain is just a sequence of these blocks linked together.
So, what kind of data does a block need to hold?
From our previous discussion, a block needs to store a timestamp, data, nonce, and hashes. Recall the following diagram.

Let’s start by creating a Block class in Java. Here’s the structure of it:
public class Block {
private String data;
private int nonce;
private int difficulty;
private long timestamp;
private String hash;
private String prevHash;
}
So what's going on here? Each block needs to store a few key pieces of information.
- data - holds whatever information we want to record (transactions, messages, anything!)
- timestamp - tells us when the block was created
- prevHash - stores the hash of the previous block (this creates the "chain" in blockchain)
- hash - this block's unique fingerprint
- nonce and difficulty - work together to make mining possible (we'll explain this soon)
Now properties are done. We need some methods for the class. Please not that I'm not going to show the getters for these properties as the code gets much larger if I do so. When you are implementing this from your own you might need to add them.
We need a way to calculate a block’s unique hash. The hash acts as an immutable fingerprint for the block.
public String calculateHash() {
String dataToHash = data + nonce + difficulty + timestamp + prevHash;
this.hashString = StringUtil.applySha256(dataToHash);
return hashString;
}
What’s happening here? We’re taking all the block’s properties, combining them into one long string, and then running it through a SHA-256 hashing algorithm.
If even one character of data changes, the resulting hash will be completely different. This is what gives blockchains their immutability. If anyone tries to modify a block, its hash won’t match anymore, and the entire chain becomes invalid.
Now let's talk about mining. Mining is what makes blockchain secure. It requires computational work to add a new block, which makes it really hard for attackers to mess with the chain. Here's our mining method:
public void mineBlock() {
String target = "0".repeat(difficulty);
nonce = 0;
hashString = calculateHash();
while (!hashString.startsWith(target)) {
nonce++;
hashString = calculateHash();
}
System.out.println("Block Mined! Hash: " + hashString);
}
What’s happening?
We’re searching for a hash that starts with a certain number of leading zeros. this is our Proof of Work. The number of zeros is determined by the difficulty.
Each time we change the nonce and recalculate the hash until it matches the target. Once it does, the block is considered “mined.”

Block Constructor
Here’s the constructor that ties everything together.
public Block(String data, int difficulty, String prevHash) {
this.data = data;
this.difficulty = difficulty;
this.prevHash = prevHash;
this.timestamp = Instant.now().toEpochMilli();
mineBlock(); // Mine the block
}
Every time a new block is created, we mine it before it gets added to the chain.
Mining ensures that adding a block requires computational effort, making the blockchain expensive to tamper with — you’d have to re-mine every block after the modified one to fake the chain successfully.
Building the Blockchain Class
Now that our Block class is ready, it’s time to build the Blockchain itself. The system that manages and connects all blocks.
We’ll store all blocks in an ArrayList, starting with a Genesis Block, which is the very first block in the chain.
public class Chain {
private final int difficulty = 4;
private final ArrayList<Block> blockchain = new ArrayList<>();
public Chain() {
blockchain.add(new Block(0, "Genesis Block", difficulty, "0"));
}
}
That’s our starting point. The Genesis Block is created manually and doesn’t link to any previous block.
Now, let’s add a method to create and append new blocks to our chain.

This method takes new data, links it to the last block using the previous hash, and mines it before adding it to the chain.
public Block getLatestBlock() {
return blockchain.get(blockchain.size() - 1);
}
public void addBlock(String data) {
Block newBlock = new Block(blockchain.size(), data, difficulty, getLatestBlock().getHashString());
blockchain.add(newBlock);
}





