Skip to content

Instantly share code, notes, and snippets.

@RobinLinus
Created May 14, 2026 09:23
Show Gist options
  • Select an option

  • Save RobinLinus/f1ee5daddacc25e138a768aef0a918ea to your computer and use it in GitHub Desktop.

Select an option

Save RobinLinus/f1ee5daddacc25e138a768aef0a918ea to your computer and use it in GitHub Desktop.
  BIP: 447
  Layer: Consensus (soft fork)
  Title: OP_TEMPLATEHASH2
  Author: Robin Linus <roblinus@stanford.edu>
  Status: Draft
  Type: Specification
  License: CC0-1.0

Abstract

This document proposes a new operation for Tapscript: OP_TEMPLATEHASH2. It introduces the ability to push on the stack a hash of a designated co-input of the transaction spending an output.

Motivation

BIP 446 OP_TEMPLATEHASH allows a Tapscript to commit to the spending transaction's outputs. However it deliberately does not commit to the transaction's inputs: committing to all prevouts and scriptpubkeys would introduce a hash cycle when the hash is embedded in the output itself, require hashing a quantity of data quadratic in the number of inputs, and prevent spending two coins encumbered by a template hash check in the same transaction1.

OP_TEMPLATEHASH2 fills this gap. It commits to a single designated co-input2 of the spending transaction without committing to the outputs. This avoids the hash cycle (the commitment is to a different coin's outpoint, not to the transaction's own outputs), avoids quadratic hashing (only one input is committed), and permits spending multiple coins encumbered by OP_TEMPLATEHASH2 in the same transaction (they all reference the same co-input).

Together, OP_TEMPLATEHASH and OP_TEMPLATEHASH2 provide complementary transaction commitment: one constrains the outputs, the other constrains an input. The co-input holder controls the remaining degrees of freedom (output selection and fee rate) through a regular signature.

A concrete application is connector outputs in BitVM bridges. A deposit output can require that a specific connector UTXO is spent as a co-input, with a BIP 68 relative timelock encoded in its sequence number. This eliminates the need for a presigning committee, makes deposits non-interactive, and allows additional inputs for fee-bumping.

Specification

OP_TEMPLATEHASH2 redefines OP_SUCCESS207 (0xcf) in the Tapscript execution context with further restrictions.

Upon execution of the opcode, the template hash of the transaction in context is pushed onto the stack as defined below, and script execution continues.

The template hash uses a tagged hash as introduced by BIP 340 and BIP 341. We use a new tag for this purpose: TemplateHash2.

The template hash re-uses the sha_annex pre-computed transaction data introduced in BIP 341. Numerical values in 4-byte are encoded in little-endian.

The co-input is always the first input of the spending transaction (index 0).

The template hash is the hashTemplateHash2 of the following transaction fields concatenated:

  • Transaction data:
    • nVersion (4): the version of the transaction.
    • nLockTime (4): the locktime of the transaction.
  • Data about this input:
    • annex_present (1): as defined in BIP 341 (0 if no annex is present, or 1 otherwise).
  • Data about the co-input (first input):
    • outpoint (36): the COutPoint of the co-input (32-byte txid followed by 4-byte output index).
    • nSequence (4): the sequence number of the co-input.
  • If an annex is present:
    • sha_annex (32): the SHA256 of the annex of this input, as per BIP 341.

Rationale

The design of OP_TEMPLATEHASH2 mirrors that of BIP 446 OP_TEMPLATEHASH. Where OP_TEMPLATEHASH follows the field selection of a SIGHASH_DEFAULT signature (committing to all outputs and all sequences), OP_TEMPLATEHASH2 follows the field selection of a SIGHASH_ANYONECANPAY|SIGHASH_NONE signature (committing to a single input and no outputs). The same adaptation approach is applied in both cases: the hash_type field is omitted (the input is fixed), spend_type is replaced by the bare annex_present bit, and BIP 341 pre-computed sub-hashes are reused where applicable. This results in at most 81 bytes being hashed upon execution of the operation3. As with a SIGHASH_ANYONECANPAY signature in BIP 341, input_index is not committed. Since no field varies across inputs, the resulting hash is identical for every input in the transaction. This means the hash can be computed once and cached, making the cost of multiple OP_TEMPLATEHASH2 executions in the same transaction negligible.

The specific fields that differ from a SIGHASH_ANYONECANPAY|SIGHASH_NONE BIP 341 signature message are the following:

  • hash_type: as with OP_TEMPLATEHASH, the input is fixed so there is no need for a mechanism to modify the hash composition.
  • spend_type: as with OP_TEMPLATEHASH, we commit directly to annex_present since no extension is appended.
  • amount: the amount of the co-input is not committed. The same rationale as OP_TEMPLATEHASH's omission of sha_amounts applies: the utility of committing to the spent amount without also committing to the spent scriptpubkey is limited, and the flexibility of not committing to the amount is desirable for recovery from mistakes4. Furthermore, not committing to the amount avoids making overcommitted funds permanently unspendable.
  • scriptPubKey: the scriptpubkey of the co-input is not committed. Committing to it would prevent changing the co-input's encumbrance without also changing every output that references it, reducing flexibility without a clear security benefit.
  • input_index: as in a SIGHASH_ANYONECANPAY BIP 341 signature, the input index is not committed. The co-input is identified by its outpoint rather than its position. This also ensures the hash is identical for every input in the transaction, enabling it to be computed once and cached.

The co-input is fixed as the first input (index 0) for simplicity. This is sufficient because OP_TEMPLATEHASH2 commits to the co-input's outpoint, which uniquely identifies the coin. As with a SIGHASH_ANYONECANPAY signature in BIP 341, input_index is not committed. Since no field varies across inputs, the hash is identical for every input in the transaction. This means all inputs encumbered by OP_TEMPLATEHASH2 can use the exact same expected hash in their scripts, the hash can be computed once and cached by the verifier, and inputs can be freely reordered without invalidating the hash5.

The outputs are deliberately unconstrained (SIGHASH_NONE semantics). Output selection and fee-rate choice are delegated to a signature on the co-input, typically using SIGHASH_DEFAULT. This separation of concerns allows the co-input holder to choose outputs at spend time while the OP_TEMPLATEHASH2 encumbrance ensures that the co-input must be present.

Committing to nVersion is important when OP_TEMPLATEHASH2 is used to enforce BIP 68 relative timelocks via the co-input's nSequence: without committing to nVersion, a version 1 transaction could satisfy the co-input commitment while ignoring BIP 68 entirely6.

As with OP_TEMPLATEHASH, this opcode is only defined for Tapscript. The same rationale applies: modifying legacy Script comes with an unnecessarily increased risk surface, and Tapscript's OP_SUCCESS upgrade hooks make it possible to push the template hash on the stack instead of being constrained to strict assertions.

As with OP_TEMPLATEHASH, this opcode commits to the Taproot annex (or its absence). Deviating from other operations which do commit to the annex would be unnecessary and surprising.

Backward compatibility

This document proposes to give meaning to a Tapscript OP_SUCCESS operation. The presence of an OP_SUCCESS in a Tapscript would previously make it unconditionally succeed. This proposal therefore only tightens the block validation rules: there is no block that is valid under the rules proposed in this BIP but not under the existing Bitcoin consensus rules. As a consequence these changes are backward-compatible with non-upgraded node software. That said, the author strongly encourages node operators to upgrade in order to fully validate all consensus rules.

Copyright

This document is licensed under the Creative Commons CC0 1.0 Universal license.

Footnotes

  1. See the rationale section of BIP 446 for a detailed discussion of why OP_TEMPLATEHASH does not commit to input prevouts, scriptpubkeys, or amounts.

  2. The "co-input" is the input that must accompany the input being spent. It is always the first input of the transaction (index 0). The term reflects its role as a required companion input.

  3. If no annex is committed, 49 bytes are hashed: 8 bytes of transaction data + 40 bytes of co-input data + 1 byte of data about this input. Committing to an annex adds 32 additional bytes of data about this input, bringing the total to 81.

  4. It is possible to commit to an underfunded co-input. The co-input holder can correct this by choosing appropriate outputs in their signature. Not committing to the amount preserves this flexibility.

  5. In a connector output construction, multiple deposit outputs each contain an OP_TEMPLATEHASH2 check. They can all be spent in a single transaction because they all reference the same co-input at index 0. This enables efficient batched processing of deposits.

  6. BIP 68 relative timelocks are only enforced when the transaction version is 2 or higher. A template creator using OP_TEMPLATEHASH2 to enforce a BIP 68 delay should set nVersion to 2 (or higher) in the committed template. The hash commitment to nVersion then ensures the spending transaction cannot downgrade to version 1 to bypass the timelock.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment