mirror of
https://github.com/bitcoin/bips.git
synced 2026-04-06 16:16:45 +00:00
Add BIP-346: OP_TXHASH
This commit is contained in:
441
bip-0346.md
Normal file
441
bip-0346.md
Normal file
@@ -0,0 +1,441 @@
|
||||
```
|
||||
BIP: 346
|
||||
Layer: Consensus (soft fork)
|
||||
Title: OP_TXHASH
|
||||
Authors: Steven Roose <steven@roose.io>
|
||||
Brandon Black <freedom@reardencode.com>
|
||||
Status: Draft
|
||||
Type: Specification
|
||||
Assigned: 2024-04-24
|
||||
License: BSD-3-Clause
|
||||
```
|
||||
|
||||
# Abstract
|
||||
|
||||
This BIP proposes a new opcode `OP_TXHASH`, to be activated as a change to the
|
||||
semantics of `OP_SUCCESS189` in tapscript contexts.
|
||||
|
||||
This opcode provides a generalized method for introspecting certain details of
|
||||
the spending transaction, which enables non-interactive enforcement of certain
|
||||
properties of the transaction spending a certain UTXO.
|
||||
|
||||
Together with an opcode like `OP_CHECKSIGFROMSTACK`, this opcode effectively
|
||||
provides a fully generalized signature hash construction, fully supporting
|
||||
all existing SIGHASH flags, the proposed sighash flags from
|
||||
[BIP-118](bip-0118.mediawiki) (`SIGHASH_ANYPREVOUT`) and many other new signature hash
|
||||
combinations.
|
||||
|
||||
The constructions specified in this BIP also open up the way for other
|
||||
potential updates; see Motivation section for more details.
|
||||
|
||||
|
||||
# Specification
|
||||
|
||||
|
||||
## OP_TXHASH
|
||||
|
||||
`OP_TXHASH` redefines the `OP_SUCCESS189` tapscript opcode (`0xbd`) as a soft
|
||||
fork upgrade. This opcode is only active in tapscript contexts.
|
||||
|
||||
Note that `OP_SUCCESS187` is used by [BIP-443](bip-0443.mediawiki) (`OP_CHECKCONTRACTVERIFY`) and
|
||||
`OP_SUCCESS188` was used by [BIP-345](bip-0345.mediawiki) (`OP_VAULT`) at the time of first draft
|
||||
of this BIP, making `OP_SUCCESS189` the next available opcode for this purpose.
|
||||
|
||||
It has the following semantics:
|
||||
|
||||
* There is at least one element on the stack, fail otherwise.
|
||||
* The element is interpreted as the TxFieldSelector and is popped off the stack.
|
||||
* The TxFieldSelector must be valid, fail otherwise.
|
||||
* The 32-byte TxHash of the transaction at the current input index, calculated
|
||||
using the given TxFieldSelector is pushed onto the stack.
|
||||
|
||||
## TxFieldSelector
|
||||
|
||||
The TxFieldSelector has the following encoding. We will give a brief conceptual
|
||||
summary, followed by a reference implementation of the CalculateTxHash function.
|
||||
|
||||
In the following specifications, the `|` operator is used for the bitwise OR
|
||||
operation.
|
||||
|
||||
* There are two special cases for the TxFieldSelector:
|
||||
* the empty value, zero bytes long: it is set equal to `TXFS_SPECIAL_TEMPLATE`,
|
||||
the de-facto default value which means everything except the prevouts and
|
||||
the prevout scriptPubkeys and amounts.
|
||||
|
||||
Special case `TXFS_SPECIAL_TEMPLATE` is 4 bytes long, as follows:
|
||||
* 1: `TXFS_VERSION | TXFS_LOCKTIME | TXFS_CURRENT_INPUT_IDX`
|
||||
* 2: `TXFS_INPUTS_SEQUENCES | TXFS_INPUTS_SCRIPTSIGS | TXFS_OUTPUTS_ALL`
|
||||
* 3: `TXFS_INOUT_NUMBER | TXFS_INOUT_SELECTION_ALL`
|
||||
* 4: `TXFS_INOUT_NUMBER | TXFS_INOUT_SELECTION_ALL`
|
||||
|
||||
* If the TxFieldSelector has exactly 1 byte, we use a _short notation_.
|
||||
It has its 8 bits assigned as follows, from lowest to highest:
|
||||
* 2/1: Inputs
|
||||
* 00: `TXFS_INOUT_SELECTION_NONE`
|
||||
* 01: `TXFS_INOUT_SELECTION_CURRENT`
|
||||
* 11: `TXFS_INOUT_SELECTION_ALL`
|
||||
* 4/3: Outputs
|
||||
* 00: `TXFS_INOUT_SELECTION_NONE`
|
||||
* 01: `TXFS_INOUT_SELECTION_CURRENT`
|
||||
* 11: `TXFS_INOUT_SELECTION_ALL`
|
||||
* 5: `TXFS_INPUTS_PREVOUTS`
|
||||
* 6: `TXFS_INPUTS_PREV_SCRIPTPUBKEYS | TXFS_INPUTS_PREV_VALUES`
|
||||
* 7: `TXFS_CURRENT_INPUT_CONTROL_BLOCK | TXFS_CURRENT_INPUT_SPENTSCRIPT | TXFS_CURRENT_INPUT_LAST_CODESEPARATOR_POS`
|
||||
* 8: `TXFS_CURRENT_INPUT_IDX`
|
||||
|
||||
Additionally, it includes `TXFS_VERSION | TXFS_LOCKTIME | TXFS_CONTROL | TXFS_CURRENT_INPUT_TAPROOT_ANNEX`
|
||||
as global fields and `TXFS_INPUTS_SEQUENCES | TXFS_INPUTS_SCRIPTSIGS | TXFS_OUTPUTS_ALL`
|
||||
as input and output fields.
|
||||
|
||||
These 1-byte selections allow the TxFieldSelector to emulate current
|
||||
signature hashing modes and those defined in [BIP-118](bip-0118.mediawiki):
|
||||
|
||||
| BIP-341/118 sighash type | 1-byte TxFieldSelector |
|
||||
| :--------------------------- | :--------------------- |
|
||||
| `ALL` | `0b11111111` |
|
||||
| `SINGLE` | `0b11110111` |
|
||||
| `NONE` | `0b11110011` |
|
||||
| `ALL|ANYONECANPAY` | `0b11111101` |
|
||||
| `SINGLE|ANYONECANPAY` | `0b11110101` |
|
||||
| `NONE|ANYONECANPAY` | `0b11110001` |
|
||||
| `ALL|ANYPREVOUT` | `0b11101101` |
|
||||
| `SINGLE|ANYPREVOUT` | `0b11100101` |
|
||||
| `NONE|ANYPREVOUT` | `0b11100001` |
|
||||
| `ALL|ANYPREVOUTANYSCRIPT` | `0b11001101` |
|
||||
| `SINGLE|ANYPREVOUTANYSCRIPT` | `0b11000101` |
|
||||
| `NONE|ANYPREVOUTANYSCRIPT` | `0b11000001` |
|
||||
|
||||
|
||||
* If the TxFieldSelector is longer than one byte, the first byte of the TxFieldSelector
|
||||
has its 8 bits assigned as follows, from lowest to highest:
|
||||
* 1: version (`TXFS_VERSION`)
|
||||
* 2: locktime (`TXFS_LOCKTIME`)
|
||||
* 3: current input index (`TXFS_CURRENT_INPUT_IDX`)
|
||||
* 4: current input control block (`TXFS_CURRENT_INPUT_CONTROL_BLOCK`)
|
||||
* 5: current input spent script (`TXFS_CURRENT_INPUT_SPENTSCRIPT`)
|
||||
* 6: current script last `OP_CODESEPARATOR` position (or 0xffffffff)
|
||||
(`TXFS_CURRENT_INPUT_LAST_CODESEPARATOR_POS`)
|
||||
* 7: current input annex including prefix byte (or empty) (`TXFS_CURRENT_INPUT_TAPROOT_ANNEX`)
|
||||
* 8: `TXFS_CONTROL` (i.e. include TxFieldSelector into hash)
|
||||
|
||||
* The highest bit of the first byte (`TXFS_CONTROL`), we will call the
|
||||
"control bit", and it can be used to control the behavior of the opcode. For
|
||||
`OP_TXHASH`, the control bit is used to determine
|
||||
whether the TxFieldSelector itself has to be included in the resulting hash.
|
||||
(For potential other uses of the TxFieldSelector (like a hypothetical
|
||||
`OP_TX`), this bit can be repurposed.)
|
||||
|
||||
* The second byte will be used to indicate fields from the inputs and outputs.
|
||||
The 8 bits are assigned the following variables, from lowest to highest:
|
||||
* Specifying which fields of the inputs will be selected:
|
||||
* 1: prevouts (`TXFS_INPUTS_PREVOUTS`)
|
||||
* 2: sequences (`TXFS_INPUTS_SEQUENCES`)
|
||||
* 3: scriptSigs (`TXFS_INPUTS_SCRIPTSIGS`)
|
||||
* 4: prevout scriptPubkeys (`TXFS_INPUTS_PREV_SCRIPTPUBKEYS`)
|
||||
* 5: prevout values (`TXFS_INPUTS_PREV_VALUES`)
|
||||
* 6: taproot annexes (`TXFS_INPUTS_TAPROOT_ANNEXES`)
|
||||
|
||||
* Specifying which fields of the outputs will be selected:
|
||||
* 7: scriptPubkeys (`TXFS_OUTPUTS_SCRIPTPUBKEYS`)
|
||||
* 8: values (`TXFS_OUTPUTS_VALUES`)
|
||||
|
||||
* We define as follows:
|
||||
* `TXFS_ALL = TXFS_VERSION | TXFS_LOCKTIME | TXFS_CURRENT_INPUT_IDX | TXFS_CURRENT_INPUT_CONTROL_BLOCK | TXFS_CURRENT_INPUT_LAST_CODESEPARATOR_POS | TXFS_CONTROL`
|
||||
* `TXFS_INPUTS_ALL = TXFS_INPUTS_PREVOUTS | TXFS_INPUTS_SEQUENCES | TXFS_INPUTS_SCRIPTSIGS | TXFS_INPUTS_PREV_SCRIPTPUBKEYS | TXFS_INPUTS_PREV_VALUES | TXFS_INPUTS_TAPROOT_ANNEXES`
|
||||
* `TXFS_OUTPUTS_ALL = TXFS_OUTPUTS_SCRIPTPUBKEYS | TXFS_OUTPUTS_VALUES`
|
||||
|
||||
|
||||
* For both inputs and then outputs, expect an additional byte as follows:
|
||||
* The highest bit (`TXFS_INOUT_NUMBER`) indicates whether the "number of
|
||||
in-/outputs" should be committed to.
|
||||
* For the remaining bits, there are three exceptional values:
|
||||
* 0x00 (`TXFS_INOUT_SELECTION_NONE`) means "no in/outputs" (hence only the
|
||||
number of them as `0x80` (`TXFS_INOUT_NUMBER`)).
|
||||
* `0x40` (`TXFS_INOUT_SELECTION_CURRENT`) means "select only the in/output
|
||||
of the current input index" (it is invalid when current index exceeds
|
||||
number of outputs).
|
||||
* `0x3f` (`TXFS_INOUT_SELECTION_ALL`) means "select all in/outputs".
|
||||
|
||||
* The second highest bit (`TXFS_INOUT_SELECTION_MODE`) is the "specification mode":
|
||||
* Set to 0 it means "leading mode".
|
||||
* Set to 1 it means "individual mode".
|
||||
|
||||
* In "leading mode", the third highest bit (`TXFS_INOUT_LEADING_SIZE`) is
|
||||
used to indicate the "index size", i.e. the number of bytes will be used to
|
||||
represent the number of in/output.
|
||||
* With "index size" set to 0, the remaining lowest 5 bits of the first byte
|
||||
will be interpreted as the number of leading in/outputs to select.
|
||||
* With "index size" set to 1, the remaining lowest 5 bits of the first byte
|
||||
together with the 8 bits of the next byte will be interpreted as the
|
||||
number of leading in/outputs to select.
|
||||
|
||||
* In "individual mode", the third highest bit (`TXFS_INOUT_INDIVIDUAL_MODE`)
|
||||
indicates whether we are passing absolute indices (0) or indices relative
|
||||
to the current input (1), the remaining lowest 5 bits will be interpreted
|
||||
as `n`, the number of individual in/outputs follow.
|
||||
* In absolute mode (second highest bit is 0), for each of the `n` indices,
|
||||
at least one extra byte is expected.
|
||||
* If that byte's highest bit is set to 0, the remaining 7 bits represent
|
||||
the absolute index to select.
|
||||
* If that byte's highest bit is set to 1, the remaining 7 bits, together
|
||||
with the next byte's 8 bits represent the absolute index to select.
|
||||
* In relative mode (second highest bit is 1), for each of the `n` indices,
|
||||
at least one extra byte is expected.
|
||||
* If that byte's highest bit is set to 0, the remaining 7 bits represent
|
||||
the relative index in two's complement.
|
||||
* If that byte's highest bit is set to 1, the remaining 7 bits, together
|
||||
with the next byte's 8 bits represent the relative index in two's
|
||||
complement.
|
||||
|
||||
|
||||
Effectively, this allows a user to select
|
||||
* all in/outputs
|
||||
* the current input index
|
||||
* the leading in/outputs up to 8,191
|
||||
* up to 32 individually selected in/outputs
|
||||
** using absolute indices up to 32,767
|
||||
** using indices relative to the current input index from -16382 to +16383.
|
||||
|
||||
|
||||
### TxFieldSelector malleability
|
||||
|
||||
It is possible to represent the same selected data using multiple different
|
||||
TxFieldSelectors. For this reason, users are advised to always set the
|
||||
`TXFS_CONTROL` field flag that commits to the TxFieldSelector that was used
|
||||
to get the hash.
|
||||
|
||||
|
||||
### Visualization
|
||||
|
||||
* first byte
|
||||
|
||||
```
|
||||
1 1 1 1 1 1 1 1
|
||||
| | | | | | | ^ version
|
||||
| | | | | | ^ locktime
|
||||
| | | | | ^ current input index
|
||||
| | | | ^ current input control block
|
||||
| | | ^ current input spent script
|
||||
| | ^ current script last OP_CODESEPARATOR
|
||||
| ^ current input taproot annex
|
||||
^ control bit (ie. include TXFS in hash)
|
||||
```
|
||||
|
||||
* second byte
|
||||
|
||||
```
|
||||
<-> outputs
|
||||
| | <---------> inputs
|
||||
1 1 1 1 1 1 1 1
|
||||
| | | | | | | ^ prevouts
|
||||
| | | | | | ^ sequences
|
||||
| | | | | ^ scriptSigs
|
||||
| | | | ^ prevout scriptPubkeys
|
||||
| | | ^ prevout values
|
||||
| | ^ taproot annexes
|
||||
| ^ scriptPubkeys
|
||||
^ values
|
||||
```
|
||||
|
||||
* in/output selector byte
|
||||
|
||||
"leading 3 in/outputs"
|
||||
```
|
||||
1 0 0 0 0 0 1 1
|
||||
| | | <-------> integer 0b00011 == 3
|
||||
| | ^ index size: single byte
|
||||
| ^ leading mode
|
||||
^ commit the number of in/outputs
|
||||
```
|
||||
|
||||
"leading 257 in/outputs"
|
||||
```
|
||||
1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1
|
||||
| | | <------------------------> integer 0b00001 00000001 == 257
|
||||
| | ^ index size 1: two bytes
|
||||
| ^ leading mode
|
||||
^ commit the number of in/outputs
|
||||
```
|
||||
|
||||
"indices 1 and 3"
|
||||
```
|
||||
0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1
|
||||
| | | | <--------------> second idx: 3
|
||||
| | | | <-------------> first idx: 1
|
||||
| | | | <-----> selection count: 0b0010 == 2 indices
|
||||
| | | ^ index size: single byte per index
|
||||
| | ^ absolute index
|
||||
| ^ individual mode
|
||||
^ don't commit the number of in/outputs
|
||||
```
|
||||
|
||||
* total example
|
||||
|
||||
```
|
||||
ff ff c2 01 03 83
|
||||
| | ^ commit number of outputs + leading 3 outputs
|
||||
| | <------> commit number of inputs + inputs at indices 1 and 3
|
||||
| ^ all input and output fields
|
||||
^ all regular fields
|
||||
```
|
||||
|
||||
|
||||
## Resource limits
|
||||
|
||||
Using the same validation budget ("sigops budget") introduced in BIP-0342,
|
||||
each TransactionHash decreases the validation budget by 25. If this brings the
|
||||
budget below zero, the script fails immediately.<br>The following
|
||||
considerations should be made:
|
||||
|
||||
* All fields that can be of arbitrary size are cacheable as TransactionHash
|
||||
always hashes their hashed values.
|
||||
* In "individual mode", a user can at most commit 32 inputs or outputs,
|
||||
which we don't consider excessive for potential repeated use.
|
||||
* In "leading mode", a caching strategy can be used where the SHA256 context
|
||||
is stored every N in/outputs so that multiple executions of the
|
||||
TransactionHash function can use the caches and only have to hash an
|
||||
additional N-1 items at most.
|
||||
|
||||
|
||||
# Motivation
|
||||
|
||||
This BIP specifies a basic transaction introspection primitive that is useful
|
||||
to either reduce interactivity in multi-user protocols or to enforce some basic
|
||||
constraints on transactions.
|
||||
|
||||
Additionally, the constructions specified in this BIP can lay the groundwork for
|
||||
some potential future upgrades:
|
||||
* The TxFieldSelector construction would work well with a hypothetical opcode
|
||||
`OP_TX` that allows for directly introspecting the transaction by putting the
|
||||
fields selected on the stack instead of hashing them together.
|
||||
* The TransactionHash obtained by `OP_TXHASH` can be combined with `OP_CHECKSIGFROMSTACK`
|
||||
(see [BIP-348](bip-0348.md)) to effectively create an
|
||||
incredibly flexible signature hash, which would enable constructions like
|
||||
`SIGHASH_ANYPREVOUT`.
|
||||
* The TransactionHash obtained by `OP_TXHASH` can be introduced as a native
|
||||
sighash calculation in a future segwit upgrade, so that signatures using the
|
||||
TransactionHash as their sighash can be used in keyspend context.
|
||||
|
||||
|
||||
## Comparing with some alternative proposals
|
||||
|
||||
* This proposal strictly generalizes BIP-119's `OP_CHECKTEMPLATEVERIFY`, as the
|
||||
default mode of our TxFieldSelector is semantically the same (though not
|
||||
byte-for-byte identical) as what `OP_CTV` accomplishes, without costing any
|
||||
additional bytes. Additionally, using `OP_TXHASH` allows for more
|
||||
flexibility which can help in the case for
|
||||
* enabling adding fees to a transaction without breaking a multi-tx protocol;
|
||||
* multi-user protocols where users are only concerned about their own inputs and outputs.
|
||||
|
||||
* Constructions like `OP_IN_OUT_VALUE` used with `OP_EQUALVERIFY` can be
|
||||
emulated by two `OP_TXHASH` instances by using the TxFieldSelector to select
|
||||
a single input value first and a single output value second and enforcing
|
||||
equality on the hashes. Neither of these alternatives can be used to enforce
|
||||
small value differences without the availability of 64-bit arithmetic in
|
||||
Script.
|
||||
|
||||
* Like mentioned above, `SIGHASH_ANYPREVOUT` can be emulated using `OP_TXHASH`
|
||||
when combined with `OP_CHECKSIGFROMSTACK`:
|
||||
`<txfs> OP_TXHASH <pubkey> OP_CHECKSIGFROMSTACK` effectively emulates `SIGHASH_ANYPREVOUT`.
|
||||
|
||||
|
||||
# Reference Implementation
|
||||
|
||||
A reference implementation in Rust is provided attached as part of this BIP
|
||||
together with a JSON file of test vectors generated using the reference
|
||||
implementation.
|
||||
|
||||
|
||||
# Design Considerations
|
||||
|
||||
This specification in in _Draft_ and there is definitely still room for feedback
|
||||
and improvements. Some considerations that were made but could be revisited:
|
||||
|
||||
- The `0b10` in/output selector for the shorthand is unused.
|
||||
Could possibly be filled in with "current + next", "current + previous" or
|
||||
any other semantics.
|
||||
- The individual index selection semantics allow for absolute indices up to ~32k
|
||||
and relative ones up to +/- ~16k, which is probably excessive. When removing
|
||||
the second byte there would reduce that to just 256 and +/- 128 respectively.
|
||||
- Similar to `OP_TEMPLATEHASH` (BIP number to be assigned, [PR](https://github.com/bitcoin/bips/pull/1974)),
|
||||
we could not support `scriptSigs` anymore and remove
|
||||
`TXFS_INPUTS_SCRIPTSIGS`. This field could then possibly be repurposed.
|
||||
|
||||
|
||||
# Backwards Compatibility
|
||||
|
||||
`OP_TXHASH` replaces `OP_SUCCESS189`. The `SUCCESS` opcodes were
|
||||
introduced in taproot (BIP-342) to support changing the semantics of opcodes in
|
||||
ways that do allow the new semantics to change the stack. For this reason,
|
||||
`OP_TXHASH` only works in tapscript context. Since it is overriding a `SUCCESS`
|
||||
opcode, any older version of the software will always accept any script that
|
||||
uses the opcode, while the new versions of the software will validate the
|
||||
scripts according to the semantics outlined in this BIP. As such, this is also a
|
||||
soft fork change.
|
||||
|
||||
## Interactions with other BIPs
|
||||
|
||||
This proposal interacts with several other BIPs:
|
||||
|
||||
* **[BIP-118](bip-0118.mediawiki) (SIGHASH_ANYPREVOUT)**: `OP_TXHASH` can be combined with
|
||||
`OP_CHECKSIGFROMSTACK` (BIP-348) to emulate `SIGHASH_ANYPREVOUT` and other
|
||||
signature hash modes defined in BIP-118. The 1-byte TxFieldSelector format
|
||||
explicitly supports these modes.
|
||||
|
||||
* **[BIP-119](bip-0119.mediawiki) (OP_CHECKTEMPLATEVERIFY)**: `OP_TXHASH` with the empty
|
||||
TxFieldSelector produces a hash semantically equivalent to BIP-119's
|
||||
`OP_CHECKTEMPLATEVERIFY`, making this proposal a generalization of BIP-119.
|
||||
|
||||
* **[BIP-347](bip-0347.mediawiki) (OP_CAT)**: When combined with `OP_CAT`, `OP_TXHASH` enables
|
||||
powerful transaction introspection capabilities. The bit encoding format is
|
||||
designed to be explicit about endianness to ensure correct interaction with
|
||||
concatenation operations.
|
||||
|
||||
* **[BIP-348](bip-0348.md) (OP_CHECKSIGFROMSTACK)**: Together with `OP_CHECKSIGFROMSTACK`,
|
||||
`OP_TXHASH` provides a fully generalized signature hash construction,
|
||||
enabling flexible covenant designs and multi-user protocols.
|
||||
|
||||
|
||||
# Implementation
|
||||
|
||||
A reference implementation is included as part of the BIP, see
|
||||
[here](./bip-0346/ref-impl/src/main.rs). This implementation focusses on clarity
|
||||
and correctness, not on efficiency. A rudimentary set of test vectors is also
|
||||
generated from this implementation and included
|
||||
[here](./bip-0346/ref-impl/txhash_vectors.json).
|
||||
|
||||
Furthermore, following other implementation attempts exist:
|
||||
|
||||
* A proposed implementation for Bitcoin Core is available here:
|
||||
https://github.com/bitcoin/bitcoin/pull/29050
|
||||
* A proposed implementation for rust-bitcoin is available here:
|
||||
https://github.com/rust-bitcoin/rust-bitcoin/pull/2275
|
||||
|
||||
NOTE: These implementations are slightly outdated as they were made for an
|
||||
earlier version of this specification. Updates are in progress.
|
||||
|
||||
Both of the above implementations perform effective caching to avoid potential
|
||||
denial-of-service attack vectors.
|
||||
|
||||
|
||||
# Deployment
|
||||
|
||||
This BIP can be deployed using a BIP 9 VersionBits deployment. The specific
|
||||
strategy and bit assignment are left unspecified and can later be amended to the
|
||||
BIP depending on community preference.
|
||||
|
||||
|
||||
# Acknowledgement
|
||||
|
||||
Credit for this proposal mostly goes to Jeremy Rubin for his work on BIP-119's
|
||||
`OP_CHECKTEMPLATEVERIFY` and to Russell O'Connor for the original idea of
|
||||
generalizing `OP_CHECKTEMPLATEVERIFY` into `OP_TXHASH`.
|
||||
|
||||
Additional thanks to Andrew Poelstra, Greg Sanders, Rearden Code, Rusty Russell
|
||||
and others for their feedback on the specification.
|
||||
|
||||
|
||||
# Copyright
|
||||
|
||||
This document is licensed under the 3-clause BSD license.
|
||||
|
||||
Reference in New Issue
Block a user