Site's logo

KL, MY

7:30:00 AM

A Headstone with an inscription by Dora Taylan Bilek on Pexels

How Bitcoin Inscriptions Really Work: Taproot, Commit-Reveal, and a Full Technical Walkthrough

A clear technical guide to Bitcoin inscriptions: Taproot, commit-reveal, data size, validity, and a full regtest coding example.

December 8, 2025

10 min read

While Bitcoin was originally designed simply as a peer-to-peer value transfer system, recent developments have enabled a very different use-case: embedding arbitrary data into single satoshis (the smallest unit of Bitcoin). This is possible via the combination of the so-called Ordinal Theory and the protocol layer mechanism called inscriptions.

Ordinal Theory (popularised by Casey Rodarmor) assigns a unique serial number to each satoshi based on the order in which it was mined and subsequently transferred.

Ordinals themselves don’t change Bitcoin’s consensus rules or the fungibility of sats at the protocol level — they’re a social layer layer. They simply provide a way to identify and track individual satoshis.

Inscriptions are the mechanism by which arbitrary data (text, images, audio, etc.) is embedded on-chain into a satoshi. The data is stored in the witness/script path of a transaction output (thanks to Taproot and witness-discount mechanics) so that once inscribed, the data is immutable and tied to that satoshi.

GitHub AlstonChan/bitcoin-inscriptions

How exactly do inscriptions work?

Bitcoin inscriptions follow a two-phase process—the commit phase and the reveal phase—to embed arbitrary data into a satoshi. This often confuses most people at first, so let’s walk through what these phases actually mean.

Why two phases?

When you inscribe something, you first send bitcoin to a specially-constructed address. This initial transaction:

  • looks like a normal transfer
  • contains no inscription data
  • is just funding a UTXO that can later reveal the data

So if the transaction has no data, how does the receiving address know what you want to inscribe?

Because the address itself encodes the inscription, not the transaction.

That’s the key insight.

Commit Phase — When the Address is the Inscription

The address you send bitcoin to is not standard. It is:

  • For P2WSH: a hash of a script
  • For P2TR (Taproot): a key with an optional script tree (MAST) committed into it

In both cases, the script contains the inscription envelope.

This script is hashed → the hash becomes your address → you fund that address.

Nothing is revealed yet because Bitcoin only stores hashes of scripts, not the script itself.

This is why:

  • The first transaction contains no inscription data
  • The address is what holds the inscription data
  • The address will be created after you type in the content you want to inscribe.This is because the Taproot output key commits to a script tree that includes your envelope; changing the content changes the script hash, which changes the address.
  • Each inscription uses a one-time address, since the script is unique per inscription (unless you inscribe the exact same content again with the same parameters/private key)
  • This is what is referred to as the commit.

The Inscription Envelope

The inscription data is embedded directly into the script with an OP_FALSE / OP_IF no-op branch:

OP_FALSE
OP_IF
OP_PUSH "ord"
OP_PUSH 1
OP_PUSH "text/plain;charset=utf-8"
OP_PUSH 0
OP_PUSH "Hello, world!"
OP_ENDIF

A few important points:

  • The OP_FALSE ensures the OP_IF branch never executes
  • The envelope does not affect script execution (it is a no-op). This ensures that the script remains valid and standard, while still allowing arbitrary data to be committed and later revealed.
  • Taproot removes the 10,000-byte script size limit for Tapscript and applies a witness discount, which makes embedding larger inscription envelopes more practical.
  • Because the script is hashed, the content is private until reveal

At this stage, the inscription is hidden and committed, but not yet on-chain.

Reveal Phase — When the Script Is Published On-Chain

To finalize the inscription, the special address needs to spend its UTXO.

Spending via the script path forces the script to be revealed. The full script (including the inscription envelope) is placed in the witness stack.

This reveal transaction includes, inside the witness:

  1. The initial stack argument (can be a dummy, or e.g., a tweak key). This value is not part of the inscription data — it’s only there to satisfy the script path evaluation rules.
  2. The entire script (containing the ordinal envelope)
  3. The control block (specifying where the script lives in the MAST)

This is the moment the inscription is visible on-chain.

After reveal, Ordinals Theory determines which satoshi in the input/output flow receives the inscription.

I randomly pick an example from mempool.space to show the input/output structure of a reveal transaction:

Ordinals Inscription input output
Ordinals Inscription input output

Why the Address Is Single-Use

Because:

  • the script = your inscription data
  • the address = hash(script)

Different inscriptions produce different scripts → different addresses for the same private key.

So each inscription address:

  • is generated in real time
  • is used exactly once to commit
  • cannot be reused (unless you want identical inscriptions)

This is normal and expected.

Summary in One Breath

  1. You create a unique Taproot address whose script contains your inscription data (commit).
  2. You send sats to it — this transaction looks normal.
  3. Later, the address spends the UTXO and reveals the script in the witness (reveal).
  4. The revealed script contains the inscription data.
  5. Ordinals Theory assigns that inscription to a specific satoshi.

That’s how all inscriptions work.

Bitcoin inscription implementation with bitcoinjs-lib

If you’d like to see a complete, fully working Taproot commit-reveal inscription flow — including:

  • building the inscription script
  • generating the Taproot address from it
  • funding the commit transaction
  • constructing and finalizing the reveal transaction
  • broadcasting both on regtest

You can explore the repository here:

GitHub AlstonChan/bitcoin-inscriptions

Frequently Asked Questions (FAQ)

1. How does provenance (parent/child linkage) work?

Ordinals provenance is used to express parent ↔ child relationships between inscriptions (like a collection). You create a parent→child link by embedding the parent reveal TXID (encoded little-endian) into the child reveal transaction and by proving ownership of the parent UTXO in that same transaction.

Key points and the required transaction layout:

  • Linking: To declare that inscription B is a child of inscription A, include the reveal TXID of A (little-endian) inside the child reveal transaction. Indexers read that pointer and interpret the relationship. Example: parent_txid_reveal → little-endian bytes pushed into the child script.

  • Forgery protection (why anyone can’t just fake a link): If the child transaction only contains a raw parent TXID, anyone could paste any TXID and fraudulently claim a link. Ordinals conventions therefore require the child reveal tx to also spend the parent inscription’s UTXO (or otherwise prove ownership). That is, the reveal tx must include the parent UTXO as an input so the indexer can verify the spend relationship.

  • Practical tx layout (minimum): child reveal txs that establish provenance typically have at least two inputs and two outputs:

    1. vin[0] — the parent inscription UTXO (spent to prove you control the parent).

      vout[0] — the corresponding output that continues the parent inscription or returns its satoshi (keeps pointer semantics).

    2. vin[1] — a new funding input used to create the child inscription.

      vout[1] — the child inscription output (the one whose script will be revealed and contain the child envelope and the little-endian parent TXID pointer).

The ordering matters: indexers expect the parent spend/return to occupy the first vin/vout slots so they can deterministically identify which satoshi counts as the parent and which satoshi receives the child.

  • Indexers enforce the convention when resolving provenance. If you omit the parent UTXO proof or place the pointer in the wrong position, the link will be ignored or the child may be treated as standalone.

  • Example flow: To make B a child of A:

    1. Locate the reveal TXID of A and encode it little-endian.
    2. Construct a reveal transaction that spends the UTXO from A as vin[0] and returns that satoshi (or an agreed output) as vout[0].
    3. Include your child script (with the little-endian A_txid pointer) in the reveal witness for vout[1] while funding it from vin[1].
    4. Broadcast — indexers will read vout[1]‘s script and link B → A after validating the parent UTXO spend.

This pattern allows building collections (A → B, A → C, A → D, …) while preventing arbitrary parties from claiming parentage without proving control of the parent UTXO (Example transaction).

Ordinals Inscription 64228106 interface
Ordinals Inscription 64228106 interface

2. How can I reduce the size of my inscription data?

You can significantly reduce reveal transaction size by compressing your inscription data with Brotli before encoding it as hex inside the script.

How it works:

  • Take the raw content (image / JSON / text / etc.).
  • Compress it using Brotli level 11 (or your preferred settings).
  • Convert the compressed bytes to hex.
  • Insert the hex into the Taproot script envelope.

Important notes:

  • The content type stays the same (e.g., image/png, text/plain, etc.).
  • Indexers know to decompress Brotli payloads automatically when reading inscription content.
  • The Taproot reveal transaction still carries the full payload, but compressed data = fewer vbytes.
  • You must also set the Content-Encoding tag (Tag 9) in the inscription envelope to brotli. This tells indexers and browsers to decompress the data before rendering.

This is currently the most effective way to reduce inscription costs.

3. Are Bitcoin Ordinals a standard? Are they part of Bitcoin?

No — Ordinals are not part of the Bitcoin protocol or any BIP standard.

This has several implications:

  • Bitcoin nodes do not track inscriptions.
  • Bitcoin consensus does not recognize “special” satoshis.
  • To a Bitcoin wallet, an inscribed satoshi is just a regular sat.
  • There is no consensus rule requiring anyone to preserve or care about inscriptions.

The inscription data:

  • lives in the witness stack,
  • does not belong to any address,
  • and is not transferred by Bitcoin itself.

Ordinal indexers (like ord) apply their own social rules to track which satoshi “carries” an inscription. This tracking is entirely off-chain logic, not part of Bitcoin’s consensus.

In other words:

Your wallet sees ordinary sats (wallet that don’t supports ordinals inscription). The Ordinals indexer sees digital artifacts. Bitcoin doesn’t care either way.

This distinction is important for understanding why inscriptions are a layer on top of Bitcoin, not a native feature of Bitcoin itself.

Conclusion

Bitcoin inscriptions may look mysterious at first, but the underlying mechanism is simple once you understand Taproot:

  • Commit: Create a Taproot address whose script contains your data.
  • Reveal: Spend that address, exposing the script in the witness.
  • Assign: Ordinals Theory tracks which satoshi receives the inscription.

Everything else in the ecosystem—from marketplaces to provenance standards—is simply a social layer built on top of these three fundamental primitives.

GitHub AlstonChan/bitcoin-inscriptions