How Does Proof of Work Actually Work in Practice?

By Kurt Wuckert Jr.

To see proof of work in practice, it helps to look at a specific block and walk through what the miner actually does. Take block 550204 as an example. It contains two transactions. Each transaction is serialized into raw bytes, then hashed twice with SHA-256 to produce its transaction ID, or TXID. Those TXIDs become the leaves of a small Merkle tree for that block.

From there, the TXIDs are paired, concatenated and double-hashed to create interior nodes, and finally a single Merkle root that represents all the transactions in the block. That Merkle root is one of the key fields placed into the block header that miners hash in their proof of work process.

Endianness and the Merkle Root

When you look at TXIDs and Merkle roots in a block explorer, they are usually shown in big-endian form, which is the conventional way to read hex numbers. Internally, however, much of the Bitcoin code uses little-endian order, where bytes are stored in reverse.

This means that if you take TXIDs from a block explorer and want to reconstruct the Merkle root yourself, you first reverse the byte order of each TXID before concatenating and hashing them. The same applies to the Merkle root that you place into the block header. For humans this byte reversal can be confusing, but for hardware and low level software it is more efficient to work in little endian. Those small gains matter when the system is designed to handle very high transaction throughput.

Constructing the Block Header

Once the Merkle root is known, the miner assembles the block header. The header is 80 bytes long and includes:

  • Version

  • Previous block hash

  • Merkle root

  • Timestamp

  • nBits (the compact representation of the difficulty target)

  • Nonce

Values are converted into the correct binary and endianness, then concatenated into a single 80-byte string. This header is what the miner will hash twice with SHA-256 when attempting to solve the proof of work puzzle.

From nBits to the Target

The field called nBits is a compact way to encode the current difficulty target. Internally, this 4-byte value is split into two parts:

  • The first byte acts as an exponent or index.

  • The remaining three bytes form a coefficient or mantissa.

The node software converts nBits from its displayed decimal form into hexadecimal, then interprets the first byte as the index and the next three bytes as the coefficient. Using a simple formula, it reconstructs a full target number from these two pieces. That target is the upper bound that any valid block hash must be below.

You do not need to do the full math by hand to understand the idea. The important point is that the network stores a very large target as a compact 4-byte field, and miners must find a header hash whose numeric value is less than that target.

Trying Nonces and Checking Hashes

With the header assembled and the target known, the miner starts making attempts. For each attempt:

  1. The miner takes the 80-byte header.

  2. It runs SHA-256 on that header twice in a row to get a 32-byte hash.

  3. It interprets that hash as a large integer.

  4. It checks whether that integer is less than the target derived from nBits.

If the hash is higher than the target, the attempt fails. The miner then changes one of the header fields and tries again. The simplest field to change is the nonce, a 4-byte value at the end of the header. Incrementing the nonce by one usually changes only one byte in the header, but because hash functions are highly sensitive to input changes, the output hash will look completely unrelated to the previous one.

In the case of block 550204, the first attempt at hashing the header produced a value larger than the target. That means the proof of work condition was not satisfied. The miner then incremented the nonce and hashed again. The second attempt produced a hash with many leading zeros in its hexadecimal representation, which corresponds to a much smaller numerical value.

When you convert that second hash to a number and compare it with the reconstructed target, it is lower, which means the proof of work requirement has been met.

A Valid Proof of Work

Once a header hash is found that lies below the target, the miner has a valid proof of work for that block. The Merkle root in the header ties the proof of work to a specific set and order of transactions. The previous block hash links it into the existing chain. The nBits and timestamp tie it to the current difficulty period and time.

In the next stage, the miner will broadcast this candidate block to the network. Other nodes can independently verify the block by:

  • Recomputing the Merkle root from the listed TXIDs.

  • Rebuilding the header in the same little-endian format.

  • Applying double SHA-256 to the header.

  • Deriving the target from nBits.

  • Confirming that the hash is indeed below the target.

If all these checks pass and the transactions themselves are valid, the nodes accept the block and extend their local view of the chain. Future miners will reference this block’s hash in their own headers as they search for the next proof of work solution.

Proof of Work ELI 5(ish...)

Proof of work is basically a giant lottery that proves you did real computing work.

  • First, the miner builds a block header. It includes a summary of all the block’s transactions (the Merkle root), the previous block’s hash, the time, the difficulty setting (nBits), and a nonce, which is just a number they are allowed to change.

  • From nBits, the software calculates a “target” number. To win, the miner has to find a hash of the header that is smaller than this target.

  • The miner then keeps changing the nonce and hashing the 80-byte header with SHA-256 twice. Each tiny change in the header gives a totally different random-looking hash.

  • Almost every hash is too big, so it fails. Once in a while, one hash ends up below the target. That is the winning ticket.

  • When a miner finds such a hash, they broadcast the block. Other nodes quickly check the math and confirm that the hash really is below the target and that the transactions are valid. If it all checks out, the block gets added to the chain.