-
Notifications
You must be signed in to change notification settings - Fork 5.8k
BIP draft: Consensus ScriptPubKey Length Limit #2039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
676d78f
38798f8
54883a0
bfee3c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| <pre> | ||
| BIP: ? | ||
| Layer: Consensus (soft fork) | ||
| Title: Consensus ScriptPubKey Length Limit | ||
| Author: billymcbip@proton.me | ||
| Status: Draft | ||
| Type: Specification | ||
| License: MIT | ||
| Version: 1.0.0 | ||
| </pre> | ||
|
|
||
| ==Abstract== | ||
|
|
||
| Limit the size of new ScriptPubKeys at the consensus level (including OP_RETURN outputs). | ||
|
|
||
| ==Specification== | ||
|
|
||
| Transactions in blocks at or above the activation height (''tbd'') cannot include outputs with ScriptPubKeys that are longer than 260 bytes. | ||
|
|
||
| ==Motivation== | ||
|
|
||
| Bitcoin is money. Transactions embedding arbitrary data compete with financial transactions for block space, and many node operators clearly do not want to process, relay or store arbitrary data. | ||
|
|
||
| The motivation of this BIP is to reduce the amount of arbitrary data that can be embedded in transactions and in the UTXO set. | ||
|
|
||
| A system with N independent bits of freedom can carry at most N bits of information. Limiting the length of ScriptPubKeys reduces independent bits of freedom within a block. More non-arbitrary bytes would have to wrap arbitrary bytes embedded in ScriptPubKeys. | ||
|
|
||
| ==Rationale== | ||
|
|
||
| '''Why limit OP_RETURN at all? Why not block OP_RETURN completely?''' | ||
|
|
||
| It is impossible to completely prevent arbitrary data in blocks. Therefore, it makes sense to continue offering a less harmful way to embed data, i.e. OP_RETURN. | ||
|
|
||
| However, OP_RETURN should only be ''marginally'' more attractive for data embedding than methods leading to arbitrary data in the UTXO set. | ||
|
|
||
| '''Why 260 bytes?''' | ||
|
|
||
| The length of ScriptPubKeys for all standard outputs is well below 260 bytes: | ||
billymcbip marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * P2PKH: 25 bytes | ||
| * P2SH: 23 bytes | ||
| * P2WPKH: 22 bytes | ||
| * P2WSH: 34 bytes | ||
| * P2TR: 34 bytes | ||
|
|
||
| Even x-of-3 bare multisig scriptPubKeys are smaller than 260 bytes. | ||
billymcbip marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| A 260 byte limit allows 256 bytes of data in OP_RETURN outputs: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is true, though this is only the limit on UTXO set excluded outpoints (unspendable) One could literally just use all 260 bytes for data if they didn't care about the execution of the script that resulted.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct, but a ~11 byte overhead per chunk would remain (see my other comment). |
||
| <pre> | ||
| 1 byte OP_RETURN | ||
| 1 byte OP_PUSHDATA2 | ||
| 2 bytes length | ||
| 256 bytes data | ||
| </pre> | ||
|
|
||
| Any limit is somewhat arbitrary, but 256 is a multiple of 32, i.e. 8 SHA-256 hashes could be embedded. | ||
|
|
||
| '''Why not limit non-OP_RETURN outputs to 34 bytes?''' | ||
|
|
||
| Firstly, simplicity: A simple length check is easier to implement, no need to discriminate between OP_RETURN outputs and other outputs. | ||
|
|
||
| Secondly, unknown unknowns: We may need longer scriptPubKeys in the future. | ||
|
|
||
| '''Why change consensus rather than mempool policy?''' | ||
|
|
||
| If we accept large OP_RETURN outputs in consensus but not in mempool policy, more transactions will be submitted directly to mining pools. This creates centralization pressure (see https://bitcoincore.org/en/2025/06/06/relay-statement/). | ||
|
|
||
| '''Why does this BIP not include other measures to limit data embedding?''' | ||
|
|
||
| The idea of this BIP is to allows the community to discuss the merits of a ScriptPubKey size limit in isolation. Limiting ScriptPubKey size can be an atomic change, it does not have to be implemented in conjunction with other, more complex anti-spam measures that constrain ''which'' UTXOs can be spent (rather than ''how'' UTXOs can be spent). | ||
|
|
||
| ==Backwards Compatibility== | ||
|
|
||
| Soft fork, backwards compatible. | ||
|
|
||
| ==Reference Implementation== | ||
|
|
||
| ''tbd'' | ||
|
|
||
| ==Deployment== | ||
|
|
||
| ''tbd'' | ||
|
|
||
| ==Credits== | ||
|
|
||
| This BIP is inspired by parts of the "Reduced Data Temporary Softfork" (https://github.com/bitcoin/bips/pull/2017). | ||
|
|
||
| ==Copyright== | ||
|
|
||
| This document is licensed under the MIT License. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This BIP only has a marginal effect on the total amount of data that could be stored as it only forces segmentation of the data into
.size()/260 + .size()%260 ? 1 : 0chunks.There is a reduction in the total usable space for arbitrary data by 5.625% with 9 bytes of overhead against 160 bytes of payload.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@portlandhodl I mostly agree - the effect is marginal. I think the ROI of this BIP is attractive because it can be implemented in very few LOC that are easy to reason about.
Nit: It might make more sense to split data into
.size()/255 + .size()%255 ? 1 : 0chunks to avoid having to useOP_PUSHDATA2(2 length bytes).Not following the numbers 9 and 160 here. I think the overhead is 14 bytes per chunk: