Building Layer 1 blockchain from scratch (PART — II Core Blockchain & Mining)
This part is in continuation of part 1
In this second part, we’ll focus on building the core blockchain, where we’ll manage transactions, create blocks, and link them to form a chain.
Environment:
Python Version: 3.11.6
Operating System: Linux Ubuntu
Database: LevelDB (from the previous part)
Blockchain (Class)
In Part 1, we created a simple wallet to generate key pairs, sign transactions, and interact with our blockchain. In this part, we will build the core structure of our blockchain. We’ll cover how transactions are collected, blocks are created, and how these blocks are linked together to form a blockchain.
Code:
1. Importing Required Modules
from typing import Dict, Optional
import json
#Custom Modules
from db import add_transaction as add_tx_to_db, get_latest_state_trie_root
# from p2p import publish
from mine import mine
typing
: Provides type hints (Dict
,Optional
) for better code readability and error checking.
2.Blockchain Class Initialization
FILE_NAME = "block.json" #This file is used later to store the blocks
class Blockchain:
def __init__(self):
self.transactions = []
self.blocks = []
self.block_number = 0
- The
Blockchain
class is initialized with an empty list of transactions, an empty list of blocks, and a block number starting at zero.
3. Adding a Transaction
def add_transaction(self, transaction: Dict[str, str]) -> Optional[str]:
txn_key = add_tx_to_db(transaction)
if txn_key:
self.transactions.append(transaction)
# Check if we have 10 transactions, then create a block
if len(self.transactions) == 10:
self.create_block()
return txn_key
return None
transaction
is passed from the wallet code where we built the message.- The transaction is first saved to the database using
add_tx_to_db
. - If the transaction is valid and successfully added, it is appended to the
self.transactions
list. - Once the number of transactions reaches 10,
create_block
is automatically called to create a new block.
4. Creating a Block
def create_block(self):
self.block_number += 1
# mine function returns the nonce and root.
nonce,root = mine(get_latest_state_trie_root())
block = {
'block_number': self.block_number,
'data': self.transactions,
'nonce': nonce,
'root':root,
'state_root':get_latest_state_trie_root()
}
self.blocks.append(block)
with open(FILE_NAME, "w") as file:
json.dump(block, file, indent=4)
# publish(FILE_NAME)
self.transactions.clear()
create_block
: Handles the creation of a new block when 10 transactions are accumulated.mine
: Mines the block, generating anonce
and updating the root based on the latest state trie.- Block storage: The block is saved to a JSON file and also appended to the
self.blocks
list. - Transaction reset: After the block is created, the
self.transactions
list is cleared to prepare for the next set of transactions. #publish
this is where we use P2P connections to publish our block but it is not implemented yet.
Mining
Refer to code here
import hashlib
def mine(latest_root: str) -> (int, str):
nonce = 0
hash_input = latest_root.encode()
while True:
hash_result = hashlib.sha256(hash_input).hexdigest()
if hash_result.startswith("000"):
return nonce, hash_result
nonce += 1
hash_input = hash_result.encode()
print(hash_result)
The mine
function accepts a string latest_root
, representing the root of the latest block or data to be mined. It initializes a nonce
at 0 and encodes the latest_root
into bytes. The function then enters an infinite loop where it computes the SHA-256 hash of the hash_input
, checks if the resulting hash starts with "000" (a simple proof-of-work condition), and if so, returns the current nonce
and the valid hash_result
.
If the condition is not met, the nonce
is incremented, and the hash_input
is updated to the current hash result, with the process repeating until a valid hash is found. The loop also prints each hash as it iterates.
This code exemplifies the fundamental concept of mining, where the goal is to find a nonce
that produces a hash satisfying a specific condition, illustrating the proof-of-work mechanism in a straightforward manner.
🏁 Conclusion and What’s Next
In this part, we built a simple blockchain, covering key aspects like transaction management, block creation, and mining. This foundational knowledge sets the stage for exploring more advanced blockchain features in the future parts of this series.
In the next part we will dive into the data base operations of our blockchain