# LNHANCE bips and implementation

**URL:** <https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376>\
**Category:** Protocol Design\
**Created:** [January 7, 2024, 6:40pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376 "2024-01-07T18:40:08Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![reardencode](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/reardencode/32/27_2.png) [@reardencode](https://delvingbitcoin.org/u/reardencode)\
**Post date:** [January 7, 2024, 6:40pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/1 "2024-01-07T18:40:08Z")

</div>

I’ve just opened pull requests for bips and implementation of a combination of BIP119, OP\_CHECKSIGFROMSTACK(VERIFY) and OP\_INTERNALKEY (together I’m calling these “LNHANCE”).

> <https://github.com/bitcoin/bitcoin/pull/29198>
>
> This pull request contains a the same implementation of OP\_CHECKTEMPLATEVERIFY (…BIP119) as @jamesob's \[Covenant Tools\](https://github.com/bitcoin/bitcoin/pull/28550), an implementation of \[OP\_CHECKSIGFROMSTACK(VERIFY)\](https://github.com/bitcoin/bips/pull/1535) and of \[OP\_INTERNALKEY\](https://github.com/bitcoin/bips/pull/1534).
> 
> There are no testnet or mainnet activation parameters proposed in this pull request. I am deeply uninterested in the details of activation semantics.
> 
> This combination of changes allows for the implementation of a variety of layer two proposals and improvements. Including, but not limited to, Lightning Symmetry, Point-Time-Locked-Contracts, Timeout Trees, and unidirectional non-interactive channels.
> 
> For anyone interested, I also have a \[branch\](https://github.com/reardencode/bitcoin/tree/lnhance-v26) with these same changes based on the latest release.
> 
> \<!--
> \*\*\* Please remove the following help text before submitting: \*\*\*
> 
> Pull requests without a rationale and clear improvement may be closed
> immediately.
> 
> GUI-related pull requests should be opened against
> https://github.com/bitcoin-core/gui
> first. See CONTRIBUTING.md
> \--\>
> 
> \<!--
> Please provide clear motivation for your patch and explain how it improves
> Bitcoin Core user experience or Bitcoin Core developer experience
> significantly:
> 
> \* Any test improvements or new tests that improve coverage are always welcome.
> \* All other changes should have accompanying unit tests (see \`src/test/\`) or
> functional tests (see \`test/\`). Contributors should note which tests cover
> modified code. If no tests exist for a region of modified code, new tests
> should accompany the change.
> \* Bug fixes are most welcome when they come with steps to reproduce or an
> explanation of the potential issue as well as reasoning for the way the bug
> was fixed.
> \* Features are welcome, but might be rejected due to design or scope issues.
> If a feature is based on a lot of dependencies, contributors should first
> consider building the system outside of Bitcoin Core, if possible.
> \* Refactoring changes are only accepted if they are required for a feature or
> bug fix or otherwise improve developer experience significantly. For example,
> most "code style" refactoring changes require a thorough explanation why they
> are useful, what downsides they have and why they \*significantly\* improve
> developer experience or avoid serious programming bugs. Note that code style
> is often a subjective matter. Unless they are explicitly mentioned to be
> preferred in the \[developer notes\](/doc/developer-notes.md), stylistic code
> changes are usually rejected.
> \--\>
> 
> \<!--
> Bitcoin Core has a thorough review process and even the most trivial change
> needs to pass a lot of eyes and requires non-zero or even substantial time
> effort to review. There is a huge lack of active reviewers on the project, so
> patches often sit for a long time.
> \--\>

> <https://github.com/bitcoin/bips/pull/1534>
>
> OP\_INTERNALKEY is a new BIP342 tapscript only opcode (upgraded using OP\_SUCCESS …semantics) that takes bytes 1-32 (0-index, inclusive) from the BIP341 taproot control block and places them on the stack. This BIP describes that behavior.

> <https://github.com/bitcoin/bips/pull/1535>
>
> This BIP is based on the BCH OP\_CHECKDATASIG work, as well as postings from the …bitcoin dev mailing list in \[this thread\](https://www.mail-archive.com/bitcoin-dev@lists.linuxfoundation.org/msg10211.html). Some differences appear due to the activation of bips 340, 341, and 342 (taproot) since those were developed.
> 
> OP\_CHECKSIGFROMSTACKVERIFY is a NOP upgrade available in all script types.
> OP\_CHECKSIGFROMSTACK is an OP\_SUCCESS upgrade available only in BIP342 tapscript.

This combination of features seems to be a potentially safe and powerful starting point for bringing output restricting covenants to bitcoin and simultaneously supporting the next iteration of lightning development in the form of ln-symmetry and PTLCs.

---

<div class="post-metadata">

**Author:** ![michaelfolkson](https://delvingbitcoin.org/letter_avatar_proxy/v4/letter/m/90db22/32.png) [@michaelfolkson](https://delvingbitcoin.org/u/michaelfolkson)\
**Post date:** [January 7, 2024, 7:17pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/2 "2024-01-07T19:17:58Z")

</div>

(Copying across from my comment on the Core repo)

This should be opened to bitcoin-inquisition rather than this repo at this stage? I thought that was the whole point of bitcoin-inquisition. I can summarize why bitcoin-inquisition was introduced in the first place if that helps. It might seem overly finicky but having all proposed consensus changes (especially if they are new) discussed in the Core repo just adds too much noise to all the work that is being done on non consensus changes in Core (imo).

Also I’m interested in why you think LN-Symmetry would be better implemented not using APO?

---

<div class="post-metadata">

**Author:** ![reardencode](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/reardencode/32/27_2.png) [@reardencode](https://delvingbitcoin.org/u/reardencode)\
**Post date:** [January 7, 2024, 7:30pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/3 "2024-01-07T19:30:43Z")

</div>

> [@michaelfolkson](#):
>
> This should be opened to bitcoin-inquisition rather than this repo at this stage? I thought that was the whole point of bitcoin-inquisition. I can summarize why bitcoin-inquisition was introduced in the first place if that helps. It might seem overly finicky but having all proposed consensus changes (especially if they are new) discussed in the Core repo just adds too much noise to all the work that is being done on non consensus changes in Core (imo).

Inquisition is fine, and I’m happy to open a separate PR there for CSFS and INTERNALKEY if that is helpful to reviewers or others in the community. It is not, however, part of the flow for changes to bitcoin core. It is an _optional_ place to test significant changes before they are proposed for activation in bitcoin core if that is helpful to the process for any particular change.

> [@michaelfolkson](#):
>
> Also I’m interested in why you think LN-Symmetry would be better implemented not using APO?

APO is one way to achieve LN-Symmetry. In the range of possible ways to achieve LN-Symmetry, APO is somewhat of a closed development path. It introduces new key types for the existing sigops with a concrete set of sighash flags that cannot later be upgraded without adding another new set of key types. I have a PR open against APO that suggests an alternative design for those sighash flags, and there is a known issue that they should be changed to commit to the control block or merkle path to the script being executed in some modes. In short, there is a large design space for those sighash flags and a lack of direct upgradeability.

In contrast, CTV has a fairly narrow design space. The basic output commitment template is pretty clearly exactly as BIP119 describes it, and this can be combined with a well understood operation (CHECKSIGFROMSTACK) to provide the same committment as that used in @instagibbs LN-Symmetry implementation. Once we have CTV and CSFS in production for some time, we will be much better positioned to further analyze what other sighash modes might be useful for our next Tapscript key versions, or to analyze what hashing modes might be worth adding as a flags byte (or bytes) to CTV.

In short, this approach gives us small building blocks that are lowest common denominator for a variety of 2nd layer enhancements and position us to continue the discussion on future improvements.

---

<div class="post-metadata">

**Author:** ![michaelfolkson](https://delvingbitcoin.org/letter_avatar_proxy/v4/letter/m/90db22/32.png) [@michaelfolkson](https://delvingbitcoin.org/u/michaelfolkson)\
**Post date:** [January 7, 2024, 7:55pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/4 "2024-01-07T19:55:48Z")

</div>

> [@reardencode](#):
>
> It is an _optional_ place to test significant changes before they are proposed for activation in bitcoin core if that is helpful to the process for any particular change.

I mean… sure it is optional. But if everyone takes your approach we get tens of different PRs in the Core repo from different authors all with different combinations of their favorite opcodes and sighash flags and supposedly that helps review and makes progress towards activation. In a repo that already suffers from being unnecessarily noisy. But ok, whatever.

> [@reardencode](#):
>
> APO is one way to achieve LN-Symmetry. In the range of possible ways to achieve LN-Symmetry, APO is somewhat of a closed development path. It introduces new key types for the existing sigops with a concrete set of sighash flags that cannot later be upgraded without adding another new set of key types. I have a PR open against APO that suggests an alternative design for those sighash flags, and there is a known issue that they should be changed to commit to the control block or merkle path to the script being executed in some modes. In short, there is a large design space for those sighash flags and a lack of direct upgradeability.

Thanks, I wasn’t aware of this [BIP PR](https://github.com/bitcoin/bips/pull/1472) you opened. I suspect that isn’t a universally agreed “known issue” unless you can point me to a different discussion I missed. But it does introduce a new public key type, if that’s your criticism I guess that holds.

---

<div class="post-metadata">

**Author:** ![instagibbs](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/instagibbs/32/28_2.png) [@instagibbs](https://delvingbitcoin.org/u/instagibbs)\
**Post date:** [January 7, 2024, 8:31pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/5 "2024-01-07T20:31:15Z")

</div>

Hi! Do you have a short list of the well-understood constructs that can be built using these, along with their relative idea maturity(your estimate is fine 🙂 )?

I think it’d be useful to make it clear what you’re getting. E.g., PTLCs are definitely possible today, but APO-like construction is certainly leaps nicer!

---

<div class="post-metadata">

**Author:** ![moonsettler](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/moonsettler/32/38_2.png) [@moonsettler](https://delvingbitcoin.org/u/moonsettler)\
**Post date:** [January 7, 2024, 8:45pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/6 "2024-01-07T20:45:58Z")

</div>

Simple unidirectional NIC (non-interactive channel) that that is immune to TXID malleability and can be natural part of pool vTXOs (virtual UTXOs) from user `Alice` where you have a coordinator `Bob` that acts as an LSP:

```auto
<sigBob>
<sigAlice>
<template>
---
CHECKTEMPLATEVERIFY
<pubAlice>
OP_CHECKSIGFROMSTACKVERIFY
<pubBob>
OP_CHECKSIGVERIFY

```

You would have an alternative spending branch with a 24h timelock and `Alice` single sig. also have a 2-of-2 musig keyspend naturally.

`Alice` can keep giving `Bob` newer more favorable distributions. `Bob` gates them with his single sig.

What `Alice` would do is give `Bob` a new `<sigAlice> <template>` pairs and the new outputs that hash to the template to move funds to `Alice`. outputs can include HTLCs and then their updated settlement.

---

<div class="post-metadata">

**Author:** ![urza](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/urza/32/234_2.png) [@urza](https://delvingbitcoin.org/u/urza)\
**Post date:** [January 8, 2024, 6:31am UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/7 "2024-01-08T06:31:45Z")

</div>

Would this also allow construction of other things that APO would? Namely channel factories and Spacechains?

Ping @RubenSomsen

---

<div class="post-metadata">

**Author:** ![moonsettler](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/moonsettler/32/38_2.png) [@moonsettler](https://delvingbitcoin.org/u/moonsettler)\
**Post date:** [January 8, 2024, 10:21am UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/8 "2024-01-08T10:21:44Z")

</div>

indeed. LN-symmetry is an other big thing it enables. (will try to dig up the contract, pretty sure someone already laid it out) it won’t do everything APO can, and that’s on purpose. just the most important things that are highly desired.

edit:

```plaintext
# S = 500000000
# IK -> A+B
<sig> <state-n-hash> | CTV IK CSFSV <S+1> CLTV

```

before funding sign first state template:

```plaintext
# state-n-hash { nLockTime(S+n), out(contract, amount(A)+amount(B)) }
# settlement-hash { nSequence(2w), out(A, amount(A)), out(B, amount(B)) }

# contract for state n < m
IF
  <sig> <state-m-hash> | CTV IK CSFSV <S+n+1> CLTV
ELSE
  <settlement-hash> CTV
ENDIF

```

`CLTV` ensures only a larger `nLockTime` transaction can spend the current on-chain state, the relative timelock for the last co-signed state’s `CTV` distribution is committed to in the `settlement-hash`

---

<div class="post-metadata">

**Author:** ![reardencode](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/reardencode/32/27_2.png) [@reardencode](https://delvingbitcoin.org/u/reardencode)\
**Post date:** [January 9, 2024, 6:23pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/9 "2024-01-09T18:23:37Z")

</div>

Here’s a new one, [Oracle slashing](https://twitter.com/jxpcsnmz/status/1744780287136137276) (just proposed).

That relates closely to [simplified DLCs with CTV](https://mailmanlists.org/pipermail/dlc-dev/2022-January/000102.html).

[Timeout Trees](https://github.com/JohnLaw2/ln-scaling-covenants/blob/386736fa15cdda3c0f24f17a31b6ad608d338b08/scalingcovenants_v1.3.pdf), pretty well specified.

LN-Symmetry, as written by @instagibbs, ports directly to LNHANCE (probably all of uses for `SIGHASH_ANYPREVOUTANYSCRIPT|SIGHASH_ALL`).

[Ark](https://arkdev.info), as originally proposed by Burak, and depending on ephemeral anchors.

[Simple coin pools](https://rubin.io/bitcoin/2021/12/10/advent-13/) (with n-n signing required to advance the state of the pool) simple to implement, only useful for small (e.g. family) groups.

[Simple CTV Vaults](https://github.com/jamesob/simple-ctv-vault) implemented, but somewhat hard to use.

edit to add: Didn’t mention the basic ability of CSFS to be used in delegation. This is often not the best method, but can be useful. Script like `<pubkey> SWAP IF 2DUP CSFSV DROP ENDIF CHECKSIG`.

And many many many more that I don’t have immediate links to.

---

<div class="post-metadata">

**Author:** ![RubenSomsen](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/rubensomsen/32/188_2.png) [@RubenSomsen](https://delvingbitcoin.org/u/RubenSomsen)\
**Post date:** [January 10, 2024, 3:30pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/10 "2024-01-10T15:30:30Z")

</div>

> [@urza](#):
>
> Would this also allow construction of other things that APO would? Namely channel factories and Spacechains?

Spacechains are already possible without covenants, but yes, just about any covenant proposal that lets you pre-commit the next tx would be useful for spacechains.

---

<div class="post-metadata">

**Author:** ![alex](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/alex/32/274_2.png) [@alex](https://delvingbitcoin.org/u/alex)\
**Post date:** [January 17, 2024, 2:51pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/11 "2024-01-17T14:51:04Z")

</div>

Jeremy Rubin’s [uxos.org](https://utxos.org/uses/) is still a great resource for CTV-related applications

---

<div class="post-metadata">

**Author:** ![reardencode](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/reardencode/32/27_2.png) [@reardencode](https://delvingbitcoin.org/u/reardencode)\
**Post date:** [January 18, 2024, 6:22am UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/12 "2024-01-18T06:22:10Z")

</div>

Tonight, I created a PR against @ajtowns 's binana to create numbers for CSFS and INTERNALKEY.

> <https://github.com/bitcoin-inquisition/binana/pull/1>

I also created draft PRs for ctv, internalkey, csfs alone against core.

> <https://github.com/bitcoin/bitcoin/pull/29280>
>
> This pull request forks from #29198 and only includes the implementation of OP\_C…HECKTEMPLATEVERIFY, its tests (except the functional ones), and standardization of bare OP\_CHECKTEMPLATEVERIFY locking scripts.

> <https://github.com/bitcoin/bitcoin/pull/29269>
>
> This pull request forks from #29198 and includes only OP\_INTERNALKEY and its tes…ts.

> <https://github.com/bitcoin/bitcoin/pull/29270>
>
> This pull request forks from #29198 and includes only OP\_CHECKSIGFROMSTACK(VERIF…Y) and their tests.

These 3 PRs include everything from #29198 except activation and functional tests that depend on CTV being active in regtest. They conflict with each other, due to overlap in SCRIPT\_VERIFY\_FLAGS numbers, which I’m not sure the best way to deal with.

---

<div class="post-metadata">

**Author:** ![hampus](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/hampus/32/1238_2.png) [@hampus](https://delvingbitcoin.org/u/hampus)\
**Post date:** [January 19, 2024, 9:44pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/13 "2024-01-19T21:44:31Z")

</div>

> [@urza](#):
>
> Would this also allow construction of other things that APO would? Namely channel factories and Spacechains?

According to rearden, this would allow for an APO spacechain-like construction. [https://twitter.com/reardencode/status/1748452392046334366](https://twitter.com/reardencode/status/1748452392046334366)

Presumably helpful for statechains too.

---

<div class="post-metadata">

**Author:** ![moonsettler](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/moonsettler/32/38_2.png) [@moonsettler](https://delvingbitcoin.org/u/moonsettler)\
**Post date:** [January 21, 2024, 11:17pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/14 "2024-01-21T23:17:19Z")

</div>

a similar contract to LN-symmetry can be used for ‘immortal’ statecoins.

you can potentially do something even cooler, by stacking such constructs and thus transfer one end of an LN-symmetry channel, you can in theory reuse a single channel funding for any number of users.

in this case the final ‘distribution’ of the first channel opens the second (latest) one on-chain, then that has it’s own timeout for latest state.

---

<div class="post-metadata">

**Author:** ![ZmnSCPxj](https://delvingbitcoin.org/letter_avatar_proxy/v4/letter/z/ee7513/32.png) [@ZmnSCPxj](https://delvingbitcoin.org/u/ZmnSCPxj)\
**Post date:** [February 4, 2024, 12:25pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/15 "2024-02-04T12:25:02Z")

</div>

I have been thinking as well about mechanisms with internal fees, i.e. the funds that will be used to pay onchain fees in case of unilateral exit are inside the mechanism, instead of requiring an additional UTXO to be kept onchain to pay for unilateral exits. This allows for reduced blockspace use by not requiring anchor outputs and a CPFP-ing transaction, at the cost of requiring funds to be reserved per mechanism for the onchain fee in case of unilateral exit. Here is an attempt to design an extension for `OP_CHECKTEMPLATEVERIFY` for this: [`sighash_outputdeltabounds` - #2 by ZmnSCPxj](https://delvingbitcoin.org/t/sighash-outputdeltabounds/504/2)

---

<div class="post-metadata">

**Author:** ![cryptoquick](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/cryptoquick/32/977_2.png) [@cryptoquick](https://delvingbitcoin.org/u/cryptoquick)\
**Post date:** [March 15, 2024, 7:14pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/16 "2024-03-15T19:14:56Z")

</div>

Hi, I’ve made a modified version of rust-bitcoin-script that can do an implementation of LN symmetry script, so anything that needs the bytes for script somewhere can easily get the right format.

> <https://github.com/cryptoquick/rust-bitcoin-script/blob/1a7e1742b3a699fa5a021a73211e36d92a2c3bd5/tests/test.rs#L26-L44>

Forgive me if my byte counts are off in the example, I wasn’t sure of the exact inputs.

I don’t yet have support for IK, but I think that’s a Taproot thing anyway, so not the same as script.

Thanks to @cguida for nudging me towards doing this. He’ll be using this or something like it in trying to make an LNHANCE CLN plugin.

---

<div class="post-metadata">

**Author:** ![reardencode](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/reardencode/32/27_2.png) [@reardencode](https://delvingbitcoin.org/u/reardencode)\
**Post date:** [March 19, 2024, 8:38pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/17 "2024-03-19T20:38:03Z")

</div>

Nice, thank you!

IKEY is Tapscript only indeed, as it reads the BIP341 internal key from the control block and writes it to the stack.

---

<div class="post-metadata">

**Author:** ![moonsettler](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/moonsettler/32/38_2.png) [@moonsettler](https://delvingbitcoin.org/u/moonsettler)\
**Post date:** [October 30, 2024, 8:32am UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/18 "2024-10-30T08:32:30Z")

</div>

The LNhance family of opcodes has a new addition:

OP\_PAIRCOMMIT (PC)

When used in sequence of `CTV PC IK CSFS` they form the backbone of the LNhance-Symmetry channel.

> <https://github.com/bitcoin-inquisition/binana/pull/8>

---

<div class="post-metadata">

**Author:** ![moonsettler](https://delvingbitcoin.org/user_avatar/delvingbitcoin.org/moonsettler/32/38_2.png) [@moonsettler](https://delvingbitcoin.org/u/moonsettler)\
**Post date:** [November 24, 2024, 3:12pm UTC](https://delvingbitcoin.org/t/lnhance-bips-and-implementation/376/19 "2024-11-24T15:12:57Z")

</div>

I heard some claims that `CTV` needs 3 other opcodes to do LN-Symmtery. That’s wrong.

LNhance is `CTV` + `CSFS` at it’s core and that is enough to do LN-Symmetry. `IKEY` and `PC` are tiny composable pieces that optimize the use of `CTV` and `CSFS` for LN-Symmetry.

There are several ways to solve the data availability problem, some don’t even require a consensus change. Some don’t even require a relay policy change.

LNhance is just the best way of doing it that we know of.

**edit:**

One way to think about the 3 opcodes (`CSFS`, `IKEY`, `PC`) is we decompose a `CSFS` variant that can use 1 byte pubkey (internal key) and can commit to a vector of stack elements as message. They thus become more generally useful, but to a limited degree without additional opcodes.

Detailed introspection opcodes would also need vector commitments with `CSFS`, and it would also be useful for `OP_CHECKCONTRACTVERIFY` aka `CCV`.
