Learn Computing from the Experts | The Rheinwerk Computing Blog

Blockchain Creation: Chaining Blocks Basics

Written by Rheinwerk Computing | Nov 15, 2024 2:42:45 PM

Before you build your own blockchain, let’s clarify what information is needed in the blocks. To do this, create a models/Block.java file and start with the Block class.

 

In each block, enter the magic number that belongs to your blockchain. In this case, the magic number is an attribute of the Integer data type. In addition, a block has a size in bytes, and since only whole bytes need to be filled, you can use an integer here as well.

 

Of course, you need a block header; a block can’t exist without a block header, so you must always create a new block header in the constructor of the block. The code below shows the constructor of a block. Since a block header always contains the timestamp of the time when the miner started the block creation, the block header can be created directly with the timestamp.

 

public Block(byte[] previousHash){

   this.blockSize = 92; //80 Byte Blockheader + 3*4 Byte fur Attribute

   this.transactions = new ArrayList<>();

   this.transactionCount = this.transactions.size();

   this.blockHeader = ↩

       new BlockHeader(System.currentTimeMillis(), previousHash);

}

 

As can be seen, the block requires two more attributes: the number of transactions and the list of transactions. Since the size of the block increases with the number of transactions, whenever you add a new transaction, you also need to update the size of the block. Each transaction is 128 bytes in size in your blockchain with the data types we specified, so always add 128 to the previous size. The next code shows that when you add a transaction, the block header must also be updated because another transaction changes the hash of the transaction list. In addition, the transaction counter must be updated.

 

The block includes other methods besides the getter and setter methods to pass through information on the block header. You need a method that returns the hash of the block or the block ID. However, the block ID is not an attribute on its own but a synonym for the hash of the block header.

 

public void addTransaction(Transaction transaction) {

   this.transactions.add(transaction);

   this.transactionCount++;

   this.blockHeader.setTransactionListHash(getTransactionHash());

   this.blockSize += 128;

}

 

Block Height and Coinbase: In the Bitcoin blockchain, there are other attributes within blocks (e.g., block height, coinbase). However, these attributes are not mandatory for the current state of your blockchain.

 

Now that you can create and use blocks including block headers and transactions, all you need is the chain itself. For this, you create the Chain class in the models/Chain.java file.

 

The Chain class is very simple and has very few attributes. It only needs a network ID and a list of blocks. Unlike the other IDs of a blockchain, the network ID is just an attribute of the Integer data type. This ID allows you to offer multiple networks of the same blockchain—for example, a production network and a test network. At this stage, you can use a simple ArrayList to store the blocks, but you’ll soon need a list that allows concurrent accesses to the chain, which is why we recommend using a CopyOnWrite-ArrayList.

 

Now, you can put your transactions into blocks and link these blocks into a chain, but this information resides exclusively in your node’s memory. Therefore, next, you need to take care of the persistent storage of your blockchain.

 

Editor’s note: This post has been adapted from a section of the book Blockchain: The Comprehensive Guide to Blockchain Development, Ethereum, Solidity, and Smart Contracts by Tobias Fertig and Andreas Schütz.