OP_CC: A simple introspection opcode to enable cheaper consolidations

Hello everyone,

I want to share an idea for a new Tapscript opcode that makes consolidation transactions significantly more space-efficient: OP_CHECKCONSOLIDATION (OP_CC).

It’s a simple introspection opcode: OP_CC pushes false for the first transaction input spending a particular scriptPubKey, and true for every subsequent input spending the same scriptPubKey. This enables a construction where all inputs spending the same SPK rely on the signature for the first input with that SPK.

A simple example:

  • We create a Taproot SPK (“address”) with a known key-path and a single Tapscript leaf of just OP_CC.
  • Now assume we have three UTXOs with that SPK and we want to spend all of them in the same transaction.
  • The first UTXO is unlocked with a simple key-path spend. It’s crucial that the signature commits to all inputs and outputs (SIGHASH_ALL).
  • The second and third UTXOs are unlocked with the OP_CC script-path spends. No signatures are required.

We save 58 witness bytes compared to spending all three UTXOs via key-path spends:

  • Key-path witness size (per input): signature length (1), signature (64) → 65 bytes
  • Script-path witness size (per input): script length (1), script (1), control block length (1), control block (33) → 36 bytes

And that’s just a simple example. The savings are much greater for n<m multisigs, and greater still in a post-quantum world with much larger signatures.

I made a draft implementation to explain the idea using code and unit tests.

I’ll post to the ML as well after collecting some initial feedback here on Delving.

Looking forward to your feedback.

1 Like

Hi, this is probably a non-starter because it would encourage address reuse which has always been something we are trying to avoid. Also, you would get the same savings with Cross-Input Signature Aggregation of Schnorr signatures plus a lot more possible upside. I am a bit biased because I am working on it. And I am not very deep into the post-quantum stuff yet but for that scenario there is already a proposal called OP_CIV by Tadge Dryja that shares some similarities with your as well but is more flexible: https://groups.google.com/g/bitcoindev/c/oFbEQb_DB3I

1 Like

@fjahr:

it would encourage address reuse which has always been something we are trying to avoid

Yes, undeniably. OP_CC is a simple way to increase the economic bandwidth of the base layer without increasing block size. We’re seeing address reuse today, indicating that the privacy implications are bearable for many actors. And it’s an opt-in feature.

Also, you would get the same savings with Cross-Input Signature Aggregation of Schnorr signatures plus a lot more possible upside.

I’m not opposed to CISA! Clarifying question: For n<m multisigs using OP_CHECKSIGADD, wouldn’t it still be necessary to reveal the script including the pubkeys in the witness? With OP_CC, the leaf script for repeated SPKs is a single byte.

Also, I’m not sure CISA is realistic for quantum signatures.

there is already a proposal called OP_CIV by Tadge Dryja that shares some similarities

Yep, I’m aware. However, @adiabat concedes his proposal does not save space vs. EC sigs. See https://youtu.be/cqjo3rmd6hY?t=1154. Moreover, I think OP_CC is much easier for wallets to implement.

Something similar can be achieved with OP_CHECKCONTRACTVERIFY (CCV). I’m a bit rusty on the exact parameters, but in the simplest form you would have a taptree with a single leaf that requires that all value flow to output0 of the same spk with no signatures. This would enable signatureless consolidation with external fee payment. A UTXO using this construction would also be spendable with the key spend as normal to any destination.

cc @salvatoshi

1 Like

@reardencode: I think you’re correct in the sense that OP_CCV supports consolidations with the following input parameters:

  • mode: CCV_MODE_CHECK_OUTPUT
  • taptree: -1 (current input taptree merkle root)
  • pk: -1 (current input internal key)
  • index: 0 (first output)
  • data: empty

The problem is that the consolidation transaction can only roll value forward into the same contract. To pay a third party (new SPK), you need a second transaction spending the consolidated output.

I think that’s what people usually call a ‘consolidation’ transaction, so perhaps OP_CHECKCONSOLIDATION might be confusing for readers if the goal is more like a ‘delegation’ (that is: one UTXO delegate the authorization for spending to other UTXOs)

You can have a scriptPubKey-based delegations with a script like:

  CCV_MODE_CHECK_INPUT
  -1  # no taptweak
  <delegatee_pk>
  0  # first input
  <>  # no data tweak
  CHECKCONTRACTVERIFY

So this says “Everything goes as long as the first input is tr(<delegatee_pk>)”. However, this Script is still 38 bytes, so this kind of delegation with CCV is probably useful to save bytes only if the delegatee_pk is spent with a rather large Script.

A delegation “to itself” (for example, checking that the first input has the same Script as the current input being spent), while expressible with CCV, would indeed not be safe as it would be tautologically true for the first input. So I think you are correct that OP_CCV does not implement your proposal.

This seems backwards.

Privacy is a common good. If individuals, for whatever reason, take actions that hurt their own privacy, they are transitively also worsening privacy for everyone they interact with. The public nature of a blockchain means that any information revealed by anyone worsens the situation for everyone.

We can’t prevent people from reusing addresses, or otherwise leaking information. But we (we being the collective of Bitcoin users that jointly decide the system’s rules) can incentivize that behavior (through changes like the ones you propose here) or disincentivize it (through CISA, e.g., as it means CoinJoins slightly cheaper than individual transfers).

In any case, you shouldn’t use the fact that some participants choose to give up their privacy as evidence that it’s desirable to incentivize it for everyone.

3 Likes

If consolidation transactions took up less block space, more block space would remain for everyone, including users who do not want to reuse addresses.

In any case, you shouldn’t use the fact that some participants choose to give up their privacy as evidence that it’s desirable to incentivize it for everyone.

@sipa, I didn’t. I see the tradeoff and I made an empirical observation about on-chain data without value judgement. The scalability benefits outweigh the privacy implications in my opinion.

It only benefits whose who engage in undesirable behavior - I don’t see why you’d want to reward them for it.

Bitcoin was designed to have some level of transaction linking privacy. If its users didn’t care about it, protocol designers should be aiming to move towards an account-based system, which naturally gives better scalability at the cost of not caring about revealing identity.

2 Likes

Sure, but all we really care about is bytes not transactions. Using OP_CCV uses 5 extra bytes per consolidated input, plus a 1-input, 1-output transaction compared to OP_CC. It is a bit more expensive, but still much cheaper than current consolidations. The OP_CCV-style could be broadcast as a TRUC transaction using package relay, so it wouldn’t even need a separate fee input if the consolidated output is spent immediately.

1 Like

CISA incentivizes all transactions with multiple inputs. This includes transactions that do not require coordination and all inputs belong to the same user.

Archive
1 Like

Is CISA realistic with quantum signatures?

In case you are looking for more opinions, financially incentivizing address reuse is a non-starter, and I sincerely doubt that this idea has any chance of adoption.

For what it’s worth, i think this could be of use as a sibling proposal to Tadge’s OP_CIV, as a poor-man’s signature aggregation scheme for post quantum signatures.

Though, unlike OP_CIV or my proposed alternative, OP_CC requires committing publicly to the exact same address for it to be used when spending. I think if you were gonna go this route, you’d want to at least offer users privacy until spending time, when they select which UTXOs to associate by the common-owner-input heuristic.

1 Like