Understanding Bitcoin Inscriptions & Commit-Reveal Transactions

Aug 9, 2024

As part of our of ongoing initiative at Surge to enrich and strengthen Bitcoin’s developer community we built a free open-source Bitcoin Playground containing a bunch of tools to help developers ideate, test and build on Bitcoin.

One of our key tools; the Bitviper Bitcoin Wallet just got it’s biggest update - the ability to directly inscribe ordinals onto our testnet. Committing to build in public, we're putting out our code as well as some of the decisions we've taken whilst building this feature, so let's jump right in.

What are Ordinal & Inscriptions?

Bitcoin Inscriptions are a way to embed data, such as text or images, directly into the Bitcoin blockchain. This innovation has sparked a new wave of creativity and applications on Bitcoin.

Ordinals are a numbering scheme for satoshis (the smallest unit of Bitcoin) that allows for the tracking and transfer of individual satoshis. This scheme enables the concept of "Bitcoin NFTs" by associating unique data with specific satoshis.

How inscriptions work on Bitcoin

Bitcoin Inscriptions use a two-step process involving Commit and Reveal transactions. This approach is necessary due to Bitcoin's script size limitations and to optimize for efficiency.

  • The Commit transaction prepares the groundwork for the inscription.

  • The Reveal transaction actually contains the inscription data.

Commit-reveal transactions in Bitcoin ordinal inscriptions ensure privacy and prevent front-running by concealing the actual inscription details until the reveal phase.

Let's assume without commit-reveal, Alice directly includes her inscription details in a single transaction. Bob, monitoring the network, sees Alice's transaction and quickly creates a similar inscription, broadcasting it with a higher fee to get it confirmed first. As a result, Bob's inscription is recorded on the blockchain before Alice's, effectively front-running her and potentially stealing her original idea or content.


Next, let’s breakdown each of the 2 key steps in this transaction

The Commit Transaction

The Commit transaction sets up the structure for the inscription without actually including the content. Key aspects include:

  • Creating an inscription script that includes placeholders for the content.

  • Utilizing Pay-to-Taproot (P2TR) for the output, which allows for more complex scripts.

  • Generating a taproot script tree and address that will be used in the Reveal transaction.

In the provided code, the createCommitTxData function handles this process:

export function createInscriptionScript(
  xOnlyPublicKey: Buffer,
  inscription: Inscription
) {
  const protocolId = Buffer.from(encoder.encode('ord'))
  return [
    xOnlyPublicKey,
    bitcoinjsLib.opcodes.OP_CHECKSIG,
    bitcoinjsLib.opcodes.OP_0,
    bitcoinjsLib.opcodes.OP_IF,
    protocolId,
    1,
    1,
    inscription.contentType,
    bitcoinjsLib.opcodes.OP_0,
    ...chunkContent(inscription.content),
    bitcoinjsLib.opcodes.OP_ENDIF,
  ]
}

export function createCommitTxData(
  network: bitcoinjsLib.Network,
  publicKey: Buffer,
  inscription: Inscription
): CommitTxData {
  const xOnlyPublicKey = toXOnly(publicKey)
  const script = createInscriptionScript(xOnlyPublicKey, inscription)

  const outputScript = bitcoinjsLib.script.compile(script)

  const scriptTree = {
    output: outputScript,
    redeemVersion: 192, // 0xc0
  }

  const scriptTaproot = bitcoinjsLib.payments.p2tr({
    internalPubkey: xOnlyPublicKey,
    scriptTree,
    redeem: scriptTree,
    network,
  })

  const cblock = scriptTaproot.witness?.[scriptTaproot.witness.length - 1]

  const tapLeafScript = {
    leafVersion: scriptTaproot.redeemVersion!,
    script: outputScript,
    controlBlock: cblock!,
  }

  return {
    script,
    scriptTaproot,
    outputScript,
    tapLeafScript,
  }
}

This function creates the necessary scripts and generates the taproot address that will be used to send the bitcoin that will carry the inscription.

The Reveal Transaction

The Reveal transaction actually embeds the inscription data into the blockchain. Key components include:

  • Using the output from the Commit transaction as an input.

  • Including the full inscription data in the witness part of the transaction.

  • Finalizing the transaction with a custom finalizer to properly structure the witness data.

The createRevealTx function in the provided code handles this:

export async function createRevealTx(
  network: bitcoinjsLib.Network,
  commitTxData: CommitTxData,
  commitTxResult: any,
  toAddress: string,
  amount: number
) {
  const { scriptTaproot, tapLeafScript } = commitTxData

  const psbt = new bitcoinjsLib.Psbt({ network })

  psbt.addInput({
    hash: commitTxResult.txId,
    index: commitTxResult.sendUtxoIndex,
    witnessUtxo: {
      value: commitTxResult.sendAmount,
      script: scriptTaproot.output!,
    },
    nonWitnessUtxo: commitTxResult.tx.toBuffer(),
    tapLeafScript: [tapLeafScript],
  })

  psbt.addOutput({
    value: amount,
    address: toAddress,
  })
  return psbt
}

This function constructs the Reveal transaction, signs it, and prepares it for broadcast to the Bitcoin network.

The key technical concepts in this process include:

  • Taproot scripts: A more flexible and privacy-enhancing way to create Bitcoin scripts.

  • Witness data: Additional data included in SegWit transactions, allowing for more complex scripts without increasing the base transaction size.

  • PSBT (Partially Signed Bitcoin Transactions): A format for creating and working with transactions that may require multiple signatures or complex signing procedures.

Importance of Commit and Reveal in Ordinals.

The Commit and Reveal process offers several benefits:

  • Security: By splitting the process into two transactions, it becomes harder for others to front-run or manipulate the inscription process.

  • Efficiency: The two-step process allows for optimizing the use of block space, potentially reducing fees.

  • Compatibility: This approach works within Bitcoin's existing script system, requiring no protocol changes.

The Commit and Reveal process is fundamental to how Bitcoin Inscriptions work. It showcases the flexibility of Bitcoin's script system and opens up new possibilities for embedding data on the Bitcoin blockchain. As the Ordinals ecosystem continues to evolve, we may see even more innovative uses of this technique.


Inscribe your own ordinal on Bitviper

Before you go, explore our signature Bitcoin wallet Bitviper (on our custom signet) with inscriptions baked right in. Inscribe an ordinal, explore it's footprint and test all its other features. For any assistance do reach out to us on our Telegram group and we'll help you to the best of our abilities.

Written by

Written by

Surge Devs

Surge Devs

About Surge:

Surge is a modular Rollup-as-a-Service (RaaS) built for Bitcoin. Rollups built on Surge are high-performance, customizable and can be tailored for app-specific use cases. With the help of it's novel intermediary SuperStack layer, transactions settle directly on Bitcoin's secure & reputable L1 via inscriptions.

Learn more about us

: