Every Bitcoin transaction contains two pieces of code. One locks the funds. The other unlocks them. Most people who use Bitcoin have never seen either — and for routine transactions, you don't need to. But understanding how this works matters if you want a clear picture of what Bitcoin can and can't do at the protocol level.
The locking and unlocking mechanism is called Bitcoin Script. It's a scripting language, but a deliberately minimal one. It doesn't work like Solidity or Python. There are no loops, no recursion, no persistent state. That isn't a limitation the developers forgot to fix — it's a structural choice with specific tradeoffs.
Bitcoin's ledger is built around UTXOs — Unspent Transaction Outputs. When you receive bitcoin, what you actually receive is a UTXO: a record that says "X amount of BTC, locked under these conditions." When you spend it, you broadcast a transaction that satisfies those conditions.
The conditions are expressed in Script.
Each UTXO carries a locking script (called scriptPubKey). This defines what's required to spend the funds. When someone wants to spend a UTXO, they provide an unlocking script (called scriptSig in legacy formats, or a witness in SegWit). The two scripts are evaluated together by every validating node. If the evaluation succeeds, the spend is permitted.
Script runs as a stack machine. Execution works by pushing and popping values from a stack — no variables, no branching based on state, no loops. When the two scripts run together, opcodes execute sequentially, manipulating the stack until a valid result emerges or the script fails.
The most common script type — P2PKH (Pay to Public Key Hash) — illustrates the pattern clearly.
The locking script says: "To spend this output, provide a public key that hashes to [this hash], and a signature valid against that key."
The unlocking script provides: the public key, and the signature.
The validator checks: does the public key hash to the expected value? Does the signature verify? If both pass, the UTXO is spent.
That's the entire mechanism. The stack handles execution; the opcodes do the verification.
Bitcoin doesn't require every transaction to define a custom script. In practice, a small set of standard templates handle nearly all activity:
P2SH and P2TR share an important design principle: complexity is hidden until it's needed. The UTXO stays compact, the conditions are only revealed at spend time. This is why multisig wallets using P2SH are indistinguishable from single-sig addresses until they actually move funds.
Bitcoin Script is intentionally not Turing-complete. No loops, no recursion, no unbounded execution.
This is a security constraint, not an oversight. A Turing-complete language can produce infinite loops or arbitrarily expensive execution paths. In a distributed network where every validating node independently verifies every transaction, that creates an obvious attack vector: submit a script that never terminates and you can potentially halt nodes. Ethereum solves this with gas — every opcode has a cost, execution halts when the budget runs out. Bitcoin chose a different path: eliminate the problem class entirely by limiting what Script can express.
The consequence is predictable, bounded execution. Every Bitcoin script terminates. Every node processes it in bounded time. The tradeoff is expressive power — Bitcoin Script can't replicate arbitrary smart contract logic. That constraint is load-bearing.
One opcode worth knowing: OP_RETURN. Any output prefixed with OP_RETURN is immediately marked unspendable. The output can't be spent under any conditions.
This sounds like it would be useless, but it's how arbitrary data gets written to the Bitcoin blockchain. The output is provably unspendable, so nodes don't need to keep it in the UTXO set — they can prune it. The data is still permanently recorded in the chain.
OP_RETURN is used for timestamping, token protocol metadata (Omni Layer, RGB), and — contentiously — for Ordinal inscriptions embedded via Taproot witness data.
Opcode availability. The opcode set is limited by design, and some opcodes that existed in early Bitcoin were disabled in 2010 due to potential exploits. OP_CAT — which concatenates stack items — is the prominent example. Re-enabling it or adding new opcodes requires a soft fork with broad community consensus, which means changes are slow. This isn't a technical barrier; it's a governance and security tradeoff.
Script standardness. Bitcoin Core nodes will only relay "standard" transaction types by default. Non-standard scripts can technically be included by miners, but most nodes won't forward them across the network. This creates a practical filter on what's deployable, even when the protocol technically permits more.
UTXO set economics. Complex scripts that create large or numerous UTXOs impose ongoing costs on every full node. This is part of why P2SH and P2TR's approach — hiding complexity until spend time — was considered an improvement over alternatives that would have expanded UTXO set overhead.
Taproot adoption is the most structurally significant recent development. Schnorr signatures, which Taproot relies on, enable key aggregation: multiple participants can produce a single signature indistinguishable from a single-key signature. For multisig setups, this has meaningful privacy and fee implications. Taproot activated in November 2021, but wallet and infrastructure support has rolled out gradually. As of early 2026, Taproot is used in a minority of transactions — adoption is real but not dominant.
Miniscript — a policy language that compiles to Bitcoin Script — reached full integration in Bitcoin Core 26.0 (late 2023). It lets developers express complex spending conditions in a higher-level language and formally verify their properties before deployment. Miniscript doesn't expand what Script can do; it makes reasoning about correctness much more tractable.
OP_CAT is the active debate. BIP-347 proposes re-enabling it via a soft fork. If activated, OP_CAT would enable script introspection and covenant constructions — scripts that can constrain how their outputs are subsequently spent. This is a meaningful capability expansion: vaults, improved Lightning channel factories, and certain stateful protocol designs become possible. The community debate is ongoing; no activation timeline exists as of early 2026.
OP_CAT BIP-347 reaching rough consensus and activation signaling. Taproot transaction share continuing to grow. Schnorr-based PTLC migration in Lightning implementations progressing. Miniscript-based wallet tooling moving into production at major custodians.
A Script vulnerability allowing a malformed script to crash or exploit validating nodes. A cryptographic flaw found in Schnorr signature verification. Prolonged stalemate on OP_CAT leading to covenant development moving off-chain or to other protocols. Developer attention consolidating around higher-layer solutions that work around Script's constraints rather than extending them.
Now: Taproot-compatible infrastructure is deploying; Miniscript tooling is live. These are active developments worth tracking if you're building on Bitcoin or evaluating wallet security models. Next: OP_CAT debate likely resolves within 12–18 months — either activation or explicit rejection, both of which carry implications for covenant-based protocols. Later: Covenant applications (vaults, channel factory improvements) are conditional on OP_CAT or equivalent opcode availability; treat them as later-stage until activation is credible.
This post explains Bitcoin Script as a protocol mechanism — how locking and unlocking scripts work, what the standard templates are, and where the constraints live. It doesn't constitute guidance on writing Script directly or evaluating specific wallet implementations. The tracked signals and thresholds live elsewhere.
Bitcoin Script defines the conditions under which bitcoin can move. Whether any particular expansion of that system is desirable is a separate question, and one the network is actively debating.




