Bitcoin mining is a lottery where each ticket is a hash. Miners repeatedly hash an 80-byte block header, changing a few fields each time, until the double SHA-256 of that header is numerically at or below a target. Whoever finds such a header first gets to add their block to the chain and collect the reward. The work proves nothing about the transactions. What it does is make rewriting history expensive.
What actually gets hashed
A miner never hashes the whole block. It hashes the block header, which is always 80 bytes:
| Field | Size | What it is |
|---|---|---|
version | 4 bytes | Block version, also used for soft-fork signalling |
prev_block_hash | 32 bytes | Hash of the previous block's header |
merkle_root | 32 bytes | Root of the Merkle tree of all transactions in the block |
time | 4 bytes | Unix timestamp, loosely constrained |
bits | 4 bytes | Compact encoding of the current target |
nonce | 4 bytes | A free counter the miner changes |
Because prev_block_hash is inside the header, every block commits to the full history before it. Because merkle_root is inside the header, changing any transaction changes the header hash.
You can check this yourself with the genesis block:
import hashlib, struct
def header_hash(version, prev_hash, merkle_root, timestamp, bits, nonce):
# Hashes are displayed big-endian but serialized little-endian
header = (
struct.pack("<I", version)
+ bytes.fromhex(prev_hash)[::-1]
+ .fromhex(merkle_root)[::-]
+ struct.pack(, timestamp, bits, nonce)
)
(header) ==
hashlib.sha256(hashlib.sha256(header).digest()).digest()[::-].()
():
exponent, mantissa = bits >> , bits &
mantissa * ** (exponent - )
h = header_hash(
version=,
prev_hash= * ,
merkle_root=,
timestamp=,
bits=,
nonce=,
)
(h)
((h, ) <= bits_to_target())