How Bitcoin Actually Works Under the Hood

MH
Written by Mohamed Habbat
Estimated read time: 10 min

Every Bitcoin transaction is a tiny program. Most users never read one. You don't need to. But if you want to know what your wallet writes when you click send, this chapter opens the hood.

You can skip it and still use Bitcoin safely. Read it and you'll know why Bitcoin has no smart contract DAO hacks, why your transaction sometimes sits unconfirmed for hours, and what Taproot actually changed.

What is Bitcoin Script?

Every Bitcoin transaction carries a small program written in a language called Bitcoin Script.

Script defines the spending rule. When you send Bitcoin to someone, you don't move coins to their address. You create an output locked with a Script program that specifies the conditions for spending. To spend those coins later, the recipient must provide an input that unlocks the program.

The two parts have names. The locking program is the ScriptPubKey (or output script). The unlocking data is the ScriptSig, or in newer transaction formats, a Witness.

Bitcoin Script is stack-based. Instructions run in sequence, pushing values onto a stack and popping them off. Picture a pile of plates where you only touch the top one. Operations stay simple: push a value, check a signature, compare hashes, branch with OP_IF.

A node validates a transaction by running the unlocking script first (pushing required data onto the stack), then running the locking script. If the top of the stack ends with a non-zero value, the transaction is valid. Otherwise the node rejects it.

Your wallet writes the Script for you. You never see it. But knowing the mechanism tells you what Bitcoin transactions can and cannot do.

Common Script Patterns

Standard Bitcoin transactions use a small set of Script templates:

Pay-to-Public-Key-Hash (P2PKH). The classic address format starting with "1". The locking script says: anyone who provides a public key matching this hash and a valid signature from the corresponding private key can spend these coins. It built most historical Bitcoin transactions.

Pay-to-Script-Hash (P2SH). Addresses starting with "3". The locking script says: anyone who provides a script hashing to this value, plus inputs that satisfy that script, can spend these coins. P2SH enabled multisig and complex conditions while keeping addresses compact.

Pay-to-Witness-Public-Key-Hash (P2WPKH). SegWit addresses starting with "bc1q". Same logic as P2PKH, but the signature data moves into the witness portion of the transaction. SegWit reduced fees and fixed a longstanding malleability bug.

Pay-to-Taproot (P2TR). Addresses starting with "bc1p". The newest format. It uses Schnorr signatures and a tree structure for spending conditions. A simple spend looks identical to a complex multi-condition spend, which improves privacy.

OP_RETURN. A special output that attaches arbitrary data to a Bitcoin transaction. The standardness rule historically capped this at 80 bytes per output. Bitcoin Core 30, released 10 October 2025, raised the default -datacarriersize to 100,000 bytes. The release notes describe this as effectively uncapped, since the per-transaction standardness ceiling hits first. See the Bitcoin Core 30 release notes and CoinDesk coverage for the rationale. OP_RETURN outputs are provably unspendable. The Runes token protocol and other data-anchoring schemes use them. (Ordinals inscriptions work differently. They embed data in the Taproot witness via an OP_FALSE OP_IF envelope, not OP_RETURN.)

What are OP Codes?

OP codes (operation codes) are the individual commands in Bitcoin Script. Each does one thing.

The ones you'll see most:

OP_DUP. Duplicates the top item on the stack. The standard address script uses it to check the public key hash without destroying the public key.

OP_HASH160. Pops the top item, runs SHA-256 followed by RIPEMD-160 over it, and pushes the result. This hash function turns public keys into Bitcoin addresses.

OP_EQUALVERIFY. Checks that the top two items on the stack match. If not, the script fails on the spot.

OP_CHECKSIG. Pops a public key and a signature, verifies the signature against the transaction data, and pushes true or false. This is the fundamental "prove you own this" operation.

OP_CHECKMULTISIG. Verifies multiple signatures against multiple public keys. Requires M-of-N to succeed, where the script specifies M and N.

OP_CHECKLOCKTIMEVERIFY (CLTV). Fails the script unless the transaction's locktime is at or past a specified block height or timestamp. Time-locked outputs that nobody can spend before a certain point rely on it.

OP_CHECKSEQUENCEVERIFY (CSV). Like CLTV, but it enforces relative timelocks. The output stays unspendable until a certain number of blocks pass after creation. Lightning Network payment channels depend on it.

OP_IF / OP_ELSE / OP_ENDIF. Conditional execution. A script can offer multiple spending paths, picked at spend time by the data the spender provides.

Many OP codes from early Bitcoin were disabled after security researchers found vulnerabilities in them. Satoshi and the maintainers narrowed Script's expressiveness on purpose.

What Does "Turing Complete" Mean, and Why Isn't Bitcoin?

A Turing complete language can simulate any computation, given enough time and memory. To qualify, it must loop indefinitely and maintain arbitrary state between operations.

Ethereum's smart contract language (Solidity, running on the EVM, the Ethereum Virtual Machine) is Turing complete. It runs loops, holds state across transactions, and executes arbitrarily complex programs. To stop infinite loops from eating the network alive, Ethereum charges "gas" for every computational step. A program runs until it finishes or its gas runs out.

Bitcoin Script is not Turing complete, by design. No loops. No recursion. No persistent state between transactions. Every Script execution terminates in a bounded number of steps. This was a choice, not an artifact of early technology.

Three reasons sit behind that choice:

Predictability. Every node in the Bitcoin network validates every transaction. If Script could loop indefinitely, a single malicious transaction could halt validation worldwide, or force every node to grind through unbounded computation before deciding the transaction's fate. Bounded Script keeps validation fast no matter how exotic the transaction.

Security. Expressive languages carry larger attack surfaces. Ethereum's history is littered with smart-contract exploits, from the DAO hack in 2016 to the DeFi protocol drains that started piling up in 2020. Bitcoin Script's narrow expressiveness rules out whole classes of vulnerability before they can exist.

Consensus safety. Tens of thousands of independent nodes worldwide must evaluate Bitcoin's rules identically. External data sources, complex state, or unbounded computation would make consensus fragile. Script keeps validation deterministic and self-contained.

You pay for this with capability. Bitcoin can't run the open-ended programmable applications Ethereum supports natively. Complex financial applications, decentralised exchanges, and governance systems that need ongoing state live on other layers or other networks.

What Smart Contracts Can Bitcoin Do?

Within Script's limits, Bitcoin expresses a meaningful range of contracts:

Multisig. Require M signatures from N designated keys before funds move. A 2-of-3 multisig means any two of three key holders can authorise a transaction, but none can act alone. Corporate treasuries, inheritance setups, and custody providers run on it.

Timelock contracts. Funds stay frozen until a specified block height or time. Vesting schedules, bonds with lock-up periods, and more complex constructions all use them as building blocks.

Lightning Network payment channels. A combination of multisig and relative timelocks lets two parties transact instantly off-chain and settle only the final balance on-chain. This is the most widely deployed Bitcoin smart contract today.

Hash Time-Locked Contracts (HTLCs). The mechanism that lets Lightning payments route through intermediaries without trusting them. A payment is locked with a cryptographic secret. The recipient unlocks it by revealing the secret. Intermediaries get paid only when the secret propagates back through the chain.

Taproot script trees (MAST). Taproot commits multiple spending conditions to a hash tree. The spender reveals only the branch they actually use, keeping unused conditions private. Complex multi-path contracts leak almost nothing about the paths nobody took.

Vaults with delayed recovery. A two-transaction construction. The first transaction starts an unlock process. A second transaction, after a delay, finishes it. If the first transaction was unauthorised, a recovery key can intervene during the delay. The result behaves like a vault with a time lock.

These constructions run on the network today. They aren't whiteboard hypotheticals. They are also a lot simpler than what Ethereum's full smart-contract environment can express.

What is the Mempool?

The mempool (memory pool) holds valid, unconfirmed transactions waiting for inclusion in a block.

A Bitcoin transaction you broadcast doesn't go straight into a block. It propagates across the network, node by node. Each node checks the signature, the inputs, the format. If everything passes, the node adds the transaction to its local mempool. The transaction sits there, visible and unconfirmed, until a miner picks it up.

Miners pick transactions from the mempool by fee rate (satoshis per virtual byte). Higher fee rates jump the queue. When the mempool is nearly empty, even very cheap transactions confirm fast. When it's full, which happens during demand spikes, low-fee transactions can wait hours or days.

Each node caps its mempool size. Bitcoin Core's default is 300 megabytes. When the mempool fills up, the node drops the lowest-fee transactions to free space. Dropped transactions aren't lost forever. You can rebroadcast them. They just won't confirm until fees drop or you bump yours.

Replace-by-Fee (RBF). Bitcoin supports replacing an unconfirmed transaction with a new version that pays more fee, which bumps its priority. Modern wallets support it. If your transaction is stuck, RBF is the standard fix.

Unconfirmed transactions expire. Bitcoin Core nodes drop unconfirmed transactions from their mempool after roughly 14 days. The coins are not lost. The transaction just needs another broadcast.

Practical guidance. Check fee estimates before you broadcast. Tools like mempool.space show live mempool conditions and estimated confirmation times at each fee level. For non-urgent transactions, weekends and overnight in European time zones tend to be cheaper, since global transaction volume historically dips then.

Key Definitions

UTXO. Unspent Transaction Output. The individual "coins" that make up a Bitcoin balance.

ScriptPubKey. The locking script attached to an output. Defines who can spend it and how.

ScriptSig / Witness. The unlocking data the spender provides to satisfy the locking script.

Timelock. A Script condition that blocks spending until a specified time or block height.

PSBT. Partially Signed Bitcoin Transaction. A standardised format for sharing and co-signing transactions that need multiple parties. Multisig setups and Ordinals trading rely on it.

P2TR (Pay-to-Taproot). The current best-practice Bitcoin address format. It uses Schnorr signatures and MAST for efficient and private complex spending conditions.

Mempool. The pool of valid but unconfirmed transactions waiting for miners.

RBF (Replace-by-Fee). A mechanism that lets a sender raise the fee on an unconfirmed transaction to speed up confirmation.

Risk Note

Bitcoin Script is powerful inside its boundaries and unforgiving outside them. A script written wrong can lock coins in an output nobody can ever spend. Multisig and timelock constructions need careful planning and testing, especially around backup and recovery. Mempool fees swing hard with demand. Very low-fee transactions can sit unconfirmed for long stretches when the network is busy. Use only software you understand and trust for any non-standard Script work.

Reader Takeaway

Bitcoin Script is simple and bounded on purpose. That's what makes Bitcoin secure, predictable, and trustworthy at scale. The cost is that complex applications live on higher layers. The mempool is the staging area for every transaction. Read it well and you'll set fees intelligently. Taproot and Schnorr are Bitcoin's current frontier of expressiveness, making complex contracts both more private and cheaper.

Chapter Summary

  • Bitcoin Script is a stack-based language inside every transaction. It defines who can spend an output and under what conditions.
  • OP codes are the individual commands. OP_CHECKSIG verifies signatures. OP_CHECKLOCKTIMEVERIFY enforces timelocks. OP_IF enables conditional spending paths.
  • Bitcoin Script is not Turing complete, by design. No loops, no persistent state. Validation stays fast, predictable, and secure.
  • Bitcoin expresses real smart contracts in active use today: multisig, timelocks, Lightning payment channels, HTLCs, Taproot script trees.
  • The mempool holds unconfirmed transactions. Miners prioritise by fee rate. RBF lets senders raise fees on stuck transactions. Mempool size and fee conditions move with demand.

References

  • Antonopoulos, A. Mastering Bitcoin. O'Reilly
  • Bitcoin.org Developer Guides, Script reference
  • Bitcoin Optech newsletters: Taproot, Schnorr, MAST documentation
  • Mempool.space: live fee estimation and mempool visualisation
  • Chaincode Labs: Bitcoin Script training materials
  • Bitcoin Core documentation: mempool policies and RBF

This content is educational and does not constitute financial advice.