CHIP 2024-12 P2S: Pay to Script

Pay to Script (P2S) improves wallet ecosystem safety, simplifies contract design, and reduces transaction sizes for vault, multi-party, and DeFi applications.

CHIP:

Some discussion:

https://x.com/bitjson/status/1867470840138252565

4 Likes

I think we should remove the data carrier rule, just set a consensus per-output limit to 223 bytes to avoid needing to make exceptions for this or that. One simple rule for locking script, and one simple rule for NFT commitment size.

This will simplify consensus/relay rules, and there won’t be any incentive to ever use some non-opreturn locking script to squeeze in more data.

Also, clarify: if locking script would be limited to 223, and unlocking script to 10k, does that mean that VM would execute a 10223-byte script (when put together)?

Also, clarify: there may exist some pre-activation UTXOs that have locking script size greater than the limit proposed here. Should they be allowed to be spent (provided total executed bytes would stay under 10223 or 10k) or should they be unspendable?

2 Likes

Thanks for bringing it up!

I don’t have a strong opinion on data carrier outputs right now. In talking with stakeholders about it over the past few years, there’s a lot of technical disagreement on whether or not it should be limited at all (and if so, to what extent).

I don’t see the current ~223-byte limit as a barrier to contract development right now, so I’ve tried to avoid any impact to that status quo in the initial P2S CHIP draft. That being said:

(edit: adding headings to link to later)

Miscalculation in existing data carrier limit

There was a misunderstanding in the calculation behind the ~223-byte data carrier limit; assuming the original justification(s) for extending standard OP_RETURN to 220 bytes, that limit should arguably be higher. (And of course, the most relevant limit is currently ~100KB.)

I’m not advocating for an increase in that limit, but the issue is relevant here if we were to try to simplify by raising the P2S limit from 201 to 223 bytes. Sticking instead to the existing 201-byte bare multisig limit is probably most conservative, especially if the data carrier limit is eventually corrected upward.

Standard locking bytecode length < standard data-carrier length

Under the existing rules, the maximum-length standard locking bytecode (201-byte multisig) is a little shorter than the max-length data carrier output (220 bytes). There may be a slight impact to some incentives if this proposal were to make them equivalent.

Data carrier outputs are still “slightly cheaper” in that they can have a value set to zero (no dust limit), but their longer contiguous limit may currently help to incentivize some use cases toward data carrier vs. less- or non-prunable data commitment techniques. (Again, arguably not important, but the P2S CHIP avoids changing the status quo out of an abundance of caution.)


If I understand the question, no – evaluation stages would work exactly as today: unlocking bytecode is evaluated first (10KB limit, restricted to push ops), then the stack is copied + intermediate validation. Then the locking bytecode is evaluated: limit of 201 bytes in standard mode (replacing most of the script-type pattern matching that happens today), or the current 10KB limit in nonstandard mode (block validation). P2SH and various follow up validation also remains the same.

The CHIP can’t invalidate any existing UTXOs/use cases, and it doesn’t create a difference between output (creation time) and UTXO (spend time) standardness validation. In the interest of staying as minimal as possible, I don’t think we should add any new schemes for e.g. extending the spending-standardness length limit if the unlocking bytecode is shorter than its maximum. After all, the remaining argument for keeping any standardness limit on locking bytecode length centers around UTXO set growth, and unlocking bytecode length is irrelevant there. (@bitcoincashautist did that answer your question?)

Posted some FAQs here:

Pay to Script (P2S) CHIP FAQs:

How are the 3 limits – Locking Bytecode Length, Token Commitment Length, and Unlocking Bytecode Length – related?

The currently-inconsistent behavior of these limits each produce the same unintended effect for contract authors: they force one or more unnecessary hashes to be placed into other part(s) of the transaction where they don’t logically belong, wasting storage/bandwidth for no gain to either the user or the wider network.

The P2S CHIP recommends the most conservative change to each constant to make these limits logically consistent + eliminate today’s most common sources of waste in transaction sizes.

But if the P2S CHIP is about wasted hashes in transactions, why is it called “Pay to Script”?

It’s not a perfect name. We could call it the “Reduce Unnecessary Hashing in Transactions” CHIP, or we could pick an amorphous name like “Beetroot” that doesn’t attempt to be meaningfully descriptive.

I’m open to suggestions, but for now, I think its best that the name highlights the biggest user-facing impact of the CHIP: right now we can only use “Pay to Script Hash” (P2SH), after this upgrade, we’d be able to use “Pay to Script” (P2S), too.

Most news sources covering the upgrade proposal probably won’t attempt to describe the technical details beyond that, but if they do, the intro offers plenty of material to clarify (and the rationale section includes even more):


Summary

This proposal makes Pay to Script (P2S) outputs standard and increases the length limits on token commitments and standard unlocking bytecode.

These changes improve wallet ecosystem safety, simplify contract design, and reduce transaction sizes for many vault, multi-party covenant, and decentralized financial applications.

Motivation & Benefits

  • Improve wallet ecosystem safety - Many kinds of contracts should not by “randomly payable” by naive wallets, but because P2SH contracts always have payable addresses, it’s easy for confused users to mistakenly send funds to unrecoverable locations. This proposal gives contract authors a new primitive that is both more byte efficient and safer for end users.

  • Simplify contracts - This proposal avoids the need for intermediate construction of P2SH contracts in a variety of use cases, simplifying inspection and modification of the active bytecode, and avoiding wasted bytes and hashing – both in packing (validating the P2SH address within the covenant) and unpacking (at spending time) the P2SH contract. This reduces the overhead of most covenant systems by at least 34 bytes per output.

1 Like

Thanks for writing this CHIP :smiley: :pray:

I’m very enthusiastic about this CHIP and the three rules it changes! The proposal transitions 2 ‘non-standard’ rules into ‘standardness’. The increased commitment length was never added as a ‘non-standard’ rule but nevertheless also this rule deserves to be relaxed to solve the current need for hashing contract state larger than 40 bytes. :100:

Transitioning non-standardness

It will be great that the rules for custom lockingscripts and 1650-10,000 byte unlocking scripts are no longer only available for use by miner-assisted developers. Currently these use-cases really only are a possible vector for malicious actors but not usable by normal contract authors.

With the ‘Unification of Standard and Consensus Unlocking Bytecode Length’ the effective limits for smart contract authors will increase 6x. As pointed out in the CHIP this will not come at any cost for the worst-case-validation scenario, so it’s a clear win for contract developers! :rocket:

Custom Locking Scripts

It’s interesting to think about what class of smart contracts would/will benefit the most from directly using a custom locking script versus using the pay-to-scripthash wrapping. With the bytesize limit of 201 for custom locking scripts, the space savings in percentage terms for each contract using it will be high, as P2SH adds 23 or 35 bytes overhead depending on the type.

Effect on user-space and developer tooling

It’s an important benefit worth repeating that the ecosystem cost is very self-contained, this doesn’t have to be supported in any of the wallets/tooling focused on simply sending/receiving Bitcoin Cash for transaction purposes. Because there is no new address type, there clearly is not the need for the wider ecosystem to support a new address type (unlike BTC with their different segwit and taproot address types) :sweat_smile:

I know you mean ‘user-facing’ loosely here, but end-users really won’t see this new scripts, as there is no address format by design. It’s mainly smart contract-capable wallets and smart contract application developers who’ll be in contact with these new custom locking types.

Eliminating the need for offchain script-backups

Additionally, the property of P2SH that it hides the underlying script can definitely be a drawback, as it can result in losing/forgetting the exact script containing your money. For smart contracts which already have unlocked UTXOs on the P2SH address this does not present a problem, but for contracts using custom initialization params, your address will be unique which leads to off-chain storage/backup requirements.

Relaxing the NFT commitment length

As you describe, an increase in the NFT commitment length would eliminate unnecessary hashing which would currently be needed by smart contracts which want to keep more than 40 bytes state. I want to emphasize that this hashing comes with the same need for offchain script-backups described above:

If you as a developer need to hash your state to fit it into an NFT commitment, this state should either be backed up off chain (with the risks that come with it) or for self-replicating covenants the new state should be derived from the previous state + latest the state transition. Eliminating the hashing means no more need for off-chain state backups or no need for emulating contract state transitions.

I hope we see the P2S CHIP activate in 2026, it builds further upon the robust foundation laid by the VM Limits CHIP and relaxes the conservative commitment limit introduced in the CashTokens CHIP

2 Likes