public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Rusty Russell <bitcoin-dev@rustcorp•com.au>
To: bitcoindev@googlegroups.com
Cc: Julian Moik <julianmoik@gmail•com>
Subject: [bitcoindev] [4/4] New Opcodes for Tapscript v2
Date: Sat, 27 Sep 2025 20:59:40 +0930	[thread overview]
Message-ID: <87tt0om8uz.fsf@rustcorp.com.au> (raw)
In-Reply-To: <87y0q0m8vz.fsf@rustcorp.com.au>

Hi all!

    Now for the least polished BIP, which proposes a scattering of new
opcodes.  These need not be deployed at the same time, and some may not
ever qualify.  But as they they might have interactions with other
proposals, I feel we are obligated to peer over this horizon a little.

    Many of these are not mine, and I definitely feel remiss in not
giving canonical references (I would appreciate this feedback!).

Thank you for you consideration!
Rusty.

<pre>
  BIP: ?
  Layer: Consensus (soft fork)
  Title: New Opcodes for Tapscript v2
  Author: Rusty Russell <rusty@rustcorp•com.au>
  Comments-URI: TBA
  Status: Draft
  Type: Standards Track
  Created: 2025-06-17
  License: BSD-3-Clause
</pre>

==Introduction==

===Abstract===

This BIP proposes several new opcodes for tapscript v2, to take full advantage of scripting enhancements and covenant facilities offered by OP_TX.

===Copyright===

This document is licensed under the 3-clause BSD license.

===Motivation===

Restoration of opcodes and introspection make script much more useful, and thus increase the range of things we may want to do.  This, in turn, highlights some existing shortfalls in Script, both in the way it handles multiple stack objects, and when attempting to reproduce modern Taproot constructions.

This list of opcodes is not exhaustive, but each offers some significant capability which was previously impossible or extremely awkward in script.

A key motivation for these changes lies in future possible BIPs: once script is well-rounded (if not "complete"), most proposals will be optimizations, whose benifits can be quantitatively assessed based on actual usage.

==New Opcodes==

;OP_CHECKSIGFROMSTACK
: A subset of OP_CHECKSIG.  With OP_TX and OP_SHA256 we have the part of CHECKSIG which obtains and hashes parts of the transaction.  What remains is being able to check a signature against a hash on the stack.  OP_CHECKSIGFROMSTACK provides this.  The varops cost is the same as a CHECKSIG operation.

;OP_SEGMENT
: This opcode remains an NOP.  But it makes script parts ''composable'': currently you cannot append two scripts, because OP_SUCCESS causes immediate success without script evaluation.  OP_SEGMENT changes this rule to ''segment'' the script into parts, which are evaluated in order.  If a segment does not have OP_SUCCESS, that part of the script is evaluated.  This allows a transaction to ensure some condition is met, but also allow arbitrary script conditions thereafter.

;OP_BYTEREV
: This is the minimium requirement for constructing ordered Merkle trees as specified in Taproot.  Unfortunately, hashes need to be compared left to right, where Script opcodes operate right to left (as per little endian numbers).  Alternatives would be a direct OP_REVCMP opcode, or even a dedicated Merkle opcode, but byte reversal can be generally useful.

;OP_ECPOINTADD
: Also required for constructing Taproot spends.  The varops cost is the same as a CHECKSIG operation.

;OP_INTERNALKEY
: An optimization: an unspendable keypath for Taproot simply wastes space.  If this is not changed in a future version, OP_INTERNALKEY at least allows the script to use this data for something else.  An alternative would be another OP_TX ''selection_vector'' bit.  See [[bip-0349.mediawiki|BIP-349]].

;OP_MULTI
: Several opcodes would benefit from a variant which takes the number of operands off the stack.  Instead of introducing many more opcodes, we propose OP_MULTI as a prefix to the following opcode which pops a number off the stack, and makes the next opcode operate on more than its usual number of operands: OP_CAT, OP_ADD, OP_SHA256, OP_DUP, OP_DROP, OP_MIN, OP_MAX, OP_AND, OP_OR, OP_BOOLAND, OP_BOOLOR, OP_EQUAL.  This is simpler than introducing general iteration into script, and intuitive to constrain using varops.  It is particularly beneficial when examining inputs or outputs of a transaction, such as calculating fees.

===Rationale===

Bitcoin script was developed long before Taproot: OP_ECPOINTADD and OP_BYTEREV are the minimal missing opcodes required for creating Taproot trees in script.  The need for OP_CHECKSIGFROMSTACK and OP_SEGMENT are a side-effect of generic introspection, into the tx itself for arbitrary signature coverage, and into scripts to allow specification of partial spending requirements.  OP_INTERNALKEY is trivial, but can save 32 weight on a transaction in many cases, which is a non-trivial savings.  OP_MULTI is more complex, but allows for much more general handling of multiple inputs or outputs: bitcoin script does not have iteration, so all possible numbers have to be handled directly, which is unwieldy at best.

There are definitely other opcodes which would be helpful, but from this point most are "merely" optimizations from what is now possible.  This itself is a major milestone: that future opcode proposals can be assessed numerically, by measuring the impact they would have on aggregate onchain space, and from there assessing whether the cost of implementation and deployment is worth the savings.

===Detailed Specification===

TBA.

==Reference Implementation==

None as yet.

==TODO==

- Are there other fundamental building blocks we are missing?  I don't see an immediate reason for OP_ECPOINTMUL, for example, but it would not be possible in script today (due to varops limits).
- If we do want OP_INTERNALKEY, it should probably be a OP_TX selector bit.
- Is OP_MULTI too ambitious?  I previously considered for-each-input and for-each-output iterators, but this is far simpler.
- Can we come up with a better name for OP_CHECKSIGFROMSTACK?  Unfortunately OP_CHECKSIG is taken, but OP_THE_REAL_CHECKSIG isn't!


== Footnotes ==

<references />

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/87tt0om8uz.fsf%40rustcorp.com.au.


      reply	other threads:[~2025-09-27 13:23 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-27  8:12 [bitcoindev] [0/4] A Bitcoin Scripting Proposal BIP Quartet Rusty Russell
2025-09-27 11:27 ` [bitcoindev] [1/4] Varops Budget For Script Runtime Constraint Rusty Russell
2025-09-27 11:28   ` [bitcoindev] [2/4] Restoration of disabled script functionality (Tapscript v2) Rusty Russell
2025-09-27 11:29     ` [bitcoindev] [3/4] OP_TX Rusty Russell
2025-09-27 11:29       ` Rusty Russell [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87tt0om8uz.fsf@rustcorp.com.au \
    --to=bitcoin-dev@rustcorp$(echo .)com.au \
    --cc=bitcoindev@googlegroups.com \
    --cc=julianmoik@gmail$(echo .)com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox