<p>At a high level, a user would lock funds into a CAT covenant that commits to a particular r-value.</p>
<p>This means the spending transaction for this utxo must use that particular r-value when sending funds. If the user sends funds and tries to RBF, they will inevitably end up using a new s-value, resulting in nonce-reuse and allowing for their funds to be slashed by anyone watching the mempool.</p>
<p>Specifically, this involves the following scripts (as outlined by <a href="https://x.com/btcanary55082" rel="nofollow noreferrer">bt canary</a> in their original spec <a href="https://gitlab.com/-/snippets/3735654" rel="nofollow noreferrer">https://gitlab.com/-/snippets/3735654</a>)</p>
<p>Locking Script:</p>
<pre><code>// Verify r and compose signature
OP_OVER
OP_HASH160
&lt;$(&lt;r&gt; OP_HASH160)&gt;
OP_EQUALVERIFY
OP_CAT
OP_SWAP
// Stack: &lt;signature&gt;, &lt;pubKey&gt;
// Standard P2PKH script
OP_DUP
OP_HASH160
&lt;$(&lt;pubKey&gt; OP_HASH160)&gt;
OP_EQUALVERIFY
OP_CHECKSIG
</code></pre>
<p>Unlocking script</p>
<pre><code>&lt;pubKey&gt;
&lt;r&gt;
&lt;$(&lt;s&gt;&lt;0x41&gt; OP_CAT)&gt;
</code></pre>
<p>As we can see, the locking script commits to the r-value, which the unlocking script must provide along with the s-value to be used.</p>
<p>CAT is necessary to concatenate the r and s values together on the stack, to be verified by CHECKSIG at the end of the script.</p>
<p>Private key recovery is specified on the original spec as well: <a href="https://gitlab.com/-/snippets/3735654" rel="nofollow noreferrer">https://gitlab.com/-/snippets/3735654</a></p>
<p>(Or a more comprehensive explanation of how slashing is achieved for those that are new to schnorr signatures can be seen here: <a href="https://web.archive.org/web/20231003173156/https://suredbits.com/introduction-to-schnorr-signatures/" rel="nofollow noreferrer">https://web.archive.org/web/20231003173156/https://suredbits.com/introduction-to-schnorr-signatures/</a> )</p>

CC BY-SA 4.0
2024-08-22T19:57:17.317Z
So, the idea would be that any sender who potentially wants to issue 0-conf transactions would stage some portion of their funds in such a r-locked covenant?
Murch
CC BY-SA 4.0
2024-08-22T20:04:26.440Z
Yep exactly. You could have a spending wallet where you've staged a portion of your funds for 0-conf transactions, and then whenever you pay someone, the change goes to another r-value covenant.

And whoever you're paying would have a receiving wallet that verifies that it was locked and unlocked using 0-conf covenant.
Matt Black
CC BY-SA 4.0
2024-08-22T20:31:02.550Z
So, we need a much bigger output script, and stage funds in advance, to be able to create a 0-conf payment that requires the receiver to run special software, but the construction only guarantees the receiver to get paid per exposing the sender to a risk of losing their funds. In the case of a breach, the sender and receiver may have a bidding war over the funds, but in the end, the miner should end up getting the funds. If we have bigger transactions and need to commit funds in advance to achieve instant payments, shouldn’t we prefer to use a payment channel?
Murch
CC BY-SA 4.0
2024-08-22T21:07:10.747Z
If fees are low, the main advantage is not running into inbound/outbound liquidity issues and being able to pay anyone. Also you only need to commit once, vs needing to commit often with new LN channels. It could also be a nice solution for a quick submarine swap. It could also be helpful as an alternative to lightning in case paying an invoice fails to a merchant.
Matt Black
CC BY-SA 4.0
2024-08-22T21:23:08.463Z
How would you commit only once? I thought you spend the r-commited UTXO, so you'd have to commit once per 0-conf payment (although you can do it with the change output).
Murch
CC BY-SA 4.0
2024-08-22T21:35:10.500Z
Yeah, I meant with the change output. The person receiving can also get the funds at a receive address that commits to r-value, saving them from having to create another transaction to commit.
Matt Black
CC BY-SA 4.0
2024-08-22T19:29:55.867Z
2024-08-22T19:29:55.867Z
Matt Black
<p>Today in the on-going OP_CAT debate, proponents <a href="https://x.com/matthewjablack/status/1826408792436687355" rel="nofollow noreferrer">claim</a> that OP_CAT enables an opt-in mechanism that produces 0-conf transactions that cannot be doublespent without leaking the private key.</p>
<p>How does this proposed construction work?</p>

<zero-confirmation><bip347-op-cat>
How does a 0-conf signature bond work?
Murch
# How does a 0-conf signature bond work?

(Asked by: username_0 on 2024-08-22)

Today in the on-going OP\_CAT debate, proponents [claim](https://x.com/matthewjablack/status/1826408792436687355) that OP\_CAT enables an opt-in mechanism that produces 0-conf transactions that cannot be doublespent without leaking the private key.

How does this proposed construction work?

**Tags:** zero-confirmation, bip347-op-cat


---

## 1 answers

### Answer by username_1 on 2024-08-22. Score: 2 | Accepted answer

At a high level, a user would lock funds into a CAT covenant that commits to a particular r-value.

This means the spending transaction for this utxo must use that particular r-value when sending funds. If the user sends funds and tries to RBF, they will inevitably end up using a new s-value, resulting in nonce-reuse and allowing for their funds to be slashed by anyone watching the mempool.

Specifically, this involves the following scripts (as outlined by [bt canary](https://x.com/btcanary55082) in their original spec <https://gitlab.com/-/snippets/3735654>)

Locking Script:

```
// Verify r and compose signature
OP_OVER
OP_HASH160
<$(<r> OP_HASH160)>
OP_EQUALVERIFY
OP_CAT
OP_SWAP
// Stack: <signature>, <pubKey>
// Standard P2PKH script
OP_DUP
OP_HASH160
<$(<pubKey> OP_HASH160)>
OP_EQUALVERIFY
OP_CHECKSIG

```

Unlocking script

```
<pubKey>
<r>
<$(<s><0x41> OP_CAT)>

```

As we can see, the locking script commits to the r-value, which the unlocking script must provide along with the s-value to be used.

CAT is necessary to concatenate the r and s values together on the stack, to be verified by CHECKSIG at the end of the script.

Private key recovery is specified on the original spec as well: <https://gitlab.com/-/snippets/3735654>

(Or a more comprehensive explanation of how slashing is achieved for those that are new to schnorr signatures can be seen here: <https://web.archive.org/web/20231003173156/https://suredbits.com/introduction-to-schnorr-signatures/> )

> **Comments:**
> **username_0**: So, the idea would be that any sender who potentially wants to issue 0-conf transactions would stage some portion of their funds in such a r-locked covenant?  
> **username_1**: Yep exactly. You could have a spending wallet where you've staged a portion of your funds for 0-conf transactions, and then whenever you pay someone, the change goes to another r-value covenant.  And whoever you're paying would have a receiving wallet that verifies that it was locked and unlocked using 0-conf covenant.  
> **username_0**: So, we need a much bigger output script, and stage funds in advance, to be able to create a 0-conf payment that requires the receiver to run special software, but the construction only guarantees the receiver to get paid per exposing the sender to a risk of losing their funds. In the case of a breach, the sender and receiver may have a bidding war over the funds, but in the end, the miner should end up getting the funds. If we have bigger transactions and need to commit funds in advance to achieve instant payments, shouldn’t we prefer to use a payment channel?  
> **username_1**: If fees are low, the main advantage is not running into inbound/outbound liquidity issues and being able to pay anyone. Also you only need to commit once, vs needing to commit often with new LN channels. It could also be a nice solution for a quick submarine swap. It could also be helpful as an alternative to lightning in case paying an invoice fails to a merchant.  
> **username_0**: How would you commit only once? I thought you spend the r-commited UTXO, so you'd have to commit once per 0-conf payment (although you can do it with the change output).  
> **username_1**: Yeah, I meant with the change output. The person receiving can also get the funds at a receive address that commits to r-value, saving them from having to create another transaction to commit.  

---

