latest-tech5 min read

Blockchain Tutorial: Learn Distributed Ledger from Scratch (2026)

Blockchain Tutorial: Learn Distributed Ledger from Scratch (2026)

Published:  |  Category: Latest Tech  |  Reading time: ~15 min
Blockchain Tutorial: Learn Distributed Ledger from Scratch (2026)

When I first encountered blockchain in 2017, it felt like peeking at the early internet — raw, contentious, and full of promise. After building several distributed ledger prototypes and one production supply-chain system, I can tell you the core idea is simpler than the hype suggests: a shared, append-only log that nobody owns alone.

This tutorial strips away the noise. You will build a minimal blockchain from first principles, understand consensus without a white paper, and learn why proof-of-work is both genius and wasteful. By the end, you will know exactly when — and when not — to reach for a blockchain.

What Makes a Blockchain Tick

A blockchain is a linked list of blocks where each block contains a cryptographic hash of the previous one. This simple link makes the entire history tamper-evident: change one byte in block 3, and block 4's hash no longer matches. The chain breaks visibly.

Every block also carries a timestamp, a nonce (for mining), and a payload of transactions. Nodes in the network each hold a full copy of the chain and vote on which fork is canonical using a consensus rule. The most common rule in public chains is the longest valid chain — the one that required the most cumulative work.

import hashlib, json, time

class Block:
    def __init__(self, index, previous_hash, transactions, nonce=0):
        self.index = index
        self.timestamp = time.time()
        self.transactions = transactions
        self.previous_hash = previous_hash
        self.nonce = nonce
        self.hash = self.compute_hash()

    def compute_hash(self):
        block_string = json.dumps(self.__dict__, sort_keys=True)
        return hashlib.sha256(block_string.encode()).hexdigest()

Proof-of-Work: The Costly Gatekeeper

Proof-of-work prevents anyone from rewriting history on a whim. To propose a new block, a miner must find a nonce such that the block's hash starts with a certain number of leading zeros. This trial-and-error search consumes compute resources — a deliberate friction that makes tampering economically unappealing.

The difficulty adjusts so that the average time between blocks stays roughly constant (10 minutes for Bitcoin, ~15 seconds for a toy chain). In practice, you start with difficulty 4 (target hash starts with '0000') and tweak from there. The beauty is that verification remains instant even though mining is slow.

def mine_block(block, difficulty):
    target = '0' * difficulty
    while block.hash[:difficulty] != target:
        block.nonce += 1
        block.hash = block.compute_hash()
    print(f'Block mined: {block.hash}')
    return block

Transactions and the Mempool

Before transactions land in a block, they live in a staging area called the mempool (memory pool). Each node validates incoming transactions against its UTXO set — the unspent outputs that define who owns what. A transaction consumes some UTXOs as inputs and creates new UTXOs as outputs, ensuring total value is conserved.

Miners then select transactions from the mempool, prioritizing those with higher fees. This auction-based inclusion is where the economics get real: during congestion, users bid against each other for block space. The protocol itself does not set fees — the market does.

class Transaction:
    def __init__(self, sender, recipient, amount, fee=0):
        self.sender = sender
        self.recipient = recipient
        self.amount = amount
        self.fee = fee
        self.txid = hashlib.sha256(f'{sender}{recipient}{amount}{fee}'.encode()).hexdigest()

mempool = []
def add_transaction(tx):
    if tx.amount > 0:
        mempool.append(tx)
        mempool.sort(key=lambda t: t.fee, reverse=True)

Consensus and Fork Resolution

When two miners find valid blocks at nearly the same time, the network forks temporarily. Each node adopts the first valid block it sees, but keeps the other candidate on standby. The fork resolves when the next block is mined on top of one branch — the longer chain wins, and the orphaned block's transactions return to the mempool.

This probabilistic finality means a transaction is never instantly final. Best practice waits for N confirmations (blocks built on top of the block containing the tx). For Bitcoin-sized difficulty, 6 confirmations (~1 hour) is the conventional threshold for irreversibility.

class Blockchain:
    def __init__(self, difficulty=4):
        self.chain = [self.create_genesis()]
        self.difficulty = difficulty

    def create_genesis(self):
        return Block(0, '0' * 64, ['genesis'], nonce=0)

    def add_block(self, block):
        block.previous_hash = self.chain[-1].hash
        mine_block(block, self.difficulty)
        self.chain.append(block)

Wallets, Keys, and Signatures

Owning cryptocurrency means holding a private key — a 256-bit integer that you must keep secret. The corresponding public key is hashed to produce an address. When you send value, your wallet signs the transaction with your private key using ECDSA (Elliptic Curve Digital Signature Algorithm). Anyone can verify the signature using your public key without knowing your private key.

Hierarchical deterministic (HD) wallets derive a tree of keys from a single seed phrase, so you can back up an entire wallet with 12 or 24 words. This is BIP-32/39 in practice and is the standard across nearly every modern wallet.

from ecdsa import SigningKey, SECP256k1

private_key = SigningKey.generate(curve=SECP256k1)
public_key = private_key.get_verifying_key()

def sign_tx(tx_hash, private_key):
    return private_key.sign(tx_hash.encode()).hex()

def verify_tx(tx_hash, signature, public_key):
    return public_key.verify(bytes.fromhex(signature), tx_hash.encode())

When Not to Use a Blockchain

The most important lesson I learned the hard way: a blockchain is a terrible database. It is slow (single-digit TPS for public chains), expensive (every write costs fees), and public by default. If your use case involves a single trusted party, high throughput, or private data, a plain database with audit logs is strictly better.

Blockchain shines only when multiple mutually distrusting parties need to agree on shared state without a central coordinator. Think supply chains with competing vendors, inter-bank settlement, or decentralized identity. For everything else, use PostgreSQL and move on.

# Anti-pattern: storing large files on-chain
# DO NOT do this:
# block.transactions.append(open('video.mp4', 'rb').read())

# Instead: store a hash on-chain, the file off-chain
# block.transactions.append({'file_hash': sha256(file_bytes), 'url': 'https://s3.amazonaws.com/bucket/video.mp4'})

Frequently Asked Questions

What is the difference between a blockchain and a distributed database?

A blockchain is append-only, permissionlessly verifiable, and achieves consensus among untrusted parties. A distributed database (like Cassandra) assumes a trusted coordinator and prioritizes speed and consistency within a controlled cluster. Blockchain sacrifices throughput for trustlessness.

Is proof-of-work the only consensus algorithm?

No. Proof-of-stake (used by Ethereum post-merge), delegated proof-of-stake (EOS), practical Byzantine fault tolerance (Hyperledger), and proof-of-authority (private networks) are all viable alternatives with different trade-offs in security, energy use, and decentralization.

How long does it take to mine a block in this tutorial?

With difficulty 4 and Python, expect 2–10 seconds per block on a modern CPU. Adjust difficulty up (more zeros) or down to control block time. For production, you would use ASIC hardware or switch to proof-of-stake entirely.

Can I modify a block after it is added to the chain?

You can, but the change will break every subsequent block's hash link. To make the chain valid again, you must re-mine all following blocks, which requires the combined hashrate of the network — practically impossible on a well-secured public chain after a few confirmations.

Originally published on Ayodhyyya. Last updated June 1, 2026.