Hi all!
In recent weeks, I’ve been thinking about a feature bitcoin script doesn’t have yet: the possibility of expiration date for transactions.
I made a rapid research and found out this opcode have already been proposed before (OP_EXPIRE: Mitigating replacing cycling attacks - Protocol Design - Delving Bitcoin OP_EXPIRE: Mitigating replacing cycling attacks - Protocol Design - Delving Bitcoin ), but mainly with LN and replace-cycling attacks in mind. I thought about this feature for different reasons, and I think it hasn’t been given enough credit or sufficiently stressed out by the community.
Context
I first had this idea after reading about the protocol level of a project I am interested in, the implementation of coinswap on Bitcoin ( GitHub - citadel-tech/coinswap: Functioning, minimal-viable binaries and libraries to perform a trustless, p2p Maxwell-Belcher Coinswap Protocol ). AFAIK, this is the first onchain BTC to BTC atomic swap implementation so far.
The protocol roughly goes:
- Participants create a closed loop of “channels” made of musigs
- HTLCs are used to swap coins in the loop
- After the pre image reveal, there is a handover of private keys to the new owners
- The new owners use the private key to spend the musig and successfully finish the session
If everything goes right, onchain footprints are only of musigs in the P2WSH version, and after implementing P2TR version, indistinguishable form every other P2TR.
After understanding the steps, it boggled my mind the necessity of the last tx by all participants. The last tx is necessary to be certain that the former partner doesn’t try to steal funds with the HTLC, so the only way a wallet wouldn’t need to constantly check for steal attempts is by spending the musig.
But this is suboptimal. Private keys have already been handovered, if the HTLCs didn’t exist, the new owner would already have sufficient info for spending the new UTXO, and we would have a single tx swap.
In order to BTC to have a safe future, we need high fees, this is crucial for hashrate maintanance. In the ideal world, txs on the blockchain need to be made minimal. In that way, I think OP_EXPIRE could reduce one tx in contracts involving swaps and privkey handover.
Further use cases
This first use case made me come with this opcode (even though, I didn’t know it was already been proposed lol), but after further thinking, I found out it can be used in several other ways, and that it composes really well with OP_CSFS and OP_CTV.
How would the opcode work:
- It pops up the top value on the stack, representing the expiration block or time (TBD if it could have different encodings of height, relative time, etc, but the absolute height case is essential for some cases)
- It asserts if the UTXO have expired or not (TBD if it would have a verify functionality or if it could push a bool in the stack, which permits IF ELSE composability, but I wonder if multiple tapleaves aren’t useful enough)
We could build scripts where the expiration height/delta on the stack is signed, allowing for diverse use cases composing with OP_CSFS, such as:
- Time restrained delegations (used together with OP_CTV)
- Contracts operating on real time data confirmed by an oracle (such as prices, exchange rates, etc)
- Short time approval of owner or associated entity
- Voting, elections, with restrained time for consensus
- More options of contracts and L2 applications
Delegation can be implemented in a clever way, such as:
- Owner have a master key pair, and a first OP_CSFS tests agains the master pubkey
- Owner creates an ephemeral key pair, and signs the ephemeral pubkey, validated by the first OP_CSFS
- They use the ephemeral privkey to sign an expiration height and a OP_CTV hash, or any other value they wish to be used by the script. Thes values are further validated by other calls to OP_CSFS, now validating against the ephemeral pubkey
- After the expiration height, all approvals are revoked, and if it wasn’t confirmed onchain, the delegated operator may need a new approval. The ephemeral key pair grants that chosen values are tied to the expiration, and a new expiration height cannot be used to validate an old chosen value
Trust assumptions and possible drawbacks
I understand that, depending on the way the opcode is used and the height is calculated, values may be burn forever. However, such assumptions already exists (in a certain degree) in any HTLC contract: if your revoke tx isn’t confirmed in time, the counterparty may get your funds.
Other possible attack vector I think may exist are miners holding to approve txs in order to make participants pay higher fees under pressure. However, this would only work in a centralized mining world, because otherwise miners may lose possible earnings to concurrent pools.
Aside from those considerstions, I see this opcode as a simple feature that doesn’t affect MEVil nor would have unpredicted outcomes. But I am interested in hearing other takes on ths subject.