Skip to content

Whitepaper

Nowadays everything we do online depends on centralized solutions: banks, platforms, intermediaries that control who can send money, to whom, and under what conditions. As a computer scientist Bitcoin has always caught my attention, but I had never actually sat down to understand how it works under the hood. A fully digital, decentralized currency, with no entity controlling it, that gives you true sovereignty over your money in a world where that sovereignty is becoming increasingly rare.

That changes today. I read the Bitcoin whitepaper for the first time. If you're just getting started, I'd recommend saving this chapter, reading the whitepaper on your own, and coming back.

Intro

Bitcoin proposes replacing the trust we place in banks and payment platforms with cryptography. Instead of needing someone to certify that a transaction is valid, that validity is proven mathematically. The technical problem that had to be solved to make this possible is double spending. If money is digital, nothing stops you from copying that data and spending it twice. Satoshi's solution is the blockchain: a network of nodes that maintain a shared record of all transactions, ordered in time and sealed using proof-of-work (we'll get to that later). Modifying a past transaction would require recalculating the entire chain from that point, something that isn't viable as long as the majority of computing power is in the hands of honest nodes.

The result is a system where two people can send money directly to each other, without intermediaries, without anyone being able to arbitrarily reverse the transaction, and without needing to share more information than necessary. The network has no central server and no one administering it. Nodes join and leave freely, and consensus on which transactions are valid emerges from the chain that accumulates the most provable computational work.

Transactions

This introduction probably hasn't cleared anything up, or maybe it's made things even more confusing. But from here on we're going to understand Bitcoin for real. Like every currency, Bitcoin is used to transfer value, so that's where we'll start.

To continue you need to understand public key cryptography

In Bitcoin there's one thing you need to be clear on before moving forward: Bitcoin is not stored anywhere. There is no database where it says "Alice has 1 BTC". What exists is a public history of every transaction that has ever taken place from the very beginning.

Unspent Transaction Outputs

So how does the network know how much Bitcoin someone has? To understand it you have to forget about the concept of a balance. In Bitcoin there are no balances, there are outputs. Every time someone receives Bitcoin, what they actually receive is the output of a previous transaction pointing to their public key that hasn't been spent yet. These unspent outputs are the UTXOs, and they are the only way the network has of knowing who owns what.

Imagine Alice has received Bitcoin on three separate occasions: 0.3 BTC from Bob, 0.5 BTC from Carol and 0.4 BTC from Dave. Alice doesn't have "1.2 BTC" anywhere, she has three separate UTXOs pointing to her public key. To find out her balance you have to go through the entire history and add up all the UTXOs that have her public key as the recipient.

Each UTXO is spent in full, like a physical banknote. You can't spend half of one: if you have a 0.5 BTC UTXO and want to send 0.3, you spend the entire UTXO and send 0.2 back to yourself. If you don't, that difference goes to the miner as a fee.

How a transaction is built

transaction If Alice wants to send 0.6 BTC to Bob the process is as follows. Alice creates a transaction in which she first references the UTXOs she is going to spend, in this case the two she has: the 0.3 BTC one and the 0.5 BTC one. To reference them she uses their TXID, which is the hash of the transaction that created that UTXO and is how Bitcoin uniquely identifies transactions on the blockchain.

With the source of funds covered, Alice declares the outputs: 0.6 BTC to Bob's public key, which is recorded in the transaction as the new owner, and 0.2 BTC back to her own public key as change, because UTXOs are spent in full and she can't leave value unassigned.

Finally Alice signs the entire transaction with her private key. That signature covers everything: the inputs, the outputs and the amounts. Any node on the network can verify that signature using Alice's public key and confirm that she was the one who authorized the spend. If the signature is valid and the UTXOs hadn't been spent before, the transaction is accepted: the original UTXOs are marked as spent and two new ones are created, one pointing to Bob and one back to Alice.

Solving the double spending problem

Up until now we've been talking about transaction chains. These chains are not what we know as the blockchain, they are called ownership chains. An ownership chain tracks every transaction a bitcoin has gone through since it was created.

But there's a problem that digital signatures alone don't solve. Nothing stops Alice from building two different transactions spending the same UTXOs: one sending 0.6 BTC to Bob and another sending that same Bitcoin to Carol. Both signatures would be perfectly valid because Alice is the legitimate owner of those UTXOs. From a cryptographic standpoint, both transactions are correct. The problem isn't authenticity, it's order: only one can exist, but the network has no way of knowing which one came first.

The obvious solution would be a central entity that keeps the record and detects double spending attempts, but that brings us back to the original problem: a third party with the power to censor or reverse transactions.

Bitcoin solves this by having the entire network maintain that record publicly. Transactions are grouped into blocks, and each block includes the hash of the previous block in its header, chaining them cryptographically. Modifying a past block would invalidate its hash, which would invalidate the hash of the next one, and so on: you would have to recalculate the entire chain from that point. The first of Alice's transactions to be confirmed in a block is the valid one. The second, which tries to spend the same UTXOs, will be rejected by every node because those UTXOs are already marked as spent in the history.

The remaining problem is consensus: how does the network decide which block is valid without depending on anyone?

Proof of work

To propose a block, a node has to find a nonce such that when SHA-256 is calculated over the block header, the resulting hash is lower than a target value set by the network, which in practice means it starts with a certain number of zeros. The block header contains the hash of the previous block, the Merkle tree root of all included transactions, a timestamp and the nonce itself. Any modification to any of these fields produces a completely different hash, forcing the search to restart from scratch.

There is no shortcut to finding that nonce: the only way is brute force, iterating until you find one that satisfies the condition. Verifying it on the other hand is trivial: a single SHA-256. This asymmetry between producing and verifying is what anchors the security of the system.

The difficulty is not fixed. The network adjusts the target value every 2016 blocks, roughly every two weeks, to keep the average time between blocks around 10 minutes regardless of how much computing power joins or leaves the network. If blocks are being found too fast, the difficulty goes up. If they're being found too slow, it goes down.

Rewriting the history from a specific block would require redoing the proof-of-work for that block and every subsequent one, while the honest network keeps extending the legitimate chain ahead. The network always accepts the chain that accumulates the most computational work, not the longest one in number of blocks. An attacker trying to sustain an alternative chain would need to continuously outpace the combined computing power of all honest nodes, which is known as the 51% attack.

The Blockchain and its incentives

We now know that when a user wants to make a transaction it gets broadcast to every node on the network. Nodes collect these pending transactions into blocks, and those blocks are what form the blockchain.

Each block has two parts: the header and the body. The body simply contains the list of transactions confirmed in that block, currently around 2000-3000 per block. The header contains the metadata that makes the whole system work: the hash of the previous block, which is what chains the blocks together, the Merkle tree root, which is a hash that summarizes all the transactions in the block so that any modification to any of them invalidates it, a timestamp, the target difficulty and the nonce the miner found to satisfy the proof-of-work.

We've seen how value is transferred in Bitcoin, but not how the bitcoins being transferred are created. This is where mining comes in. A miner is a node that competes with the rest to find the valid nonce that allows it to propose the next block. When it finds one, it broadcasts it to the network and if the rest of the nodes validate it, that block gets added to the chain. The first transaction in that block is always the coinbase transaction: a special transaction with no inputs that creates new bitcoins out of thin air and assigns them directly to the miner's public key. It doesn't reference any previous UTXO because it isn't spending anything, it's the only exception in the entire protocol to the rule that every output needs an input. On top of that reward come all the fees from the transactions included in the block, which are the difference between the inputs and outputs of each transaction.

This reward is the only way new bitcoins are created in the system. No entity issues them: the protocol generates them automatically every time a valid block is added to the chain. The amount of bitcoins each block generates gets cut in half roughly every four years in an event known as the halving, which caps the total supply at 21 million bitcoins. Once that limit is reached, miners will only earn transaction fees.

This mechanism aligns miners' incentives with the integrity of the network. A miner that tried to include fraudulent transactions would see their block rejected by the rest of the nodes, losing all the energy spent on the proof-of-work with nothing to show for it. But there's something more important: an attacker controlling 51% of the network's computing power, enough to rewrite the history, would make more money simply mining honestly than trying to attack it. The system is designed so that destroying it is less profitable than maintaining it.

The Merkle tree

Inside each block there are thousands of transactions. To be able to reference all of them in the header with a single hash, Bitcoin uses a structure called a Merkle tree.

The way it works is straightforward: each transaction is taken and its hash is calculated. Those hashes are then combined in pairs and the result is hashed again. The process repeats until a single hash remains, called the Merkle root, which is the one included in the block header. If any transaction in the block is modified, its hash changes, which changes the hash of its pair, which changes the hash of the level above, and so on until the entire root is invalidated.

merkle-tree This has a very important practical consequence: it allows you to verify whether a specific transaction is in a block without having to download the whole thing. Instead of downloading all the transactions, you only need the branch of the tree that connects your transaction to the root, just a few hashes. You calculate the path upwards and check that the result matches the Merkle root in the header. If it matches, the transaction is there.

This is what the whitepaper calls Simplified Payment Verification or SPV. A light node, like the one in a mobile wallet, doesn't need to store the entire blockchain to verify that a transaction was confirmed. It only needs the block headers, which are 80 bytes each, and the corresponding Merkle branch. With that it can prove that its transaction is included in a valid block without depending on anyone to confirm it.

The tradeoff is that an SPV node trusts that the network is controlled by honest nodes. It can't verify transactions by itself, only check that they're included in the longest chain. If the network were dominated by an attacker, it could be fooled. That's why businesses that receive frequent or high value payments run their own full nodes: independent verification, no compromises.

Calculating the probability of generating a fraudulent chain

How many blocks do I need to wait to be sure my transaction can't be reversed?

Alice pays Bob. Bob sees the transaction on the network but Alice could be secretly building an alternative chain where that transaction doesn't exist, to get her money back once Bob has shipped the product. Satoshi models this as a race between two chains, exactly the mathematical problem known as the Gambler's Ruin.

He defines p as the probability that the honest network finds the next block and q as the attacker's, where p + q = 1. The attacker starts z blocks behind because the transaction already has z confirmations. If q ≥ p the probability of catching up to the honest chain is 1, the attacker always wins eventually. That's why 51% is the critical threshold. If q < p the probability is (q/p)^z, which drops exponentially with each confirmation.

The problem is that this assumes the attacker hasn't mined anything yet, which isn't realistic. In practice they've been mining their alternative chain in secret from the start. How far they've gotten follows a Poisson distribution with expected value λ = z × (q/p). The full equation sums over all possible states of the attacker, combining the Poisson with the probability of catching up from each point.

\[ 1 - \sum_{k=0}^{z} \frac{\lambda^k e^{-\lambda}}{k!} \left(1 - (q/p)^{(z-k)}\right) \]

Let's translate this equation into Python:

import numpy as np

def attacker_success_probability(q: float, z: int) -> float:
    p = 1.0 - q
    lam = z * (q / p)
    total = 1.0
    for k in range(z + 1):
        poisson = np.exp(-lam)
        for i in range(1, k + 1):
            poisson *= lam / i
        total -= poisson * (1 - (q / p) ** (z - k))
    return total

for z in [0, 1, 2, 3, 4, 5, 10]:
    print(f"z={z}: q=0.10 → {attacker_success_probability(0.10, z):.7f} | q=0.30 → {attacker_success_probability(0.30, z):.7f}")

attacker-success-probability

With a 10% attacker five confirmations bring the probability below 0.1%. With a 30% attacker you need 24. That's why exchanges require more confirmations than an online store.

Conclusion

This chapter is my starting point in the world of Bitcoin. I've tried to explain the whitepaper the way I understood it.

There's one topic we haven't covered that deserves its own chapter: privacy. Bitcoin is pseudonymous, not anonymous. All transactions are public and traceable, which has serious implications if you care about financial privacy. I know Monero solves this and it's something I'll definitely be diving into down the line.

transaction

Satoshi's original whitepaper describes a system that is brilliant in its simplicity, but I'm aware that Bitcoin has evolved a lot since 2008. Layers have been built on top of it, like the Lightning Network for instant payments, and the community keeps expanding its functionality. There's a lot more to explore.

support with btc <3

wallet-qr