diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..732da86f7a
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.mediawiki linguist-detectable
diff --git a/.github/workflows/github-action-checks.yml b/.github/workflows/github-action-checks.yml
new file mode 100644
index 0000000000..ad76317f96
--- /dev/null
+++ b/.github/workflows/github-action-checks.yml
@@ -0,0 +1,31 @@
+name: GitHub Actions Check
+run-name: ${{ github.actor }} Checks 🚀
+on: [push, pull_request]
+jobs:
+ Link-Format-Checks:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - run: scripts/link-format-chk.sh
+ Build-Table-Checks:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - run: scripts/buildtable.pl >/tmp/table.mediawiki || exit 1
+ Diff-Checks:
+ name: "Diff Checks (fails until number assignment)"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 2
+ - run: scripts/diffcheck.sh
+ Typo-Checks:
+ name: "Typo Checks"
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Actions Repository
+ uses: actions/checkout@v4
+
+ - name: Check spelling
+ uses: crate-ci/typos@master
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..d939d2a572
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+bip-0174/coinjoin-workflow.aux
+bip-0174/coinjoin-workflow.log
+bip-0174/coinjoin-workflow.pdf
+bip-0174/multisig-workflow.aux
+bip-0174/multisig-workflow.log
+bip-0174/multisig-workflow.pdf
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 70d339ae65..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-os: linux
-language: generic
-script:
- - scripts/link-format-chk.sh
- - scripts/buildtable.pl >/tmp/table.mediawiki || exit 1
- - diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/after.diff || true
- - if git checkout HEAD^ && scripts/buildtable.pl >/tmp/table.mediawiki 2>/dev/null; then diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/before.diff || true; newdiff=$(diff -s /tmp/before.diff /tmp/after.diff -u | grep '^+'); if [ -n "$newdiff" ]; then echo "$newdiff"; exit 1; fi; else echo 'Cannot build previous commit table for comparison'; fi
diff --git a/.typos.toml b/.typos.toml
new file mode 100644
index 0000000000..15d831fa1e
--- /dev/null
+++ b/.typos.toml
@@ -0,0 +1,44 @@
+[default]
+extend-ignore-re = [
+ # NOTE: use here for regex patterns
+ "xpub.*",
+ "xprv.*",
+ "3.*", # address
+ "5.*", # address
+ "private_key .*",
+ "privkey .*",
+ "tt.*", # tags
+ "code.*", # tags
+ "\\w*", # prefix for tags
+ "OP_SUCCESSx|\\d+",
+ "pay.*",
+ "ser.*",
+ "prefix.*",
+ "value: .*",
+]
+
+[default.extend-words]
+# NOTE: use here for false-positives
+anc = "anc"
+PSBT = "PSBT"
+ser = "ser"
+# Names
+Atack = "Atack"
+Meni = "Meni"
+Ono = "Ono"
+
+[files]
+extend-exclude = [
+ "/*/*.csv",
+ "/*.d*",
+ "/*/*.d*",
+ "/*/*.go",
+ "/*/*.json",
+ "/*/*/*.json",
+ "/*/*.mod",
+ "/*/*.proto",
+ "/*/*.py",
+ "scripts",
+ "/*/*.s*",
+ "/*/*.t*",
+]
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..df6d947a5a
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,12 @@
+# Contributing Guidelines
+
+Apart from following [BIP 2](./bip-0002.mediawiki),
+we do CI checks to ensure that the proposed BIPs do not have common typos.
+These checks are done using [`typos`](https://github.com/crate-ci/typos).
+To check for typos locally,
+install [`typos`](https://github.com/crate-ci/typos)
+and then run in the root directory:
+
+```bash
+typos
+```
diff --git a/README.mediawiki b/README.mediawiki
index ce21e2e48c..c2ded8de71 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -1,4 +1,4 @@
-People wishing to submit BIPs, first should propose their idea or document to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev bitcoin-dev@lists.linuxfoundation.org] mailing list (do not assign a number - read BIP 2 for the full process). After discussion, please open a PR. After copy-editing and acceptance, it will be published here.
+People wishing to submit BIPs, first should propose their idea or document to the [https://groups.google.com/g/bitcoindev bitcoindev@googlegroups.com] mailing list (do not assign a number - read BIP 2 for the full process). After discussion, please open a PR. After copy-editing and acceptance, it will be published here.
We are fairly liberal with approving BIPs, and try not to be too involved in decision making on behalf of the community. The exception is in very rare cases of dispute resolution when a decision is contentious and cannot be agreed upon. In those cases, the conservative option will always be preferred.
@@ -27,6 +27,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Luke Dashjr
| Process
| Active
+|- style="background-color: #ffffcf"
+| [[bip-0003.md|3]]
+|
+| Updated BIP Process
+| Murch
+| Process
+| Proposed
|-
| [[bip-0008.mediawiki|8]]
|
@@ -202,13 +209,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Mike Caldwell, Aaron Voisine
| Standard
| Draft
-|- style="background-color: #ffffcf"
+|- style="background-color: #cfffcf"
| [[bip-0039.mediawiki|39]]
| Applications
| Mnemonic code for generating deterministic keys
| Marek Palatinus, Pavol Rusnak, Aaron Voisine, Sean Bowe
| Standard
-| Proposed
+| Final
|-
| 40
| API/RPC
@@ -235,15 +242,15 @@ Those proposing changes should consider that ultimately consent may rest with th
| Applications
| Purpose Field for Deterministic Wallets
| Marek Palatinus, Pavol Rusnak
-| Informational
+| Standard
| Final
-|- style="background-color: #ffffcf"
+|- style="background-color: #cfffcf"
| [[bip-0044.mediawiki|44]]
| Applications
| Multi-Account Hierarchy for Deterministic Wallets
| Marek Palatinus, Pavol Rusnak
| Standard
-| Proposed
+| Final
|- style="background-color: #ffffcf"
| [[bip-0045.mediawiki|45]]
| Applications
@@ -252,18 +259,32 @@ Those proposing changes should consider that ultimately consent may rest with th
| Standard
| Proposed
|-
+| [[bip-0046.mediawiki|46]]
+| Applications
+| Address Scheme for Timelocked Fidelity Bonds
+| Chris Belcher, Thebora Kompanioni
+| Standard
+| Draft
+|- style="background-color: #cfffcf"
| [[bip-0047.mediawiki|47]]
| Applications
| Reusable Payment Codes for Hierarchical Deterministic Wallets
| Justus Ranvier
| Informational
-| Draft
+| Final
+|- style="background-color: #ffffcf"
+| [[bip-0048.mediawiki|48]]
+| Applications
+| Multi-Script Hierarchy for Multi-Sig Wallets
+| Fontaine
+| Standard
+| Proposed
|- style="background-color: #cfffcf"
| [[bip-0049.mediawiki|49]]
| Applications
| Derivation scheme for P2WPKH-nested-in-P2SH based accounts
| Daniel Weigl
-| Informational
+| Standard
| Final
|- style="background-color: #cfffcf"
| [[bip-0050.mediawiki|50]]
@@ -272,14 +293,28 @@ Those proposing changes should consider that ultimately consent may rest with th
| Gavin Andresen
| Informational
| Final
-
|-
+| [[bip-0052.mediawiki|52]]
+| Consensus (hard fork)
+| Durable, Low Energy Bitcoin PoW
+| Michael Dubrovsky, Bogdan Penkovsky
+| Standard
+| Draft
+|-
+| [[bip-0054.md|54]]
+| Consensus (soft fork)
+| Consensus Cleanup
+| Antoine Poinsot, Matt Corallo
+| Standard
+| Draft
+
+|- style="background-color: #ffcfcf"
| [[bip-0060.mediawiki|60]]
| Peer Services
| Fixed Length "version" Message (Relay-Transactions Field)
| Amir Taaki
| Standard
-| Draft
+| Rejected
|- style="background-color: #cfffcf"
| [[bip-0061.mediawiki|61]]
| Peer Services
@@ -420,27 +455,27 @@ Those proposing changes should consider that ultimately consent may rest with th
| Eric Lombrozo
| Standard
| Rejected
-|-
+|- style="background-color: #cfffcf"
| [[bip-0084.mediawiki|84]]
| Applications
| Derivation scheme for P2WPKH based accounts
| Pavol Rusnak
-| Informational
-| Draft
-|-
+| Standard
+| Final
+|- style="background-color: #cfffcf"
| [[bip-0085.mediawiki|85]]
| Applications
| Deterministic Entropy From BIP32 Keychains
-| Ethan Kosakovsky
+| Ethan Kosakovsky, Aneesh Karve
| Informational
-| Draft
-|-
+| Final
+|- style="background-color: #cfffcf"
| [[bip-0086.mediawiki|86]]
| Applications
| Key Derivation for Single Key P2TR Outputs
-| Andrew Chow
+| Ava Chow
| Standard
-| Draft
+| Final
|- style="background-color: #ffffcf"
| [[bip-0087.mediawiki|87]]
| Applications
@@ -470,6 +505,20 @@ Those proposing changes should consider that ultimately consent may rest with th
| Standard
| Final
|-
+| [[bip-0093.mediawiki|93]]
+| Applications
+| codex32: Checksummed SSSS-aware BIP32 seeds
+| Leon Olsson Curr, Pearlwort Sneed, Andrew Poelstra
+| Informational
+| Draft
+|- style="background-color: #cfffcf"
+| [[bip-0094.mediawiki|94]]
+| Applications
+| Testnet 4
+| Fabian Jahr
+| Standard
+| Final
+|-
| [[bip-0098.mediawiki|98]]
| Consensus (soft fork)
| Fast Merkle Trees
@@ -644,13 +693,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Eric Lombrozo, William Swanson
| Informational
| Rejected
-|- style="background-color: #ffffcf"
+|- style="background-color: #cfffcf"
| [[bip-0125.mediawiki|125]]
| Applications
| Opt-in Full Replace-by-Fee Signaling
| David A. Harding, Peter Todd
| Standard
-| Proposed
+| Final
|-
| [[bip-0126.mediawiki|126]]
|
@@ -672,13 +721,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Hugo Nguyen, Peter Gray, Marko Bencun, Aaron Chen, Rodolfo Novak
| Standard
| Proposed
-|- style="background-color: #ffffcf"
+|- style="background-color: #cfffcf"
| [[bip-0130.mediawiki|130]]
| Peer Services
| sendheaders message
| Suhas Daftuar
| Standard
-| Proposed
+| Final
|- style="background-color: #ffcfcf"
| [[bip-0131.mediawiki|131]]
| Consensus (hard fork)
@@ -693,13 +742,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Andy Chase
| Process
| Withdrawn
-|-
+|- style="background-color: #cfffcf"
| [[bip-0133.mediawiki|133]]
| Peer Services
| feefilter message
| Alex Morcos
| Standard
-| Draft
+| Final
|- style="background-color: #ffcfcf"
| [[bip-0134.mediawiki|134]]
| Consensus (hard fork)
@@ -804,14 +853,14 @@ Those proposing changes should consider that ultimately consent may rest with th
| Peer Authentication
| Jonas Schnelli
| Standard
-| Draft
+| Deferred
|- style="background-color: #ffcfcf"
| [[bip-0151.mediawiki|151]]
| Peer Services
| Peer-to-Peer Communication Encryption
| Jonas Schnelli
| Standard
-| Withdrawn
+| Replaced
|- style="background-color: #cfffcf"
| [[bip-0152.mediawiki|152]]
| Peer Services
@@ -854,13 +903,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Olaoluwa Osuntokun, Alex Akselrod
| Standard
| Draft
-|-
+|- style="background-color: #cfffcf"
| [[bip-0159.mediawiki|159]]
| Peer Services
| NODE_NETWORK_LIMITED service bit
| Jonas Schnelli
| Standard
-| Draft
+| Final
|- style="background-color: #ffcfcf"
| [[bip-0171.mediawiki|171]]
| Applications
@@ -868,6 +917,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Luke Dashjr
| Standard
| Rejected
+|-
+| [[bip-0172.mediawiki|172]]
+| Applications
+| Define Bitcoin Subunits as Satoshis
+| OceanSlim
+| Informational
+| Draft
|- style="background-color: #cfffcf"
| [[bip-0173.mediawiki|173]]
| Applications
@@ -879,7 +935,7 @@ Those proposing changes should consider that ultimately consent may rest with th
| [[bip-0174.mediawiki|174]]
| Applications
| Partially Signed Bitcoin Transaction Format
-| Andrew Chow
+| Ava Chow
| Standard
| Final
|- style="background-color: #ffcfcf"
@@ -897,6 +953,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Informational
| Draft
|-
+| [[bip-0177.mediawiki|177]]
+|
+| Redefine Bitcoin's Base Unit
+| John Carvalho
+| Informational
+| Draft
+|-
| [[bip-0178.mediawiki|178]]
| Applications
| Version Extended WIF
@@ -907,7 +970,7 @@ Those proposing changes should consider that ultimately consent may rest with th
| [[bip-0179.mediawiki|179]]
|
| Name for payment recipient identifiers
-| Emil Engler, MarcoFalke, Luke Dashjr
+| Emil Engler, Luke Dashjr
| Informational
| Draft
|- style="background-color: #ffcfcf"
@@ -924,13 +987,13 @@ Those proposing changes should consider that ultimately consent may rest with th
| Matthew Black, Tony Cai
| Standard
| Draft
-|-
+|- style="background-color: #ffcfcf"
| [[bip-0199.mediawiki|199]]
| Applications
| Hashed Time-Locked Contract transactions
| Sean Bowe, Daira Hopwood
| Standard
-| Draft
+| Rejected
|-
| [[bip-0300.mediawiki|300]]
| Consensus (soft fork)
@@ -960,12 +1023,26 @@ Those proposing changes should consider that ultimately consent may rest with th
| Standard
| Draft
|-
+| [[bip-0321.mediawiki|321]]
+| Applications
+| URI Scheme
+| Matt Corallo
+| Standard
+| Draft
+|-
| [[bip-0322.mediawiki|322]]
| Applications
| Generic Signed Message Format
| Karl-Johan Alm
| Standard
| Draft
+|- style="background-color: #cfffcf"
+| [[bip-0324.mediawiki|324]]
+| Peer Services
+| Version 2 P2P Encrypted Transport Protocol
+| Dhruv Mehta, Tim Ruffing, Jonas Schnelli, Pieter Wuille
+| Standard
+| Final
|- style="background-color: #ffffcf"
| [[bip-0325.mediawiki|325]]
| Applications
@@ -974,6 +1051,34 @@ Those proposing changes should consider that ultimately consent may rest with th
| Standard
| Proposed
|-
+| [[bip-0326.mediawiki|326]]
+| Applications
+| Anti-fee-sniping in taproot transactions
+| Chris Belcher
+| Informational
+| Draft
+|- style="background-color: #cfffcf"
+| [[bip-0327.mediawiki|327]]
+|
+| MuSig2 for BIP340-compatible Multi-Signatures
+| Jonas Nick, Tim Ruffing, Elliott Jin
+| Informational
+| Active
+|- style="background-color: #ffffcf"
+| [[bip-0328.mediawiki|328]]
+| Applications
+| Derivation Scheme for MuSig2 Aggregate Keys
+| Ava Chow
+| Informational
+| Proposed
+|-
+| [[bip-0329.mediawiki|329]]
+| Applications
+| Wallet Labels Export Format
+| Craig Raw
+| Informational
+| Draft
+|-
| [[bip-0330.mediawiki|330]]
| Peer Services
| Transaction announcements reconciliation
@@ -981,59 +1086,255 @@ Those proposing changes should consider that ultimately consent may rest with th
| Standard
| Draft
|-
+| [[bip-0331.mediawiki|331]]
+| Peer Services
+| Ancestor Package Relay
+| Gloria Zhao
+| Standard
+| Draft
+|-
+| [[bip-0337.mediawiki|337]]
+| API/RPC
+| Compressed Transactions
+| Tom Briar
+| Standard
+| Draft
+|- style="background-color: #ffcfcf"
| [[bip-0338.mediawiki|338]]
| Peer Services
| Disable transaction relay message
| Suhas Daftuar
| Standard
-| Draft
-|-
+| Withdrawn
+|- style="background-color: #cfffcf"
| [[bip-0339.mediawiki|339]]
| Peer Services
| WTXID-based transaction relay
| Suhas Daftuar
| Standard
-| Draft
-|-
+| Final
+|- style="background-color: #cfffcf"
| [[bip-0340.mediawiki|340]]
|
| Schnorr Signatures for secp256k1
| Pieter Wuille, Jonas Nick, Tim Ruffing
| Standard
-| Draft
-|-
+| Final
+|- style="background-color: #cfffcf"
| [[bip-0341.mediawiki|341]]
| Consensus (soft fork)
| Taproot: SegWit version 1 spending rules
| Pieter Wuille, Jonas Nick, Anthony Towns
| Standard
-| Draft
-|-
+| Final
+|- style="background-color: #cfffcf"
| [[bip-0342.mediawiki|342]]
| Consensus (soft fork)
| Validation of Taproot Scripts
| Pieter Wuille, Jonas Nick, Anthony Towns
| Standard
-| Draft
-|- style="background-color: #ffffcf"
+| Final
+|- style="background-color: #cfffcf"
| [[bip-0343.mediawiki|343]]
| Consensus (soft fork)
| Mandatory activation of taproot deployment
| Shinobius, Michael Folkson
| Standard
-| Proposed
+| Final
+|- style="background-color: #ffcfcf"
+| [[bip-0345.mediawiki|345]]
+| Consensus (soft fork)
+| OP_VAULT
+| James O'Beirne, Greg Sanders
+| Standard
+| Withdrawn
+|-
+| [[bip-0347.mediawiki|347]]
+| Consensus (soft fork)
+| OP_CAT in Tapscript
+| Ethan Heilman, Armin Sabouri
+| Standard
+| Draft
|-
+| [[bip-0348.md|348]]
+| Consensus (soft fork)
+| CHECKSIGFROMSTACK
+| Brandon Black, Jeremy Rubin
+| Standard
+| Draft
+|-
+| [[bip-0349.md|349]]
+| Consensus (soft fork)
+| OP_INTERNALKEY
+| Brandon Black, Jeremy Rubin
+| Standard
+| Draft
+|- style="background-color: #cfffcf"
| [[bip-0350.mediawiki|350]]
| Applications
| Bech32m format for v1+ witness addresses
| Pieter Wuille
| Standard
+| Final
+|-
+| [[bip-0351.mediawiki|351]]
+| Applications
+| Private Payments
+| Alfred Hodler, Clark Moody
+| Informational
| Draft
+|- style="background-color: #ffffcf"
+| [[bip-0352.mediawiki|352]]
+| Applications
+| Silent Payments
+| josibake, Ruben Somsen
+| Standard
+| Proposed
|-
+| [[bip-0353.mediawiki|353]]
+| Applications
+| DNS Payment Instructions
+| Matt Corallo, Bastien Teinturier
+| Standard
+| Draft
+|- style="background-color: #cfffcf"
| [[bip-0370.mediawiki|370]]
| Applications
| PSBT Version 2
-| Andrew Chow
+| Ava Chow
+| Standard
+| Final
+|- style="background-color: #cfffcf"
+| [[bip-0371.mediawiki|371]]
+| Applications
+| Taproot Fields for PSBT
+| Ava Chow
+| Standard
+| Final
+|-
+| [[bip-0372.mediawiki|372]]
+| Applications
+| Pay-to-contract tweak fields for PSBT
+| Maxim Orlovsky
+| Standard
+| Draft
+|- style="background-color: #ffffcf"
+| [[bip-0373.mediawiki|373]]
+| Applications
+| MuSig2 PSBT Fields
+| Ava Chow
+| Standard
+| Proposed
+|-
+| [[bip-0374.mediawiki|374]]
+| Applications
+| Discrete Log Equality Proofs
+| Andrew Toth, Ruben Somsen, Sebastian Falbesoner
+| Standard
+| Draft
+|-
+| [[bip-0375.mediawiki|375]]
+| Applications
+| Sending Silent Payments with PSBTs
+| Andrew Toth, Ava Chow, josibake
+| Standard
+| Draft
+|-
+| [[bip-0379.md|379]]
+| Applications
+| Miniscript
+| Pieter Wuille, Andrew Poelstra, Sanket Kanjalkar, Antoine Poinsot, Ava Chow
+| Informational
+| Draft
+|- style="background-color: #cfffcf"
+| [[bip-0380.mediawiki|380]]
+| Applications
+| Output Script Descriptors General Operation
+| Pieter Wuille, Ava Chow
+| Informational
+| Final
+|- style="background-color: #cfffcf"
+| [[bip-0381.mediawiki|381]]
+| Applications
+| Non-Segwit Output Script Descriptors
+| Pieter Wuille, Ava Chow
+| Informational
+| Final
+|- style="background-color: #cfffcf"
+| [[bip-0382.mediawiki|382]]
+| Applications
+| Segwit Output Script Descriptors
+| Pieter Wuille, Ava Chow
+| Informational
+| Final
+|- style="background-color: #cfffcf"
+| [[bip-0383.mediawiki|383]]
+| Applications
+| Multisig Output Script Descriptors
+| Pieter Wuille, Ava Chow
+| Informational
+| Final
+|- style="background-color: #cfffcf"
+| [[bip-0384.mediawiki|384]]
+| Applications
+| combo() Output Script Descriptors
+| Pieter Wuille, Ava Chow
+| Informational
+| Final
+|- style="background-color: #cfffcf"
+| [[bip-0385.mediawiki|385]]
+| Applications
+| raw() and addr() Output Script Descriptors
+| Pieter Wuille, Ava Chow
+| Informational
+| Final
+|- style="background-color: #cfffcf"
+| [[bip-0386.mediawiki|386]]
+| Applications
+| tr() Output Script Descriptors
+| Pieter Wuille, Ava Chow
+| Informational
+| Final
+|- style="background-color: #cfffcf"
+| [[bip-0387.mediawiki|387]]
+| Applications
+| Tapscript Multisig Output Script Descriptors
+| Pieter Wuille, Ava Chow
+| Informational
+| Final
+|- style="background-color: #ffffcf"
+| [[bip-0388.mediawiki|388]]
+| Applications
+| Wallet Policies for Descriptor Wallets
+| Salvatore Ingala
+| Standard
+| Proposed
+|-
+| [[bip-0389.mediawiki|389]]
+| Applications
+| Multipath Descriptor Key Expressions
+| Ava Chow
+| Informational
+| Draft
+|-
+| [[bip-0390.mediawiki|390]]
+| Applications
+| musig() Descriptor Key Expression
+| Ava Chow
+| Informational
+| Draft
+|-
+| [[bip-0431.mediawiki|431]]
+| Applications
+| Topology Restrictions for Pinning
+| Gloria Zhao
+| Informational
+| Draft
+|-
+| [[bip-0443.mediawiki|443]]
+| Consensus (soft fork)
+| OP_CHECKCONTRACTVERIFY
+| Salvatore Ingala
| Standard
| Draft
|}
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000000..034e848032
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,21 @@
+# Security Policy
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version | Supported |
+| ------- | ------------------ |
+| 5.1.x | :white_check_mark: |
+| 5.0.x | :x: |
+| 4.0.x | :white_check_mark: |
+| < 4.0 | :x: |
+
+## Reporting a Vulnerability
+
+Use this section to tell people how to report a vulnerability.
+
+Tell them where to go, how often they can expect to get an update on a
+reported vulnerability, what to expect if the vulnerability is accepted or
+declined, etc.
diff --git a/bip-0001.mediawiki b/bip-0001.mediawiki
index 7067f64b30..40fe99ca9e 100644
--- a/bip-0001.mediawiki
+++ b/bip-0001.mediawiki
@@ -23,7 +23,7 @@ Because the BIPs are maintained as text files in a versioned repository, their r
There are three kinds of BIP:
* A Standards Track BIP describes any change that affects most or all Bitcoin implementations, such as a change to the network protocol, a change in block or transaction validity rules, or any change or addition that affects the interoperability of applications using Bitcoin.
-* An Informational BIP describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementors are free to ignore Informational BIPs or follow their advice.
+* An Informational BIP describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementers are free to ignore Informational BIPs or follow their advice.
* A Process BIP describes a process surrounding Bitcoin, or proposes a change to (or an event in) a process. Process BIPs are like Standards Track BIPs but apply to areas other than the Bitcoin protocol itself. They may propose an implementation, but not to Bitcoin's codebase; they often require community consensus; unlike Informational BIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Bitcoin development. Any meta-BIP is also considered a Process BIP.
==BIP Work Flow==
diff --git a/bip-0002.mediawiki b/bip-0002.mediawiki
index c6eb950fec..fd390c4ff3 100644
--- a/bip-0002.mediawiki
+++ b/bip-0002.mediawiki
@@ -32,13 +32,13 @@ The BIP process begins with a new idea for Bitcoin. Each potential BIP must have
Small enhancements or patches to a particular piece of software often don't require standardisation between multiple projects; these don't need a BIP and should be injected into the relevant project-specific development workflow with a patch submission to the applicable issue tracker.
Additionally, many ideas have been brought forward for changing Bitcoin that have been rejected for various reasons.
The first step should be to search past discussions to see if an idea has been considered before, and if so, what issues arose in its progression.
-After investigating past work, the best way to proceed is by posting about the new idea to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev Bitcoin development mailing list].
+After investigating past work, the best way to proceed is by posting about the new idea to the [https://groups.google.com/g/bitcoindev Bitcoin development mailing list].
Vetting an idea publicly before going as far as writing a BIP is meant to save both the potential author and the wider community time.
Asking the Bitcoin community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the internet does not always do the trick).
It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Bitcoin is used.
-Once the champion has asked the Bitcoin community as to whether an idea has any chance of acceptance, a draft BIP should be presented to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev Bitcoin development mailing list].
+Once the champion has asked the Bitcoin community as to whether an idea has any chance of acceptance, a draft BIP should be presented to the [https://groups.google.com/g/bitcoindev Bitcoin development mailing list].
This gives the author a chance to flesh out the draft BIP to make it properly formatted, of high quality, and to address additional concerns about the proposal.
Following a discussion, the proposal should be submitted to the [https://github.com/bitcoin/bips BIPs git repository] as a pull request.
This draft must be written in BIP style as described below, and named with an alias such as "bip-johndoe-infinitebitcoins" until an editor has assigned it a BIP number (authors MUST NOT self-assign BIP numbers).
@@ -67,8 +67,12 @@ If you are interested in assuming ownership of a BIP, send a message asking to t
The current BIP editors are:
+* Bryan Bishop ([[mailto:kanzure@gmail.com|kanzure@gmail.com]])
+* Jon Atack ([[mailto:jon@atack.com|jon@atack.com]])
* Luke Dashjr ([[mailto:luke_bipeditor@dashjr.org|luke_bipeditor@dashjr.org]])
-* Kalle Alm ([[mailto:karljohan-alm@garage.co.jp|karljohan-alm@garage.co.jp]])
+* Mark "Murch" Erhardt ([[mailto:murch@murch.one|murch@murch.one]])
+* Olaoluwa Osuntokun ([[mailto:laolu32@gmail.com|laolu32@gmail.com]])
+* Ruben Somsen ([[mailto:rsomsen@gmail.com|rsomsen@gmail.com]])
===BIP Editor Responsibilities & Workflow===
@@ -98,11 +102,13 @@ The BIP editor will:
The BIP editors are intended to fulfill administrative and editorial responsibilities. The BIP editors monitor BIP changes, and update BIP headers as appropriate.
+BIP editors may also, at their option, unilaterally make and merge strictly-editorial changes to BIPs, such as correcting misspellings, fixing broken links, etc.
+
==BIP format and structure==
===Specification===
-BIPs should be written in mediawiki format.
+BIPs should be written in mediawiki or markdown format.
Each BIP should have the following parts:
@@ -177,7 +183,7 @@ BIPs may include auxiliary files such as diagrams. Auxiliary files should be inc
There are three kinds of BIP:
* A Standards Track BIP describes any change that affects most or all Bitcoin implementations, such as a change to the network protocol, a change in block or transaction validity rules, or any change or addition that affects the interoperability of applications using Bitcoin. Standards Track BIPs consist of two parts, a design document and a reference implementation.
-* An Informational BIP describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementors are free to ignore Informational BIPs or follow their advice.
+* An Informational BIP describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementers are free to ignore Informational BIPs or follow their advice.
* A Process BIP describes a process surrounding Bitcoin, or proposes a change to (or an event in) a process. Process BIPs are like Standards Track BIPs but apply to areas other than the Bitcoin protocol itself. They may propose an implementation, but not to Bitcoin's codebase; they often require community consensus; unlike Informational BIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Bitcoin development. Any meta-BIP is also considered a Process BIP.
==BIP status field==
@@ -356,28 +362,28 @@ In this case, only the acceptable license(s) should be listed in the License and
* BSD-2-Clause: [https://opensource.org/licenses/BSD-2-Clause OSI-approved BSD 2-clause license]
* BSD-3-Clause: [https://opensource.org/licenses/BSD-3-Clause OSI-approved BSD 3-clause license]
* CC0-1.0: [https://creativecommons.org/publicdomain/zero/1.0/ Creative Commons CC0 1.0 Universal]
-* GNU-All-Permissive: [http://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html GNU All-Permissive License]
+* GNU-All-Permissive: [https://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html GNU All-Permissive License]
In addition, it is recommended that literal code included in the BIP be dual-licensed under the same license terms as the project it modifies. For example, literal code intended for Bitcoin Core would ideally be dual-licensed under the MIT license terms as well as one of the above with the rest of the BIP text.
====Not recommended, but acceptable licenses====
-* Apache-2.0: [http://www.apache.org/licenses/LICENSE-2.0 Apache License, version 2.0]
-* BSL-1.0: [http://www.boost.org/LICENSE_1_0.txt Boost Software License, version 1.0]
+* Apache-2.0: [https://www.apache.org/licenses/LICENSE-2.0 Apache License, version 2.0]
+* BSL-1.0: [https://www.boost.org/LICENSE_1_0.txt Boost Software License, version 1.0]
* CC-BY-4.0: [https://creativecommons.org/licenses/by/4.0/ Creative Commons Attribution 4.0 International]
* CC-BY-SA-4.0: [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0 International]
* MIT: [https://opensource.org/licenses/MIT Expat/MIT/X11 license]
-* AGPL-3.0+: [http://www.gnu.org/licenses/agpl-3.0.en.html GNU Affero General Public License (AGPL), version 3 or newer]
-* FDL-1.3: [http://www.gnu.org/licenses/fdl-1.3.en.html GNU Free Documentation License, version 1.3]
-* GPL-2.0+: [http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html GNU General Public License (GPL), version 2 or newer]
-* LGPL-2.1+: [http://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html GNU Lesser General Public License (LGPL), version 2.1 or newer]
+* AGPL-3.0+: [https://www.gnu.org/licenses/agpl-3.0.en.html GNU Affero General Public License (AGPL), version 3 or newer]
+* FDL-1.3: [https://www.gnu.org/licenses/fdl-1.3.en.html GNU Free Documentation License, version 1.3]
+* GPL-2.0+: [https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html GNU General Public License (GPL), version 2 or newer]
+* LGPL-2.1+: [https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html GNU Lesser General Public License (LGPL), version 2.1 or newer]
====Not acceptable licenses====
All licenses not explicitly included in the above lists are not acceptable terms for a Bitcoin Improvement Proposal unless a later BIP extends this one to add them.
However, BIPs predating the acceptance of this BIP were allowed under other terms, and should use these abbreviation when no other license is granted:
-* OPL: [http://opencontent.org/openpub/ Open Publication License, version 1.0]
+* OPL: [https://opencontent.org/openpub/ Open Publication License, version 1.0]
* PD: Released into the public domain
===Rationale===
@@ -409,7 +415,6 @@ Why is Public Domain no longer acceptable for new BIPs?
* Non-image auxiliary files are permitted in the bip-XXXX subdirectory.
* Email addresses are now required for authors.
* The Post-History header may be provided as a link instead of a simple date.
-* Markdown format is no longer permitted for BIPs.
* The Resolution header has been dropped, as it is not applicable to a decentralised system where no authority exists to make final decisions.
==See Also==
diff --git a/bip-0003.md b/bip-0003.md
new file mode 100644
index 0000000000..1624e50e65
--- /dev/null
+++ b/bip-0003.md
@@ -0,0 +1,754 @@
+```
+ BIP: 3
+ Title: Updated BIP Process
+ Author: Murch
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0003
+ Status: Proposed
+ Type: Process
+ Created: 2025-01-09
+ License: BSD-2-Clause
+ Post-History: https://github.com/murchandamus/bips/pull/2
+ https://gnusha.org/pi/bitcoindev/59fa94cea6f70e02b1ce0da07ae230670730171c.camel@timruffing.de/#t
+ Requires: 123
+ Replaces: 2
+```
+
+## Abstract
+
+This _Bitcoin Improvement Proposal (BIP)_ provides information about the preparation of BIPs and policies relating to
+the publication of BIPs. It replaces [BIP 2](bip-0002.mediawiki) with a streamlined process, and may be amended to
+address the evolving needs of the BIP process.
+
+## Motivation
+
+BIP 2 was written in 2016.
+This BIP revisits aspects of the BIP 2 process
+that did not achieve broad adoption, reduces the judgment calls assigned to the BIP Editor role, delineates the
+BIP Types more clearly, and generalizes the BIP process to meet the community’s use of the repository.
+
+## Fundamentals
+
+### What is a BIP?
+
+BIPs cover the range of interests of the Bitcoin[^capitalization] community. The main topic is information and technologies that support and expand the utility of the bitcoin
+currency. Most BIPs provide a concise, self-contained, technical description of one new concept, feature, or standard.
+Some BIPs describe processes, implementation guidelines, best practices, incident reports (e.g.,
+[BIP 50](bip-0050.mediawiki)), or other information relevant to the Bitcoin community. However, any topics related to
+the Bitcoin protocol, peer-to-peer network, and client software may be acceptable.
+
+BIPs are intended to be a means for proposing new protocol features, coordinating client standards, and
+documenting design decisions that have gone into implementations. BIPs may be submitted by anyone.
+
+The scope of the BIP
+repository is limited to BIPs that do not oppose the fundamental principle that Bitcoin constitutes a peer-to-peer
+electronic cash system for the bitcoin currency.
+
+### BIP Ownership
+
+Each BIP is primarily owned by its authors and represents the authors’ opinion or recommendation. The authors are
+expected to foster discussion, address feedback and dissenting opinions, and, if applicable, advance the adoption of
+their proposal within the Bitcoin community. As a BIP progresses through the workflow, it becomes increasingly
+ co-owned by the Bitcoin community.
+
+#### Authors and Deputies
+
+Authors may want additional help with the BIP process after writing an initial draft. In that case, they may assign
+one or more Deputies to their BIP. Deputies are stand-in owners of a BIP who were not involved in writing the
+document. They support the authors in advancing the proposal, or act as a point of contact for the BIP in the absence of the
+authors. Deputies may perform the role of Authors for any aspect of the BIP process unless overruled by an Author.
+Deputies share ownership of the BIP at the discretion of the Authors.
+
+### What is the Significance of BIPs?
+
+BIPs do not define what Bitcoin is: individual BIPs do not represent Bitcoin community consensus or a general
+recommendation for implementation. A BIP represents a personal recommendation by the BIP authors to the Bitcoin
+community. Some BIPs may never be adopted. Some BIPs may be adopted by one or more Bitcoin clients or other related
+software. Some may even end up changing the consensus rules that the Bitcoin ecosystem jointly enforces.
+
+### What is the Purpose of the BIPs Repository?
+
+The [BIPs repository](https://github.com/bitcoin/bips/) serves as a publication medium and archive for mature proposals.
+Through its high visibility, it facilitates the community-wide consideration of BIPs and provides a well-established
+source to retrieve the latest version of any BIP. The repository transparently records all changes to each BIP and
+allows any community member to retain a complete copy of the archive easily.
+
+The BIPs repository is not a tool to track acceptance[^acceptance], adoption, or community consensus on BIPs, beyond
+providing a brief overview of BIP statuses (see [Workflow](#workflow) below) to the audience.
+There is no formal or informal decision body that governs Bitcoin development or decides acceptance of BIPs. Bitcoin
+development emerges from the participation of stakeholders across the ecosystem.
+
+## BIP Format and Structure
+
+### Specification
+
+Authors may choose to submit BIPs in MediaWiki or Markdown[^markdown] format.
+
+Each BIP must have a _Preamble_, an _Abstract_, a _Copyright_, and a _Motivation_ section. Authors should consider all issues in the
+following list and address each as appropriate.
+
+* Preamble — Headers containing metadata about the BIP (see the section [BIP Header Preamble](#bip-header-preamble)
+ below).
+* Abstract — A short description of the issue being addressed.
+* Motivation — Why is this BIP being written? Clearly explain how the existing situation presents a problem and why the proposed idea resolves the
+ issue or improves upon the current situation.
+* Specification — The technical specification should describe the syntax and semantics of any new feature. The
+ specification should be detailed enough to enable any Bitcoin project to create an interoperable implementation.
+* Rationale — The rationale fleshes out the specification by describing what inspired the design and why particular
+ design decisions were made. It should describe related work and alternate designs that were considered. The rationale
+ should record relevant objections or important concerns that were raised and addressed as this proposal was developed.
+* Backward Compatibility — Any BIP that introduces incompatibilities must include a section describing these incompatibilities and their severity as well as provide instructions on how
+ implementers and users should deal with these incompatibilities.
+* Reference Implementation — Where applicable, a reference implementation, test vectors, and documentation must be
+ finished before the BIP can be given the status "Complete". Test vectors must be provided in the BIP or
+ as auxiliary files (see [Auxiliary Files](#auxiliary-files)) under an acceptable license. The reference implementation can be provided in the BIP, as an auxiliary file, or per reference to a pull request that is expected to remain available permanently.
+* Changelog — A section to track modifications to a BIP after reaching Complete status.
+* Copyright — The BIP must be placed under an acceptable license (see [BIP Licensing](#bip-licensing) below).
+
+#### BIP Header Preamble
+
+Each BIP must begin with an [RFC 822-style header preamble](https://www.w3.org/Protocols/rfc822/). The headers must
+appear in the following order. Headers marked with "\*" are optional. All other headers are required.
+
+##### Overview
+
+```
+ BIP:
+* Layer:
+ Title:
+ Authors:
+* Deputies:
+ Status:
+ Type:
+ Created:
+ License:
+* License-Code:
+* Discussion:
+* Version:
+* Requires:
+* Replaces:
+* Proposed-Replacement:
+```
+
+##### Header Descriptions
+
+* BIP — The assigned number of the BIP. Please use "?" before a number has been assigned by the BIP Editors.
+* Layer — The layer of Bitcoin the BIP applies to using the BIP classification defined in [BIP 123](bip-0123.mediawiki).
+* Authors — The names (or pseudonyms) and email addresses of all authors of the BIP. The format of each authors header
+ value must be
+
+ Random J. User
+
+ Multiple authors are recorded on separate lines:
+
+ Authors: Random J. User
+ Anata Sample
+
+* Deputies — Additional owners of the BIP that are not authors. The Deputies header uses the same format as the
+ Authors header. See the [BIP Ownership](#bip-ownership) section above.
+* Status — The stage of the workflow of the proposal. See the [Workflow](#workflow) section below.
+* Type — See the [BIP Types](#bip-types) section below for a description of the three BIP types.
+* License and License-Code — These headers list SPDX License Identifier(s) of the acceptable licenses under which the
+ BIP and corresponding code are available. See the [BIP Licensing](#bip-licensing) section below for a description of
+ the Licenses and their SPDX License Identifiers. If there are multiple acceptable licenses, each should be on a
+ separate line.
+* Discussion — The Discussion header points the audience to relevant discussions of the BIP, e.g., the mailing list
+ thread in which the idea for the BIP was discussed, a thread where a new version of the BIP was presented, or relevant
+ discussion threads on other platforms. Entries take the format "yyyy-mm-dd: URL", e.g., `2009-01-09:
+ https://www.mail-archive.com/cryptography@metzdowd.com/msg10142.html`, using the date and URL of the start of the
+ conversation. Multiple discussions should be listed on separate lines.
+* Version — The current version number of this BIP. See the [Changelog](#changelog) section below.
+* Requires — A list of existing BIPs the new proposal depends on. If multiple BIPs
+ are required, they should be listed in one line separated by a comma and space (e.g., "1, 2").
+* Replaces — BIP authors may place the numbers of one or more prior BIPs in the Replaces header to recommend that their
+ BIP succeeds, supersedes, or renders obsolete those prior BIPs.
+* Proposed-Replacement[^superseded-by-proposed-replacement] — When a later BIP indicates that it intends to supersede an
+ existing BIP, the later BIP’s number is added to the Proposed-Replacement header of the existing BIP to indicate the
+ potential successor BIP.
+
+#### Auxiliary Files
+
+BIPs may include auxiliary files such as diagrams and source code. Auxiliary files must be included in a subdirectory
+for that BIP named `bip-XXXX`, where "XXXX" is the BIP number zero-padded to four digits. File names in the subdirectory
+do not need to adhere to a specific convention.
+
+### BIP Types
+
+* A **Specification BIP** defines a set of technical rules describing a new feature or affecting the interoperability of implementations. The
+ distinguishing characteristic of a Specification BIP is that it can be implemented, and implementations can be compliant with
+ it. Specification BIPs must have a Specification section, must have a Backward Compatibility section (if incompatibilities are introduced), and can only be advanced to Complete after they contain or refer to a reference implementation and test vectors.
+* An **Informational BIP** describes a Bitcoin design issue, or provides general guidelines or other information to the
+ Bitcoin community.
+* A **Process BIP** describes a process surrounding Bitcoin, or proposes a change to (or an event in) a process. Process
+ BIPs are like Specification BIPs, but apply to topics other than the Bitcoin protocol and Bitcoin implementations.
+ They often require community consensus and are typically binding for the corresponding process. Examples include
+ procedures, guidelines, and changes to decision-making processes such as the BIP Process.
+
+## Workflow
+
+The BIP process starts with a new idea for Bitcoin. Each potential BIP must have authors—people who write the BIP,
+gather feedback, shepherd the discussion in the appropriate forums, and finally recommend a mature proposal to the
+community.
+
+
+
+### Ideation
+
+After having an idea, the authors should evaluate whether it meets the criteria to become a BIP, as described in this
+BIP. The idea must be of interest to the broader community or relevant to multiple software projects. Minor improvements
+and matters concerning only a single project usually do not require standardization and should instead be brought up directly to
+the relevant project.
+
+The authors should first research whether an idea has been considered before. Ideas in Bitcoin are often rediscovered,
+and prior related discussions may inform the authors of the issues that may arise in its progression. After some investigation,
+the novelty of an idea can be tested by posting about it to the [Bitcoin Development Mailing
+List](https://groups.google.com/g/bitcoindev). Prior correspondence can be found in the [mailing list
+archive](https://gnusha.org/pi/bitcoindev/).
+
+Vetting an idea publicly before investing the time to describe the idea formally is meant to save both the authors and
+the broader community time. Not only may someone point out relevant discussion topics that were missed in the authors’
+research, or that an idea is guaranteed to be rejected based on prior discussions, but describing an idea publicly also
+tests whether it is of interest to more people besides the authors. After establishing that the idea may be of interest
+to the Bitcoin community, the authors should work on drafting a BIP.
+
+As a first sketch of the proposal is taking shape, the authors should present it to the [Bitcoin Development Mailing
+List](https://groups.google.com/g/bitcoindev). This gives the authors a chance to collect initial feedback and address
+fundamental concerns. If the authors wish to work in public on the proposal at this stage, it is recommended that they
+open a pull request against one of their forks of the BIPs repository instead of the main BIPs repository.
+
+It is recommended that complicated proposals be split into separate BIPs that each focus on a specific component of the
+overall proposal.
+
+### Progression through BIP Statuses
+
+The following sections refer to BIP Status Field values. The BIP Status Field is defined in the Header Preamble
+specification above.
+
+#### Draft
+
+After fleshing out the proposal further and ensuring that it is of high quality and properly formatted, the authors
+should open a pull request to the [BIPs repository](https://github.com/bitcoin/bips). The document must adhere to the
+formatting requirements specified above and should be provided as a file named with a working title of the form
+"bip-title.[md|mediawiki]". The authors must not self-assign a number to their proposal.
+
+BIPs that (1) adhere to the formatting requirements, (2) are on-topic, and (3) have materially progressed beyond the
+ideation phase, e.g., by generating substantial public discussion and commentary from diverse contributors, by
+independent Bitcoin projects working on adopting the proposal, or by the authors working for an extended period toward
+improving the proposal based on community feedback, will be assigned a number by a BIP editor. The BIP editors should
+delay number assignment when they perceive a proposal being met with lack of interest: number assignment facilitates the
+distributed discussion of ideas, but before a proposal garners some interest in the Bitcoin community, there is no need
+to refer to it by a number.
+
+Proposals are also not ready for number assignment if they duplicate efforts, disregard formatting rules, are too
+unfocused or too broad, fail to provide proper motivation, fail to address backward compatibility where necessary, or
+fail to specify the feature clearly and comprehensively. Reviewers and BIP editors should provide guidance on how the
+proposal may be improved to progress toward readiness. Pull requests that are proposing off-topic ideas or
+have stopped making progress may be closed.
+
+When the proposal is ready and has been assigned a number, a BIP editor will merge it into the BIPs repository. After the
+BIP has been merged to the repository, its main focus should no longer shift significantly, even while the authors may
+continue to update the proposal as necessary. Updates to merged documents by the authors should also be submitted as
+pull requests.
+
+#### Complete[^complete]
+
+When the authors have concluded all planned work on their proposal, are confident that their BIP represents a net
+improvement, is clear, comprehensive, and is
+ready for adoption by the Bitcoin community, they may update the BIP’s status to Complete to indicate that they
+recommend adoption, implementation, or deployment of the BIP. Where applicable, the authors must ensure that any
+proposed specification is solid, not unduly complicated, and definitive. Specification BIPs must come with or refer to a working reference implementation and comprehensive test vectors before they can be moved to Complete. Subsequently, the BIP’s content should only be
+adjusted in minor details, e.g., to improve language, clarify ambiguities, backfill omissions in the specification, add
+test vectors for edge cases, or address other issues discovered as the BIP is being adopted.
+
+A Complete BIP can only move to Deployed or Closed. Any necessary changes to the specification should be minimal and
+interfere as little as possible with ongoing adoption. If a Complete BIP is found to need substantial functional
+changes, it may be preferable to move it to Closed[^new-BIP], and to start a new BIP with the changes instead.
+Otherwise, it could cause confusion as to what being compliant with the BIP means.
+
+A BIP may remain in the Complete status indefinitely unless its authors decide to move it to Closed or it is advanced to
+Deployed.
+Complete is the final status for most successful Informational BIPs.
+
+#### Deployed
+
+A settled[^settled] BIP may be advanced to Deployed upon request by any community member with evidence[^evidence] that the idea
+described in the BIP is in active use. Convincing evidence includes for example: an established project having deployed support
+for the BIP in mainnet software releases, a soft fork proposal’s activation criteria having been met on the network, or
+rough consensus for the BIP having been demonstrated.
+
+At that point, the BIP should be considered final and any breaking changes to the BIP should be proposed as a new
+separate BIP.[^new-BIP]
+
+##### Process BIPs
+
+A Process BIP may change status from Complete to Deployed when it achieves rough consensus on the Bitcoin Development Mailing List. Such a
+proposal is said to have rough consensus if it has been open to discussion on the mailing list for at least
+one month, and no person maintains any unaddressed substantiated objections to it. Addressed or obstructive objections
+may be ignored/overruled by general agreement that they have been sufficiently addressed, but clear reasoning must be
+given in such circumstances. Deployed Process BIPs may be modified indefinitely as long as a proposed modification has
+rough consensus per the same criteria.[^living-documents]
+
+#### Closed[^closed]
+
+A BIP that is of historical interest only, and is not being actively worked on, promoted or in active use, should be
+marked as Closed. The reason for moving the
+proposal to (or from) Closed should be recorded in the Changelog section in the same commit that updates the status.
+BIPs do not get deleted, they are retained even after being updated to Closed.
+Transitions involving the Closed state are:
+
+##### Draft ↦ Closed
+
+BIP authors may decide on their own to change their BIP’s status from Draft to Closed. If a Draft BIP stops making
+progress, sees accumulated feedback unaddressed, or otherwise appears stalled for a year, the community may move the BIP
+to Closed unless the authors assert that they intend to continue work within four weeks of being contacted.
+
+##### Complete ↦ Closed
+
+BIPs that had attained the Complete status, i.e., that had been recommended for adoption, may be moved to Closed per the
+authors’ announcement to the Bitcoin Development Mailing List[^bip-announcements-to-list]. However, if someone volunteers to adopt the proposal
+within four weeks, they become the BIP's author or deputy (see [Transferring BIP Ownership](#transferring-bip-ownership) below), and the BIP will
+remain Complete instead.
+
+##### Deployed ↦ Closed
+
+A BIP may evolve from Deployed to Closed when it is no longer in active use. Any community member may initiate this
+Status update by announcing it to the mailing list[^bip-announcements-to-list], and proceed if no objections have been raised for four weeks.
+
+##### Closed ↦ Draft
+
+The Closed status is generally intended to be a final status for BIPs,
+and if BIP authors decide to make another attempt at a previously Closed BIP, it is generally recommended to create a new
+proposal. (Obviously, the authors may borrow any amount of inspiration or actual text from any prior BIPs as licensing
+permits.) The authors should take special care to address the issues that caused the prior attempt’s abandonment. Even
+if the prior attempt had been assigned a number, the new BIP will generally be assigned a distinct number. However, if it is
+obvious that the new attempt directly continues work on the same idea, it may be reasonable to return the
+Closed BIP to Draft status.
+
+### Changelog
+
+To help implementers understand updates to a BIP, any changes after it has reached Complete must be tracked with version,
+date, and description in a Changelog section sorted by most recent version first. The version number is inspired by semantic versioning (MAJOR.MINOR.PATCH).
+The MAJOR version is incremented if changes to the BIP’s Specification are introduced that are incompatible with prior
+versions (which should be rare after a BIP is Complete, and only happen in well-grounded exceptional cases to a BIP that
+is Deployed). The MINOR version is incremented whenever the specification of the BIP is changed or extended in a
+backward-compatible way. The PATCH version is incremented for other changes to the BIP that are noteworthy (bug fixes,
+test vectors, important clarifications, etc.). Version 1.0.0 is used to label the promotion to
+Complete. A Changelog section may be introduced during the Draft phase to record significant changes (using versions 0.x.y).
+
+Example:
+
+> __Changelog__
+>
+> * __2.0.0__ (2025-01-22):
+> * Introduce a breaking change in the specification to fix a bug.
+> * __1.1.0__ (2025-01-17):
+> * Add a backward compatible extension to the BIP.
+> * __1.0.1__ (2025-01-15):
+> * Clarify an edge case and add corresponding test vectors.
+> * __1.0.0__ (2025-01-14):
+> * Complete planned work on the BIP.
+
+After a BIP receives a Changelog, the
+Preamble must indicate the latest version in the Version header. The Changelog highlights revisions to BIPs to human readers. A single
+BIP shall not recommend more than one variant of an idea at the same time. A different or
+competing variant of an existing BIP must be published as a separate BIP.
+
+### Adoption of Proposals
+
+The BIPs repository does not track the sentiment on proposals and does not track the adoption of BIPs beyond whether they
+are in active use or not. It is not intended for BIPs to list additional implementations beyond the reference
+implementation: the BIPs repository is not a signpost where to find implementations.[^OtherImplementations] After a BIP
+is advanced to Complete, it is up to the Bitcoin community to evaluate, adopt, ignore, or reject a BIP. Individual
+Bitcoin projects are encouraged to publish a list of BIPs they implement. A good example of this at the time of writing
+this BIP can be observed in Bitcoin Core’s [doc/bips.md](https://github.com/bitcoin/bitcoin/blob/master/doc/bips.md)
+file.
+
+### Transferring BIP Ownership
+
+It occasionally becomes necessary to transfer ownership of BIPs to new owners. In general, it would be preferable to
+retain the original authors of the transferred BIP, but that is up to the original authors. A good reason to transfer
+ownership is because the original authors no longer have the time or interest in updating it or following through with
+the BIP process, or are unreachable or unresponsive. A bad reason
+to transfer ownership is because someone doesn't agree with the direction of the BIP. The community tries to build
+consensus around a BIP, but if that's not possible, rather than fighting over control, the dissenters should supply a
+competing BIP.
+
+If someone is interested in assuming ownership of a BIP, they should send an email asking to take over, addressed to the
+original authors, the BIP Editors, and the Bitcoin Development Mailing List[^bip-announcements-to-list]. If the authors are unreachable or do not respond in a timely
+manner (e.g., four weeks), the BIP editors will make a unilateral decision whether to appoint the applicants as
+[Authors or Deputies](#authors-and-deputies) (which may be amended should the original authors make a delayed reappearance).
+
+## BIP Licensing
+
+The Bitcoin project develops a global peer-to-peer digital cash system. Open standards are indispensable for continued
+interoperability. Open standards reduce friction, and encourage anybody and everyone to contribute, compete, and
+innovate on a level playing field. Only freely licensed contributions are accepted to the BIPs repository.
+
+### Specification
+
+Each new BIP must identify at least one acceptable license in its preamble. Licenses must be referenced per their
+respective [SPDX License identifier](https://spdx.org/licenses). New BIPs may be accepted with the licenses described
+below.
+
+For example, a preamble might include the following License header:
+
+ License: CC0-1.0
+ GNU-All-Permissive
+
+In this case, the BIP text is fully licensed under both the Creative Commons CC0 1.0 Universal license as well as the
+GNU All-Permissive License, and anyone may modify and redistribute the text provided they comply with the terms of
+*either* license. In other words, the license list is an "OR choice", not an "AND also" requirement.
+
+It is also possible to license source code differently from the BIP text by including the optional License-Code header
+after the License header. Again, each license must be referenced by their respective SPDX License identifier shown
+below.
+
+Each source code file or source directory should specify the license under which it is made available as is common in
+software (e.g., with a license header or a LICENSE/COPYING file). It is recommended to make any test vectors available
+under CC0-1.0 or GNU-All-Permissive in addition to any other licenses to allow anyone to copy test vectors into their
+implementations without introducing license hindrances. Licenses listed in the License-Code header apply to all source
+directories, source code files, and test vectors provided with the BIP except those where a LICENSE file in a directory
+or the file header states otherwise.
+
+For example, a preamble specifying the optional License-Code header might look like:
+
+ License: CC0-1.0
+ License-Code: MIT
+
+In this case, the code in the BIP is not available under CC0-1.0, but is only available under the terms of the MIT
+License.
+
+BIPs are not required to be *exclusively* licensed under approved terms, and may also be licensed under unacceptable
+licenses *in addition to* at least one acceptable license. In this case, only the acceptable license(s) should be listed
+in the License and License-Code headers.
+
+It is recommended that BIPs that include literal code be licensed under the same license terms as the project it
+modifies. For example, literal code intended for Bitcoin Core would ideally be licensed (or dual-licensed) under the MIT
+license terms.
+
+In all cases, details of the licensing terms must be provided in the Copyright section of the BIP.
+
+#### Acceptable Licenses[^licenses]
+
+* BSD-2-Clause: [OSI-approved BSD 2-clause license](https://opensource.org/licenses/BSD-2-Clause)
+* BSD-3-Clause: [OSI-approved BSD 3-clause license](https://opensource.org/licenses/BSD-3-Clause)
+* CC0-1.0: [Creative Commons CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/)
+* GNU-All-Permissive: [GNU All-Permissive License](http://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html)
+* CC-BY-4.0: [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/)
+* MIT: [Expat/MIT/X11 license](https://opensource.org/licenses/MIT)
+* Apache-2.0: [Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+* BSL-1.0: [Boost Software License, version 1.0](http://www.boost.org/LICENSE_1_0.txt)
+
+#### Not Acceptable Licenses
+
+All licenses not explicitly included in the above lists are not acceptable terms for a Bitcoin Improvement Proposal.
+However, BIPs predating the acceptance of this BIP were allowed under other terms, and should use these abbreviations
+when no other license is granted:
+
+* PD: Released into the public domain
+* OPL: [Open Publication License, version 1.0](http://opencontent.org/openpub/)
+
+## BIP Editors
+
+The current BIP editors are:
+
+* Bryan Bishop ([kanzure@gmail.com](mailto:kanzure@gmail.com))
+* Jon Atack ([jon@atack.com](mailto:jon@atack.com))
+* Luke Dashjr ([luke_bipeditor@dashjr.org](mailto:luke_bipeditor@dashjr.org))
+* Mark "Murch" Erhardt ([murch@murch.one](mailto:murch@murch.one))
+* Olaoluwa Osuntokun ([laolu32@gmail.com](mailto:laolu32@gmail.com))
+* Ruben Somsen ([rsomsen@gmail.com](mailto:rsomsen@gmail.com))
+
+### BIP Editor Responsibilities and Workflow
+
+The BIP editors subscribe to the Bitcoin Development Mailing List and watch the [BIPs
+repository](https://github.com/bitcoin/bips).
+
+When a new BIP idea is submitted to the mailing list, BIP editors and other community members should comment in regard
+to:
+
+* Novelty of the idea
+* Viability, utility, and relevance of the concept
+* Readiness of the proposal
+* On-topic for the Bitcoin community
+
+Discussion in pull request comments can often be hard to follow as feedback gets marked as resolved when it is addressed
+by authors. Substantive discussion of ideas may be more accessible to a broader audience on the mailing list, where it
+is also more likely to be retained by the community memory.
+
+If the BIP needs more work, an editor should ensure that constructive, actionable feedback is provided to the authors
+for revision. Once the BIP is ready it should be submitted as a "pull request" to the [BIPs
+repository](https://github.com/bitcoin/bips) where it may get further feedback.
+
+For each new BIP pull request that comes in, an editor checks the following:
+
+* The idea has been previously discussed on the Bitcoin Development Mailing List
+* The described idea is on-topic for the repository
+* Title accurately describes the content
+* Proposal is of general interest and/or pertains to more than one Bitcoin project/implementation
+* Document is properly formatted
+* Licensing terms are acceptable
+* Motivation, Rationale, and Backward Compatibility have been addressed
+* Specification provides sufficient detail for implementation
+* The defined Layer header must be correctly assigned for the given specification
+* The BIP is ready: it is comprehensible, technically feasible, and all aspects are addressed as necessary
+
+Editors do NOT evaluate whether the proposal is likely to be adopted.
+
+Then, a BIP editor will:
+
+* Assign a BIP number and BIP type in the pull request
+* Ensure that the BIP is listed in the [README](README.mediawiki)
+* Merge the pull request when it is ready
+
+The BIP editors are intended to fulfill administrative and editorial responsibilities. The BIP editors monitor BIP
+changes, and update BIP headers as appropriate.
+
+BIP editors may also, at their option, unilaterally make and merge strictly editorial changes to BIPs, such as
+correcting misspellings, mending grammar mistakes, fixing broken links, etc. as long as they do not change the meaning or conflict with the
+original intent of the authors. Such a change must be recorded in the Changelog if it’s noteworthy per the criteria
+mentioned in the [Changelog](#changelog) section.
+
+## Backward Compatibility
+
+### Changes from BIP 2
+
+#### Workflow
+
+- Status field values are reduced from nine to four:
+ - Deferred, Obsolete, Rejected, Replaced, and Withdrawn are gathered up into Closed.[^closed]
+ - Final and Active are collapsed into Deployed.
+ - Proposed is renamed to Complete.
+ - The remaining statuses are Draft, Complete, Deployed, and Closed.
+- The comment system is abolished.[^comments]
+- A BIP in Draft or Complete status may no longer be closed solely on grounds of not making progress for three years.[^rejection]
+ - A BIP in Draft status may be set to Closed by anyone if it appears to have stopped making progress for at least a
+ year and its authors do not assert that they are still working on it when contacted.
+ - Complete BIPs can only be moved to Closed by its authors and may remain in Complete indefinitely.
+- Process BIPs are living documents that do not ossify and may be modified indefinitely.
+- Some judgment calls previously required from BIP Editors are reassigned either to the BIP authors or the repository’s
+ audience.
+
+#### BIP Format
+
+- The Standards Track type is superseded by the similar Specification type.[^standard-track]
+- Many sections are declared optional; it is up to the authors and reviewers to judge whether all relevant topics have
+ been comprehensively addressed and which topics require a designated section to do so.
+- "Other Implementations" sections are discouraged.[^OtherImplementations]
+- Auxiliary files are only permitted in the corresponding BIP’s subdirectory, as no one used the alternative of labeling
+ them with the BIP number.
+- Tracking of adoption, acceptance, and community consensus is out of scope for the BIPs repository, except to determine
+ whether a BIP is in active use for the move into or out of the Deployed status.
+- The distinction between recommended and acceptable licenses was dropped.
+- Most licenses that have not been used in the BIP process have been dropped from the list of acceptable licenses.
+
+#### Preamble
+
+- "Comments-URI" and "Comment-Summary" headers are dropped from the preamble.[^comments]
+- The "Superseded-By" header is replaced with the "Proposed-Replacement" header.
+- The "Post-History" header is replaced with the "Discussion" header.
+- The "Discussions-To" header is dropped as it has never been used in any BIP.
+- Introduce Deputies and optional "Deputies" header.
+- The BIP "Title" header may now contain up to 50 characters (increased from 44 in BIP 2).
+- The "Layer" header is optional for Specification BIPs or Informational BIPs, as it does not make sense for all BIPs.[^layer]
+- Rename the "Author" field to "Authors".
+
+### Updates to Existing BIPs should this BIP be Activated
+
+#### Previous BIP Process
+
+This BIP replaces BIP 2 as the guideline for the BIP process.
+
+#### BIP Types
+
+Standards Track BIPs and eligible Informational BIPs are assigned the Specification type. The Standards Track type is
+considered obsolete. Specification BIPs use the Layer header rules specified in [BIP 123](bip-0123.mediawiki).
+
+#### Comments
+
+The Comments-URI and Comment-Summary headers should be removed from all BIPs whose comment page in the wiki is empty.
+For existing BIPs whose comment page has content, BIP Authors may keep both headers or remove both headers at their
+discretion. It is recommended that existing wiki pages are not modified due to the activation of this BIP.
+
+#### Status Field
+
+After the activation of this BIP, the Status fields of existing BIPs that do not fit the specification in this BIP are
+updated to the corresponding values prescribed in this BIP. BIPs that have had Draft status for extended periods will be
+moved to Complete or Deployed as applicable in collaboration with their authors. The authors of incomplete Draft BIPs
+will be contacted to learn whether the BIPs are still in progress toward Complete, and will otherwise be updated to
+Closed as described in the [Workflow](#workflow) section above.
+
+#### Authors Header
+
+The Author header is replaced with the Authors header in all BIPs.
+
+#### Discussion Header
+
+The Post-History header is replaced with the Discussion header in all BIPs.
+
+#### Proposed-Replacement Header
+
+The Superseded-By header is replaced with the Proposed-Replacement header in all BIPs.
+
+#### Licenses
+
+The licenses of existing BIPs remain untouched.
+
+## Copyright
+
+This BIP is licensed under the [BSD-2-Clause License](https://opensource.org/licenses/BSD-2-Clause). Some content was
+adapted from [BIP 2](bip-0002.mediawiki) which was also licensed under the BSD-2-Clause.
+
+## Related Work
+
+- [BIP 1: BIP Purpose and Guidelines](bip-0001.mediawiki)
+- [BIP 2: BIP Process, revised](bip-0002.mediawiki)
+- [BIP 123: BIP Classification](bip-0123.mediawiki)
+- [RFC 822: Standard for ARPA Internet Text Messages](https://datatracker.ietf.org/doc/html/rfc822)
+- [RFC 2223: Instructions to RFC Authors](https://datatracker.ietf.org/doc/html/rfc2223)
+- [RFC 7282: On Consensus and Humming in the IETF](https://tools.ietf.org/html/rfc7282)
+
+## Acknowledgements
+
+We thank AJ Towns, Jon Atack, Jonas Nick, Larry Ruane, Pieter Wuille, Tim Ruffing, and others for their review,
+feedback, and helpful comments.
+
+## Rationale
+
+[^capitalization]: **When is Bitcoin capitalized and when is it lowercased?**
+ This document uses capitalized Bitcoin to refer to the system, network and abstract concept, and only uses lowercase
+ bitcoin to refer to units of the bitcoin currency.
+[^standard-track]: **Why was the Specification type introduced?**
+ The definitions of Informational and Standards Track BIPs caused some confusion in the past. Due to Informational
+ BIPs being described as optional, Standards Track BIPs were sometimes misunderstood to be generally recommended.
+ This has led to a number of BIPs that propose new features affecting interoperability of implementations being
+ assigned the Informational type. The situation is remedied by introducing a new _Specification BIP_ type that is
+ inclusive of any BIPs that can be implemented and affect interoperability of Bitcoin applications. Since all BIPs
+ are individual recommendations by the authors (even if some may eventually achieve endorsement by the majority of
+ the community), the prior reminder that Informational BIPs are optional is dropped.
+[^comments]: **Why were comments, Comments-URI, and Comment-Summary removed from the process?**
+ The comments feature saw insignificant adoption. Few BIPs received any comments and barely any more than two with
+ only a handful of contributors commenting at all. This led to many situations in which one or two comments ended up
+ dominating the comment summary. While some of those comments may have been representative of broadly held opinions,
+ it also overstated the importance of individual comments directly in the Preamble of BIPs. As collecting feedback in
+ this accessible fashion failed, the new process puts the onus back on the audience to make their own evaluation.
+[^layer]: **Why is the layer header now permitted for other BIP types?**
+ The layer header had already been used by many Informational BIPs, so the rule that it is only available to
+ Standards Track BIPs is dropped.
+[^OtherImplementations]: **What is the issue with "Other Implementations" sections in BIPs?**
+ In the past, some BIPs had "Other Implementations" sections that caused frequent change requests to existing BIPs.
+ This put an onus on the BIP authors, and frequently led to lingering pull requests due to the corresponding BIPs’
+ authors no longer participating in the process. Many of these alternative implementations eventually became
+ unmaintained or were low-quality to begin with. Therefore, "Other Implementations" sections are heavily discouraged.
+[^complete]: **Why was the Proposed status renamed to Complete?**
+ Some reviewers of this BIP raised that in a process which outlines the workflow of Bitcoin Improvement _Proposals_
+ using "Proposed" as a status field value was overloading the term: clearly _proposals_ are proposed at all stages of
+ the process. "Complete" expresses that the authors have concluded planned work on all parts of the proposal and are
+ ready to recommend their BIP for adoption. The term "ready" was also considered, but considered too subjective.
+[^rejection]: **Why can proposals remain in Draft or Complete indefinitely?**
+ The automatic 3-year timeout of BIPs has led to some disagreement in the past and seems unnecessary in cases where
+ the authors remain active in the community and still consider their idea worth pursuing. On the other hand,
+ Draft proposals that appear stale may be closed after only one year, which should achieve the main goal of
+ the original rule by limiting the effort and attention spent on proposals that never reach Complete.
+[^closed]: **Why was the Closed Status introduced?**
+ The Closed Status provides value to the audience by indicating which documents are only of historical significance.
+ Previously, the process had Deferred, Obsolete, Rejected, Replaced, and Withdrawn, which all meant some flavor of
+ "work has stopped on this." The many statuses complicated the process, may have contributed to process fatigue, and
+ may have resulted in BIPs’ statuses not being maintained well. The author of this BIP feels that all of the
+ aforementioned can be represented by _Closed_ without significantly impacting the information quality of the
+ overview table. Where the many Status variants provided minuscule additional information, the simplification is more
+ valuable and the Changelog section now collects specific details.
+[^acceptance]: **Why does the BIPs repository no longer track adoption?**
+ BIP 2 made an attempt to gather community feedback into comment summaries in BIPs directly. Given the low adoption
+ and corresponding low information quality of the summaries that resulted from that feature, this BIP instead intends
+ to leave the evaluation of BIPs to the audience.
+[^markdown]: **Which flavor of Markdown is allowed?**
+ The author of this proposal has no opinion on Markdown flavors, but recommends that proposals stick to the basic
+ Markdown syntax features commonly shared across Markdown dialects.
+[^living-documents]: **Why are Process BIPs living documents?**
+ In the past years, the existing BIPs process has not always provided a clear approach to all situations. For
+ example, the content of BIP 2 appears to have been penned especially with fork proposals in mind. It seems clear
+ that Bitcoin development will evolve in many surprising ways in the future. Instead of mandating the effort of
+ writing a new process document every time new situations arise, it seems preferable to allow the process to adapt to
+ the concerns of the future in specific aspects. Therefore, Process BIPs are defined as living documents that remain
+ open to amendment. If a Process BIP requires large modifications or even a complete overhaul, a new BIP should be
+ preferred.
+[^new-BIP]: **Why should the specification of an implemented BIP no longer be changed?**
+ After a Complete or Deployed BIP has been deployed by one or more implementations, breaking changes to the
+ specification could lead to a situation where multiple "compliant" implementations fail at being interoperable,
+ because they implemented different versions of the same BIP. Therefore, even changes to the specification of
+ Complete BIPs should be avoided, but Deployed BIPs should never be subject to breaking changes to their
+ specification.
+[^settled]: **What is meant by a BIP being settled?**
+ Since Deployed BIPs should not be changed, a Complete BIP should only be moved to Deployed after its Specification
+ has been put through its paces and changes to the BIP have stopped.
+[^bip-announcements-to-list]: **Why are some BIP status changes announced to the mailing list?**
+ The BIPs repository does not and cannot track who might be interested in or has deployed a BIP. While concerns were
+ raised that making announcements to the Bitcoin Developer Mailing List would introduce unnecessary noise, our
+ rationale is that 1) moving Complete and Deployed BIPs to the Closed status will be a rare occurrence, 2) status
+ updates will usually not generate a lot of discussion, 3) while the mailing list should preferably only used for
+ getting review for new BIPs, it is the only channel available to us that can be considered a public announcement to
+ the audience of the BIPs repository: even if the authors, implementers, or other parties interested in a BIP do not
+ see the announcement themselves, they may be made aware by someone that does see it.
+[^superseded-by-proposed-replacement]: **Why is Superseded-By replaced with Proposed-Replacement?**
+ Reviewers asked who should get to decide whether a BIP is superseded in case of a disagreement among the authors of
+ the original BIP, the authors of the new BIP, the editors, or the community? This is addressed by making the
+ "Replaces" header part of the recommendation of the authors of the new document, and replacing the "Superseded-By"
+ header with the "Proposed-Replacement" header that lists any proposals that recommend replacing the original document.
+[^evidence]: **How is evidence for advancing to Deployed evaluated?**
+ Whether evidence is deemed convincing to move a BIP to Deployed is up to the BIP Editors and Bitcoin community.
+ Running a single instance of a personal fork of a software project might be rejected, while a small software project with
+ dozens of users may be sufficient. The main point of the Deployed status is to indicate that changes to the BIP
+ could negatively impact users of projects that have already implemented support.
+[^licenses]: **Why were some licenses dropped?**
+ Among the 141 BIPs with licenses in the repository, only nine licenses have ever been used to license BIPs
+ (although, some BIPs were made available under more than one license) and only one license has been used to license
+ code:
+
+ Licenses used:
+
+ * BSD-2-Clause: 55
+ * PD: 42
+ * CC0-1.0: 23
+ * BSD-3-Clause: 19
+ * OPL: 5
+ * CC-BY-SA-4.0: 4
+ * GNU-All-Permissive: 3
+ * MIT: 2
+ * CC-BY-4.0: 1
+
+ License-Code used:
+
+ * MIT: 4
+
+ The following previously acceptable licenses were retained per request of reviewers, even though they have so far
+ never been used in the BIPs process:
+
+ * Apache-2.0: [Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * BSL-1.0: [Boost Software License, version 1.0](http://www.boost.org/LICENSE_1_0.txt)
+
+ The following previously acceptable licenses have never been used in the BIPs Process and have been dropped:
+
+ * AGPL-3.0+: [GNU Affero General Public License (AGPL), version 3 or newer](http://www.gnu.org/licenses/agpl-3.0.en.html)
+ * FDL-1.3: [GNU Free Documentation License, version 1.3](http://www.gnu.org/licenses/fdl-1.3.en.html)
+ * GPL-2.0+: [GNU General Public License (GPL), version 2 or newer](http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
+ * LGPL-2.1+: [GNU Lesser General Public License (LGPL), version 2.1 or newer](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html)
+
+ Why are software licenses included?
+
+ * Some BIPs, in particular those concerning the consensus layer, may include literal code in the BIP itself which
+ may not be available under the license terms the authors wish to use for the BIP.
+ * The author of this BIP has been provided with a learned opinion indicating that software licenses are perfectly
+ acceptable for licensing "human code" i.e., text as well as Markdown or MediaWiki code.
+
+ Why is CC-BY-SA-4.0 no longer acceptable for new BIPs?
+
+ * Specification BIPs are required to have a Reference Implementation and Test Vectors to be advanced to Complete. As
+ the BIPs repository is aiming to make proposals easily adoptable, the intention is for the reference
+ implementation and test vectors to be as accessible as possible. Copyleft licenses may introduce friction here,
+ and therefore CC-BY-SA-4.0 (and the GPL-flavors) is no longer considered acceptable for new BIPs. As mentioned
+ above, existing BIPs will retain their original licensing.
+
+ Why are OPL and Public Domain no longer acceptable for new BIPs?
+
+ * Public domain is not universally recognised as a legitimate action, thus it is inadvisable.
+ * The OPL is generally regarded as obsolete, and not a license suitable for new publications.
diff --git a/bip-0003/status-diagram.png b/bip-0003/status-diagram.png
new file mode 100644
index 0000000000..acddba6337
Binary files /dev/null and b/bip-0003/status-diagram.png differ
diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki
index f7fbad1c94..1883562dba 100644
--- a/bip-0009.mediawiki
+++ b/bip-0009.mediawiki
@@ -119,7 +119,7 @@ other one simultaneously transitions to STARTED, which would mean both would dem
Note that a block's state never depends on its own nVersion; only on that of its ancestors.
- case STARTED:
+ case STARTED:
if (GetMedianTimePast(block.parent) >= timeout) {
return FAILED;
}
diff --git a/bip-0009/states.gv b/bip-0009/states.gv
new file mode 100644
index 0000000000..9dc95c56e3
--- /dev/null
+++ b/bip-0009/states.gv
@@ -0,0 +1,22 @@
+/* There are many ways to compile this, but one of them is:
+ *
+ * $ dot -Tpng states.gv -o states.png
+ */
+digraph {
+ /* States. */
+ DEFINED; FAILED; STARTED; LOCKED_IN; ACTIVE;
+
+ /* Relationships between states, labeled where applicable. */
+ DEFINED -> DEFINED;
+ DEFINED -> FAILED [label = "timeout ≤ MTP"];
+ DEFINED -> STARTED [label = "starttime ≤ MTP < timeout"];
+ FAILED -> FAILED;
+ STARTED -> STARTED;
+ STARTED -> FAILED [label = "timeout ≤ MTP"];
+ STARTED -> LOCKED_IN [label = "(MTP < timeout) AND (threshold reached)"];
+ LOCKED_IN -> ACTIVE [label = "Always"];
+ ACTIVE -> ACTIVE;
+
+ /* Visualization hack to unclutter output. */
+ nodesep = 1.2;
+}
diff --git a/bip-0009/states.png b/bip-0009/states.png
index 09312a1c03..2048ed870d 100644
Binary files a/bip-0009/states.png and b/bip-0009/states.png differ
diff --git a/bip-0010.mediawiki b/bip-0010.mediawiki
index 42071f3a6f..289e3b041a 100644
--- a/bip-0010.mediawiki
+++ b/bip-0010.mediawiki
@@ -93,10 +93,10 @@ The following is an example TxDP from Armory, produced while running on the test
In this transaction, there are two inputs, one of 150 BTC and the other of 12 BTC. This transaction combines 162 BTC to create two outputs, one of 160 BTC, one 1.9995 BTC, and a tx fee of 0.0005. In this TxDP, both inputs have been signed, and thus could broadcast immediately.
-The style of communication is taken directly from PGP/GPG, which uses blocks of ASCII like this to communicate encrypted messages and signatures. This serialization is compact, and will be interpretted the same in all character encodings. It can be copied inline into an email, or saved in a text file. The advantage over the analogous PGP encoding is that there are some human readable elements to it, for users that wish to examine the TxDP packet manually, instead of requiring a program to parse the core elements of the TxDP.
+The style of communication is taken directly from PGP/GPG, which uses blocks of ASCII like this to communicate encrypted messages and signatures. This serialization is compact, and will be interpreted the same in all character encodings. It can be copied inline into an email, or saved in a text file. The advantage over the analogous PGP encoding is that there are some human readable elements to it, for users that wish to examine the TxDP packet manually, instead of requiring a program to parse the core elements of the TxDP.
A party receiving this TxDP can simply add their signature to the appropriate _TXINPUT_ line. If that is the last signature required, they can broadcast it themselves. Any software that implements this standard should be able to combine multiple TxDPs into a single TxDP. However, even without the programmatic support, a user could manually combine them by copying the appropriate _TXSIGS_ lines between serializations, though it is not the recommended method for combining TxDPs.
== Reference Implementation ==
-This proposal was implemented and tested in the older versions of ''Armory'' Bitcoin software for use in offline-wallet transaction signing (as a 1-of-1 transaction). Implementation can be found in https://github.com/etotheipi/BitcoinArmory/blob/v0.91-beta/armoryengine/Transaction.py under the class PyTxDistProposal. However, as of verion 0.92 released in July 2014, Armory no longer uses this proposal for offline wallet transaction signing and has moved on to a new format.
+This proposal was implemented and tested in the older versions of ''Armory'' Bitcoin software for use in offline-wallet transaction signing (as a 1-of-1 transaction). Implementation can be found in https://github.com/etotheipi/BitcoinArmory/blob/v0.91-beta/armoryengine/Transaction.py under the class PyTxDistProposal. However, as of version 0.92 released in July 2014, Armory no longer uses this proposal for offline wallet transaction signing and has moved on to a new format.
diff --git a/bip-0011.mediawiki b/bip-0011.mediawiki
index 8375f55356..7e9e1f6842 100644
--- a/bip-0011.mediawiki
+++ b/bip-0011.mediawiki
@@ -54,7 +54,7 @@ A weaker argument is OP_CHECKMULTISIG should not be used because it pops one too
OP_CHECKMULTISIG is already supported by old clients and miners as a non-standard transaction type.
-https://github.com/gavinandresen/bitcoin-git/tree/op_eval
+https://github.com/gavinandresen/bitcoin-git/tree/77f21f1583deb89bf3fffe80fe9b181fedb1dd60
== Post History ==
diff --git a/bip-0012.mediawiki b/bip-0012.mediawiki
index 9cb3795cd1..bd3d88c9b4 100644
--- a/bip-0012.mediawiki
+++ b/bip-0012.mediawiki
@@ -43,11 +43,11 @@ OP_EVAL allows the receiver of bitcoins to specify how they can be spent when th
If ''serialized script'' is a large or complicated multi-signature script, then the burden of paying for it (in increased transaction fees due to more signature operations or transaction size) is shifted from the sender to the receiver.
-The main objection to OP_EVAL is that it adds complexity, and complexity is the enemy of security. Also, evaluating data as code has a long record of being a source of security vulnerabilties.
+The main objection to OP_EVAL is that it adds complexity, and complexity is the enemy of security. Also, evaluating data as code has a long record of being a source of security vulnerabilities.
That same argument can be applied to the existing Bitcoin 'scripting' system; scriptPubKeys are transmit as data across the network and are then interpreted by every bitcoin implementation. OP_EVAL just moves the data that will be interpreted. It is debatable whether or not the entire idea of putting a little interpreted expression evaluation language at the core of Bitcoin was brilliant or stupid, but the existence of OP_EVAL does not make the expression language less secure.
-There is a 1-confirmation attack on old clients that interepret OP_EVAL as a no-op, but it is expensive and difficult in practice. The attack is:
+There is a 1-confirmation attack on old clients that interpret OP_EVAL as a no-op, but it is expensive and difficult in practice. The attack is:
# Attacker creates an OP_EVAL transaction that is valid as seen by old clients, but invalid for new clients.
# Attacker also creates a standard transaction that spends the OP_EVAL transaction, and pays the victim.
@@ -75,7 +75,7 @@ Example of a transaction that must fail for both old and new miners/clients:
==Reference Implementation==
-https://github.com/gavinandresen/bitcoin-git/tree/op_eval
+https://github.com/gavinandresen/bitcoin-git/tree/77f21f1583deb89bf3fffe80fe9b181fedb1dd60
==See Also==
diff --git a/bip-0014.mediawiki b/bip-0014.mediawiki
index abd575ce9b..fded42036a 100644
--- a/bip-0014.mediawiki
+++ b/bip-0014.mediawiki
@@ -28,7 +28,7 @@ Version bumping can also introduce incompatibilities and fracture the network. I
By using a protocol version, we set all implementations on the network to a common standard. Everybody is able to agree within their confines what is protocol and what is implementation-dependent. A user agent string is offered as a 'vanity-plate' for clients to distinguish themselves in the network.
-Separation of the network protocol from the implemention, and forming development of said protocol by means of a mutual consensus among participants, has the democratic disadvantage when agreement is hard to reach on contentious issues. To mitigate this issue, strong communication channels and fast release schedules are needed, and are outside the scope of this document (concerning a process-BIP type).
+Separation of the network protocol from the implementation, and forming development of said protocol by means of a mutual consensus among participants, has the democratic disadvantage when agreement is hard to reach on contentious issues. To mitigate this issue, strong communication channels and fast release schedules are needed, and are outside the scope of this document (concerning a process-BIP type).
User agents provide extra tracking information that is useful for keeping tabs on network data such as client implementations used or common architectures/operating-systems. In the rare case they may even provide an emergency method of shunning faulty clients that threaten network health- although this is strongly unrecommended and extremely bad form. The user agent does not provide a method for clients to work around and behave differently to different implementations, as this will lead to protocol fracturing.
diff --git a/bip-0015.mediawiki b/bip-0015.mediawiki
index a6e4426a81..9efcb81b80 100644
--- a/bip-0015.mediawiki
+++ b/bip-0015.mediawiki
@@ -12,7 +12,7 @@
[[bip-0070.mediawiki|BIP 0070]] (payment protocol) may be seen as the alternative to Aliases.
-Using vanilla bitcoin, to send funds to a destination, an address in the form 1Hd44nkJfNAcPJeZyrGC5sKJS1TzgmCTjjZ is needed. The problem with using addresses is they are not easy to remember. An analogy can be thought if one were required to enter the IP address of their favourite websites if domain names did not exist.
+Using vanilla bitcoin, to send funds to a destination, an address in the form 1Hd44nkJfNAcPJeZyrGC5sKJS1TzgmCTjjZ is needed. The problem with using addresses is that they are not easy to remember. An analogy can be thought if one were required to enter the IP address of their favourite websites if domain names did not exist.
This document aims to layout through careful argument, a bitcoin alias system. This is a big modification to the protocol that is not easily changed in the future and has big ramifications. There is impetus in getting it correct the first time. Aliases have to be robust and secure.
@@ -36,7 +36,7 @@ Their FirstBits alias becomes:
It is enough information to be given the FirstBits alias ''1brmlab''. When someone wishes to make a purchase, without FirstBits, they either have to type out their address laboriously by hand, scan their QR code (which requires a mobile handset that this author does not own) or find their address on the internet to copy and paste into the client to send bitcoins. FirstBits alleviates this impracticality by providing an easy method to make payments.
-Together with [[vanitygen|Vanitygen (vanity generator)]], it becomes possible to create memorable unique named addresses. Addresses that are meaningful, rather than an odd assemblage of letters and numbers but add context to the destination.
+Together with Vanitygen (vanity generator), it becomes possible to create memorable unique named addresses. Addresses that are meaningful, rather than an odd assemblage of letters and numbers but add context to the destination.
However FirstBits has its own problems. One is that the possible aliases one is able to generate is limited by the available computing power available. It may not be feasible to generate a complete or precise alias that is wanted- only approximates may be possible. It is also computationally resource intensive which means a large expenditure of power for generating unique aliases in the future, and may not scale up to the level of individuals at home or participants with hand-held devices in an environment of ubiquitous computing.
@@ -208,7 +208,7 @@ NameResolutionService::~NameResolutionService()
void NameResolutionService::ExplodeHandle(const string& strHandle, string& strNickname, string& strDomain)
{
- // split address at @ furthrest to the right
+ // split address at @ furthest to the right
size_t nPosAtsym = strHandle.rfind('@');
strNickname = strHandle.substr(0, nPosAtsym);
strDomain = strHandle.substr(nPosAtsym + 1, strHandle.size());
@@ -348,7 +348,7 @@ By using DNS lookups, the MITM problem with IP transactions could be mitigated b
=== Namecoin ID ===
-This proposal uses the Namecoin blockchain to associate an alias with a bitcoin address. Bitcoin queries a namecoin node. This retreives the structured data containing the bitcoin address(es) associated with this alias.
+This proposal uses the Namecoin blockchain to associate an alias with a bitcoin address. Bitcoin queries a namecoin node. This retrieves the structured data containing the bitcoin address(es) associated with this alias.
Using a decentralised domain name system like Namecoin, means no external server or entity needs to be trusted unlike the other proposals listed here. This indicates a system with the advantage of having a high availability and ease of entry (no restrictions for users to create aliases).
@@ -401,4 +401,4 @@ Any text can be put into the brackets, allowing merchants to adapt it to all the
New features can be added later to support uncovered cases.
-See the specification of [http://dot-bit.org/Namespace:Identity Namecoin ID] for more informations.
+See the specification of [http://dot-bit.org/Namespace:Identity Namecoin ID] for more information.
diff --git a/bip-0016.mediawiki b/bip-0016.mediawiki
index 0f4fb815a8..abc27d6610 100644
--- a/bip-0016.mediawiki
+++ b/bip-0016.mediawiki
@@ -40,7 +40,7 @@ The rules for validating these outpoints when relaying transactions or consideri
# Normal validation is done: an initial stack is created from the signatures and {serialized script}, and the hash of the script is computed and validation fails immediately if it does not match the hash in the outpoint.
# {serialized script} is popped off the initial stack, and the transaction is validated again using the popped stack and the deserialized script as the scriptPubKey.
-These new rules should only be applied when validating transactions in blocks with timestamps >= 1333238400 (Apr 1 2012) [https://github.com/bitcoin/bitcoin/commit/8f188ece3c82c4cf5d52a3363e7643c23169c0ff Remove -bip16 and -paytoscripthashtime command-line arguments]. There are transactions earlier than 1333238400 in the block chain that fail these new validation rules. [http://blockexplorer.com/tx/6a26d2ecb67f27d1fa5524763b49029d7106e91e3cc05743073461a719776192 Transaction 6a26d2ecb67f27d1fa5524763b49029d7106e91e3cc05743073461a719776192]. Older transactions must be validated under the old rules. (see the Backwards Compatibility section for details).
+These new rules should only be applied when validating transactions in blocks with timestamps >= 1333238400 (Apr 1 2012) [https://github.com/bitcoin/bitcoin/commit/8f188ece3c82c4cf5d52a3363e7643c23169c0ff Remove -bip16 and -paytoscripthashtime command-line arguments]. There are transactions earlier than 1333238400 in the block chain that fail these new validation rules. [https://web.archive.org/web/20141122040355/http://blockexplorer.com/tx/6a26d2ecb67f27d1fa5524763b49029d7106e91e3cc05743073461a719776192 Transaction 6a26d2ecb67f27d1fa5524763b49029d7106e91e3cc05743073461a719776192]. Older transactions must be validated under the old rules. (see the Backwards Compatibility section for details).
For example, the scriptPubKey and corresponding scriptSig for a one-signature-required transaction is:
diff --git a/bip-0017.mediawiki b/bip-0017.mediawiki
index 671f75ab5d..aeb8764486 100644
--- a/bip-0017.mediawiki
+++ b/bip-0017.mediawiki
@@ -86,7 +86,7 @@ Avoiding a block-chain split by malicious pay-to-script transactions requires ca
* A pay-to-script-hash transaction that is invalid for new clients/miners but valid for old clients/miners.
-To gracefully upgrade and ensure no long-lasting block-chain split occurs, more than 50% of miners must support full validation of the new transaction type and must switch from the old validation rules to the new rules at the same time.
+To gracefully upgrade and ensure no long-lasting block-chain split occurs, more than 50% of miners must support full validation of the new transaction type and must switch from the old validation rules to the new rules at the same time.
To judge whether or not more than 50% of hashing power supports this BIP, miners are asked to upgrade their software and put the string "p2sh/CHV" in the input of the coinbase transaction for blocks that they create.
diff --git a/bip-0020.mediawiki b/bip-0020.mediawiki
index fc3c0eaaee..1e9a733bd8 100644
--- a/bip-0020.mediawiki
+++ b/bip-0020.mediawiki
@@ -54,7 +54,7 @@ Graphical bitcoin clients SHOULD register themselves as the handler for the "bit
*label: Label for that address (e.g. name of receiver)
*address: bitcoin address
-*message: message that shown to the user after scanning the QR code
+*message: message that is shown to the user after scanning the QR code
*size: amount of base bitcoin units ([[#Transfer amount/size|see below]])
*send: used to send bitcoin, rather than to request them
*(others): optional, for future extensions
diff --git a/bip-0021.mediawiki b/bip-0021.mediawiki
index 0fba9bcf9a..9fa4823256 100644
--- a/bip-0021.mediawiki
+++ b/bip-0021.mediawiki
@@ -37,7 +37,7 @@ Elements of the query component may contain characters outside the valid range.
=== ABNF grammar ===
-(See also [[#Simpler syntax|a simpler representation of syntax]])
+(See also [[#simpler-syntax|a simpler representation of syntax]])
bitcoinurn = "bitcoin:" bitcoinaddress [ "?" bitcoinparams ]
bitcoinaddress = *base58
@@ -120,11 +120,6 @@ Some future version that has variables which are (currently) not understood but
Characters must be URI encoded properly.
-== Reference Implementations ==
-=== Bitcoin clients ===
-* Bitcoin-Qt supports the old version of Bitcoin URIs (ie without the req- prefix), with Windows and KDE integration as of commit 70f55355e29c8e45b607e782c5d76609d23cc858.
+== Reference Implementation ==
-=== Libraries ===
-* Javascript - https://github.com/bitcoinjs/bip21
-* Java - https://github.com/SandroMachado/BitcoinPaymentURI
-* Swift - https://github.com/SandroMachado/BitcoinPaymentURISwift
+Bitcoin-Qt supports the old version of Bitcoin URIs (ie without the req- prefix), with Windows and KDE integration as of commit 70f55355e29c8e45b607e782c5d76609d23cc858.
diff --git a/bip-0032.mediawiki b/bip-0032.mediawiki
index 88c2dbbcd9..c9ff38fa01 100644
--- a/bip-0032.mediawiki
+++ b/bip-0032.mediawiki
@@ -25,7 +25,7 @@ This document describes hierarchical deterministic wallets (or "HD Wallets"): wa
The specification is intended to set a standard for deterministic wallets that can be interchanged between different clients. Although the wallets described here have many features, not all are required by supporting clients.
-The specification consists of two parts. In a first part, a system for deriving a tree of keypairs from a single seed is presented. The second part demonstrates how to build a wallet structure on top of such a tree.
+The specification consists of two parts. In the first part, a system for deriving a tree of keypairs from a single seed is presented. The second part demonstrates how to build a wallet structure on top of such a tree.
==Copyright==
@@ -37,7 +37,7 @@ The Bitcoin reference client uses randomly generated keys. In order to avoid the
Deterministic wallets do not require such frequent backups, and elliptic curve mathematics permit schemes where one can calculate the public keys without revealing the private keys. This permits for example a webshop business to let its webserver generate fresh addresses (public key hashes) for each order or for each customer, without giving the webserver access to the corresponding private keys (which are required for spending the received funds).
-However, deterministic wallets typically consist of a single "chain" of keypairs. The fact that there is only one chain means that sharing a wallet happens on an all-or-nothing basis. However, in some cases one only wants some (public) keys to be shared and recoverable. In the example of a webshop, the webserver does not need access to all public keys of the merchant's wallet; only to those addresses which are used to receive customer's payments, and not for example the change addresses that are generated when the merchant spends money. Hierarchical deterministic wallets allow such selective sharing by supporting multiple keypair chains, derived from a single root.
+However, deterministic wallets typically consist of a single "chain" of keypairs. The fact that there is only one chain means that sharing a wallet happens on an all-or-nothing basis. However, in some cases one only wants some (public) keys to be shared and recoverable. In the example of a webshop, the webserver does not need access to all public keys of the merchant's wallet; only to those addresses which are used to receive customers' payments, and not for example the change addresses that are generated when the merchant spends money. Hierarchical deterministic wallets allow such selective sharing by supporting multiple keypair chains, derived from a single root.
==Specification: Key derivation==
@@ -104,7 +104,7 @@ The function N((k, c)) → (K, c) computes the extended public key correspond
To compute the public child key of a parent private key:
* N(CKDpriv((kpar, cpar), i)) (works always).
* CKDpub(N(kpar, cpar), i) (works only for non-hardened child keys).
-The fact that they are equivalent is what makes non-hardened keys useful (one can derive child public keys of a given parent key without knowing any private key), and also what distinguishes them from hardened keys. The reason for not always using non-hardened keys (which are more useful) is security; see further for more information.
+The fact that they are equivalent is what makes non-hardened keys useful (one can derive child public keys of a given parent key without knowing any private key), and also what distinguishes them from hardened keys. The reason for not always using non-hardened keys (which are more useful) is security; see further below for more information.
====Public parent key → private child key====
@@ -137,7 +137,7 @@ Extended public and private keys are serialized as follows:
* 32 bytes: the chain code
* 33 bytes: the public key or private key data (serP(K) for public keys, 0x00 || ser256(k) for private keys)
-This 78 byte structure can be encoded like other Bitcoin data in Base58, by first adding 32 checksum bits (derived from the double SHA-256 checksum), and then converting to the Base58 representation. This results in a Base58-encoded string of up to 112 characters. Because of the choice of the version bytes, the Base58 representation will start with "xprv" or "xpub" on mainnet, "tprv" or "tpub" on testnet.
+This 78 byte structure can be encoded like other Bitcoin data in Base58, by first adding 32 checksum bits (derived from the double SHA-256 checksum), and then converting to the Base58 representation. This results in a Base58-encoded string of exactly 111 characters. Because of the choice of the version bytes, the Base58 representation will start with "xprv" or "xpub" on mainnet, "tprv" or "tpub" on testnet.
Note that the fingerprint of the parent only serves as a fast way to detect parent and child nodes in software, and software must be willing to deal with collisions. Internally, the full 160-bit identifier could be used.
@@ -151,7 +151,7 @@ The total number of possible extended keypairs is almost 2512, but th
* Calculate I = HMAC-SHA512(Key = "Bitcoin seed", Data = S)
* Split I into two 32-byte sequences, IL and IR.
* Use parse256(IL) as master secret key, and IR as master chain code.
-In case IL is 0 or ≥n, the master key is invalid.
+In case parse256(IL) is 0 or parse256(IL) ≥ n, the master key is invalid.
@@ -184,7 +184,7 @@ When a business has several independent offices, they can all use wallets derive
====Recurrent business-to-business transactions: N(m/iH/0)====
In case two business partners often transfer money, one can use the extended public key for the external chain of a specific account (M/i h/0) as a sort of "super address", allowing frequent transactions that cannot (easily) be associated, but without needing to request a new address for each payment.
-Such a mechanism could also be used by mining pool operators as variable payout address.
+Such a mechanism could also be used by mining pool operators as a variable payout address.
====Unsecure money receiver: N(m/iH/0)====
@@ -201,7 +201,7 @@ In addition to the expectations from the EC public-key cryptography itself:
the intended security properties of this standard are:
* Given a child extended private key (ki,ci) and the integer i, an attacker cannot find the parent private key kpar more efficiently than a 2256 brute force of HMAC-SHA512.
* Given any number (2 ≤ N ≤ 232-1) of (index, extended private key) tuples (ij,(kij,cij)), with distinct ij's, determining whether they are derived from a common parent extended private key (i.e., whether there exists a (kpar,cpar) such that for each j in (0..N-1) CKDpriv((kpar,cpar),ij)=(kij,cij)), cannot be done more efficiently than a 2256 brute force of HMAC-SHA512.
-Note however that the following properties does not exist:
+Note however that the following properties do not exist:
* Given a parent extended public key (Kpar,cpar) and a child public key (Ki), it is hard to find i.
* Given a parent extended public key (Kpar,cpar) and a non-hardened child private key (ki), it is hard to find kpar.
@@ -212,7 +212,7 @@ Private and public keys must be kept safe as usual. Leaking a private key means
Somewhat more care must be taken regarding extended keys, as these correspond to an entire (sub)tree of keys.
One weakness that may not be immediately obvious, is that knowledge of a parent extended public key plus any non-hardened private key descending from it is equivalent to knowing the parent extended private key (and thus every private and public key descending from it). This means that extended public keys must be treated more carefully than regular public keys.
-It is also the reason for the existence of hardened keys, and why they are used for the account level in the tree. This way, a leak of account-specific (or below) private key never risks compromising the master or other accounts.
+It is also the reason for the existence of hardened keys, and why they are used for the account level in the tree. This way, a leak of account-specific (or below) private keys never risks compromising the master or other accounts.
==Test Vectors==
@@ -288,6 +288,26 @@ Seed (hex): 3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678
** ext pub: xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt
** ext prv: xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1
+===Test vector 5===
+
+These vectors test that invalid extended keys are recognized as invalid.
+
+* xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5fTtTQBm (pubkey version / prvkey mismatch)
+* xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGTQQD3dC4H2D5GBj7vWvSQaaBv5cxi9gafk7NF3pnBju6dwKvH (prvkey version / pubkey mismatch)
+* xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Txnt3siSujt9RCVYsx4qHZGc62TG4McvMGcAUjeuwZdduYEvFn (invalid pubkey prefix 04)
+* xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGpWnsj83BHtEy5Zt8CcDr1UiRXuWCmTQLxEK9vbz5gPstX92JQ (invalid prvkey prefix 04)
+* xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6N8ZMMXctdiCjxTNq964yKkwrkBJJwpzZS4HS2fxvyYUA4q2Xe4 (invalid pubkey prefix 01)
+* xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fEQ3Qen6J (invalid prvkey prefix 01)
+* xprv9s2SPatNQ9Vc6GTbVMFPFo7jsaZySyzk7L8n2uqKXJen3KUmvQNTuLh3fhZMBoG3G4ZW1N2kZuHEPY53qmbZzCHshoQnNf4GvELZfqTUrcv (zero depth with non-zero parent fingerprint)
+* xpub661no6RGEX3uJkY4bNnPcw4URcQTrSibUZ4NqJEw5eBkv7ovTwgiT91XX27VbEXGENhYRCf7hyEbWrR3FewATdCEebj6znwMfQkhRYHRLpJ (zero depth with non-zero parent fingerprint)
+* xprv9s21ZrQH4r4TsiLvyLXqM9P7k1K3EYhA1kkD6xuquB5i39AU8KF42acDyL3qsDbU9NmZn6MsGSUYZEsuoePmjzsB3eFKSUEh3Gu1N3cqVUN (zero depth with non-zero index)
+* xpub661MyMwAuDcm6CRQ5N4qiHKrJ39Xe1R1NyfouMKTTWcguwVcfrZJaNvhpebzGerh7gucBvzEQWRugZDuDXjNDRmXzSZe4c7mnTK97pTvGS8 (zero depth with non-zero index)
+* DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHGMQzT7ayAmfo4z3gY5KfbrZWZ6St24UVf2Qgo6oujFktLHdHY4 (unknown extended key version)
+* DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHPmHJiEDXkTiJTVV9rHEBUem2mwVbbNfvT2MTcAqj3nesx8uBf9 (unknown extended key version)
+* xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx (private key 0 not in 1..n-1)
+* xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD5SDKr24z3aiUvKr9bJpdrcLg1y3G (private key n not in 1..n-1)
+* xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Q5JXayek4PRsn35jii4veMimro1xefsM58PgBMrvdYre8QyULY (invalid pubkey 020000000000000000000000000000000000000000000000000000000000000007)
+* xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHL (invalid checksum)
==Acknowledgements==
diff --git a/bip-0035.mediawiki b/bip-0035.mediawiki
index 64edaf5d7a..b476806a7d 100644
--- a/bip-0035.mediawiki
+++ b/bip-0035.mediawiki
@@ -16,7 +16,7 @@ Make a network node's transaction memory pool accessible via a new "mempool" mes
==Motivation==
-Several use cases make it desireable to expose a network node's transaction memory pool:
+Several use cases make it desirable to expose a network node's transaction memory pool:
# SPV clients, wishing to obtain zero-confirmation transactions sent or received.
# Miners, to avoid missing lucrative fees, downloading existing network transactions after a restart.
# Remote network diagnostics.
@@ -24,7 +24,7 @@ Several use cases make it desireable to expose a network node's transaction memo
==Specification==
# The mempool message is defined as an empty message where pchCommand == "mempool"
-# Upon receipt of a "mempool" message, the node will respond with an "inv" message containing MSG_TX hashes of all the transactions in the node's transaction memory pool, if any.
+# Upon receipt of a "mempool" message, the node will respond with an "inv" message containing MSG_TX hashes of all the transactions in the node's transaction memory pool, if any.
# The typical node behavior in response to an "inv" is "getdata". However, the reference Satoshi implementation ignores requests for transaction hashes outside that which is recently relayed. To support "mempool", an implementation must extend its "getdata" message support to querying the memory pool.
# Feature discovery is enabled by checking two "version" message attributes:
## Protocol version >= 60002
diff --git a/bip-0037.mediawiki b/bip-0037.mediawiki
index d817bc012c..ba207b6de9 100644
--- a/bip-0037.mediawiki
+++ b/bip-0037.mediawiki
@@ -159,7 +159,7 @@ A ''Merkle tree'' is a way of arranging a set of items as leaf nodes of tree in
** Check whether this node corresponds to a leaf node (transaction) that is to be included OR any parent thereof:
*** If so, append a '1' bit to the flag bits
*** Otherwise, append a '0' bit.
-** Check whether this node is a internal node (non-leaf) AND is the parent of an included leaf node:
+** Check whether this node is an internal node (non-leaf) AND is the parent of an included leaf node:
*** If so:
**** Descend into its left child node, and process the subtree beneath it entirely (depth-first).
**** If this node has a right child node too, descend into it as well.
diff --git a/bip-0038.mediawiki b/bip-0038.mediawiki
index bfe1f4ab61..6bcf41198e 100644
--- a/bip-0038.mediawiki
+++ b/bip-0038.mediawiki
@@ -36,10 +36,10 @@ Password and passphrase-protected private keys enable new practical use cases fo
This proposal is hereby placed in the public domain.
==Rationale==
-:'''''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.''
-:'''''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds. I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).''
-:'''''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key. I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.''
-:'''''User story:''' (EC multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate.
+:'' '''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.''
+:'' '''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds. I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).''
+:'' '''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key. I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.''
+:'' '''User story:''' (EC-multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate.''
==Specification==
This proposal makes use of the following functions and definitions:
@@ -47,12 +47,12 @@ This proposal makes use of the following functions and definitions:
*'''AES256Encrypt, AES256Decrypt''': the simple form of the well-known AES block cipher without consideration for initialization vectors or block chaining. Each of these functions takes a 256-bit key and 16 bytes of input, and deterministically yields 16 bytes of output.
*'''SHA256''', a well-known hashing algorithm that takes an arbitrary number of bytes as input and deterministically yields a 32-byte hash.
*'''scrypt''': A well-known key derivation algorithm. It takes the following parameters: (string) password, (string) salt, (int) n, (int) r, (int) p, (int) length, and deterministically yields an array of bytes whose length is equal to the length parameter.
-*'''ECMultiply''': Multiplication of an elliptic curve point by a scalar integer with respect to the [[secp256k1]] elliptic curve.
-*'''G, N''': Constants defined as part of the [[secp256k1]] elliptic curve. G is an elliptic curve point, and N is a large positive integer.
-*'''[[Base58Check]]''': a method for encoding arrays of bytes using 58 alphanumeric characters commonly used in the Bitcoin ecosystem.
+*'''ECMultiply''': Multiplication of an elliptic curve point by a scalar integer with respect to the secp256k1 elliptic curve.
+*'''G, N''': Constants defined as part of the secp256k1 elliptic curve. G is an elliptic curve point, and N is a large positive integer.
+*'''Base58Check''': a method for encoding arrays of bytes using 58 alphanumeric characters commonly used in the Bitcoin ecosystem.
===Prefix===
-It is proposed that the resulting Base58Check-encoded string start with a '6'. The number '6' is intended to represent, from the perspective of the user, "a private key that needs something else to be usable" - an umbrella definition that could be understood in the future to include keys participating in multisig transactions, and was chosen with deference to the existing prefix '5' most commonly observed in [[Wallet Import Format]] which denotes an unencrypted private key.
+It is proposed that the resulting Base58Check-encoded string start with a '6'. The number '6' is intended to represent, from the perspective of the user, "a private key that needs something else to be usable" - an umbrella definition that could be understood in the future to include keys participating in multisig transactions, and was chosen with deference to the existing prefix '5' most commonly observed in Wallet Import Format which denotes an unencrypted private key.
It is proposed that the second character ought to give a hint as to what is needed as a second factor, and for an encrypted key requiring a passphrase, the uppercase letter P is proposed.
@@ -64,9 +64,9 @@ To keep the size of the encrypted key down, no initialization vectors (IVs) are
* How the user sees it: 58 characters always starting with '6P'
** Visual cues are present in the third character for visually identifying the EC-multiply and compress flag.
* Count of payload bytes (beyond prefix): 37
-** 1 byte (''flagbyte''):
+** 1 byte (''flagbyte''):
*** the most significant two bits are set as follows to preserve the visibility of the compression flag in the prefix, as well as to keep the payload within the range of allowable values that keep the "6P" prefix intact. For non-EC-multiplied keys, the bits are 11. For EC-multiplied keys, the bits are 00.
-*** the bit with value 0x20 when set indicates the key should be converted to a bitcoin address using the compressed public key format.
+*** the bit with value 0x20 when set indicates the key should be converted to a base58check encoded P2PKH bitcoin address using the DER compressed public key format. When not set, it should be a base58check encoded P2PKH bitcoin address using the DER uncompressed public key format.
*** the bits with values 0x10 and 0x08 are reserved for a future specification that contemplates using multisig as a way to combine the factors such that parties in possession of the separate factors can independently sign a proposed transaction without requiring that any party possess both factors. These bits must be 0 to comply with this version of the specification.
*** the bit with value 0x04 indicates whether a lot and sequence number are encoded into the first factor, and activates special behavior for including them in the decryption process. This applies to EC-multiplied keys only. Must be 0 for non-EC-multiplied keys.
*** remaining bits are reserved for future use and must all be 0 to comply with this version of the specification.
@@ -75,10 +75,10 @@ To keep the size of the encrypted key down, no initialization vectors (IVs) are
**16 bytes: lasthalf: An AES-encrypted key material record (contents depend on whether EC multiplication is used)
* Range in base58check encoding for non-EC-multiplied keys without compression (prefix 6PR):
** Minimum value: 6PRHv1jg1ytiE4kT2QtrUz8gEjMQghZDWg1FuxjdYDzjUkcJeGdFj9q9Vi (based on 01 42 C0 plus thirty-six 00's)
-** Maximum value: 6PRWdmoT1ZursVcr5NiD14p5bHrKVGPG7yeEoEeRb8FVaqYSHnZTLEbYsU (based on 01 42 C0 plus thirty-six FF's)
+** Maximum value: 6PRWdmoT1ZursVcr5NiD14p5bHrKVGPG7yeEoEeRb8FVaqYSHnZTLEbYsU (based on 01 42 C0 plus thirty-six FF's)
* Range in base58check encoding for non-EC-multiplied keys with compression (prefix 6PY):
** Minimum value: 6PYJxKpVnkXUsnZAfD2B5ZsZafJYNp4ezQQeCjs39494qUUXLnXijLx6LG (based on 01 42 E0 plus thirty-six 00's)
-** Maximum value: 6PYXg5tGnLYdXDRZiAqXbeYxwDoTBNthbi3d61mqBxPpwZQezJTvQHsCnk (based on 01 42 E0 plus thirty-six FF's)
+** Maximum value: 6PYXg5tGnLYdXDRZiAqXbeYxwDoTBNthbi3d61mqBxPpwZQezJTvQHsCnk (based on 01 42 E0 plus thirty-six FF's)
* Range in base58check encoding for EC-multiplied keys without compression (prefix 6Pf):
** Minimum value: 6PfKzduKZXAFXWMtJ19Vg9cSvbFg4va6U8p2VWzSjtHQCCLk3JSBpUvfpf (based on 01 43 00 plus thirty-six 00's)
** Maximum value: 6PfYiPy6Z7BQAwEHLxxrCEHrH9kasVQ95ST1NnuEnnYAJHGsgpNPQ9dTHc (based on 01 43 00 plus thirty-six FF's)
@@ -170,7 +170,7 @@ To recalculate the address:
# Derive ''passfactor'' using scrypt with ''ownerentropy'' and the user's passphrase and use it to recompute ''passpoint''
# Derive decryption key for ''pointb'' using scrypt with ''passpoint'', ''addresshash'', and ''ownerentropy''
# Decrypt ''encryptedpointb'' to yield ''pointb''
-# ECMultiply ''pointb'' by ''passfactor''. Use the resulting EC point as a public key and hash it into ''address'' using either compressed or uncompressed public key methodology as specifid in ''flagbyte''.
+# ECMultiply ''pointb'' by ''passfactor''. Use the resulting EC point as a public key and hash it into ''address'' using either compressed or uncompressed public key methodology as specified in ''flagbyte''.
=====Decryption=====
# Collect encrypted private key and passphrase from user.
@@ -184,7 +184,7 @@ To recalculate the address:
# Hash the Bitcoin address, and verify that ''addresshash'' from the encrypted private key record matches the hash. If not, report that the passphrase entry was incorrect.
==Backwards compatibility==
-Backwards compatibility is minimally applicable since this is a new standard that at most extends [[Wallet Import Format]]. It is assumed that an entry point for private key data may also accept existing formats of private keys (such as hexadecimal and [[Wallet Import Format]]); this draft uses a key format that cannot be mistaken for any existing one and preserves auto-detection capabilities.
+Backwards compatibility is minimally applicable since this is a new standard that at most extends Wallet Import Format. It is assumed that an entry point for private key data may also accept existing formats of private keys (such as hexadecimal and Wallet Import Format); this draft uses a key format that cannot be mistaken for any existing one and preserves auto-detection capabilities.
==Suggestions for implementers of proposal with alt-chains==
If this proposal is accepted into alt-chains, it is requested that the unused flag bytes not be used for denoting that the key belongs to an alt-chain.
@@ -209,14 +209,10 @@ The preliminary values of 16384, 8, and 8 are hoped to offer the following prope
==Reference implementation==
Added to alpha version of Casascius Bitcoin Address Utility for Windows available at:
-* via https: https://casascius.com/btcaddress-alpha.zip
-* at github: https://github.com/casascius/Bitcoin-Address-Utility
+* https://github.com/casascius/Bitcoin-Address-Utility
Click "Tools" then "PPEC Keygen" (provisional name)
-==Other implementations==
-* Javascript - https://github.com/bitcoinjs/bip38
-
==Test vectors==
===No compression, no EC multiply===
@@ -276,7 +272,7 @@ Test 2:
Test 1:
*Passphrase: MOLON LABE
-*Passphrase code: passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX
+*Passphrase code: passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX
*Encrypted key: 6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j
*Bitcoin address: 1Jscj8ALrYu2y9TD8NrpvDBugPedmbj4Yh
*Unencrypted private key (WIF): 5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8
@@ -284,9 +280,9 @@ Test 1:
*Confirmation code: cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD
*Lot/Sequence: 263183/1
-Test 2:
+Test 2:
*Passphrase (all letters are Greek - test UTF-8 compatibility with this): ΜΟΛΩΝ ΛΑΒΕ
-*Passphrase code: passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK
+*Passphrase code: passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK
*Encrypted private key: 6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH
*Bitcoin address: 1Lurmih3KruL4xDB5FmHof38yawNtP9oGf
*Unencrypted private key (WIF): 5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D
diff --git a/bip-0039.mediawiki b/bip-0039.mediawiki
index 4ac3c556d9..338751fe14 100644
--- a/bip-0039.mediawiki
+++ b/bip-0039.mediawiki
@@ -8,9 +8,10 @@
Sean Bowe
Comments-Summary: Unanimously Discourage for implementation
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0039
- Status: Proposed
+ Status: Final
Type: Standards Track
Created: 2013-09-10
+ License: MIT
==Abstract==
@@ -22,6 +23,10 @@ It consists of two parts: generating the mnemonic and converting it into a
binary seed. This seed can be later used to generate deterministic wallets using
BIP-0032 or similar methods.
+==Copyright==
+
+This BIP falls under the MIT License.
+
==Motivation==
A mnemonic code or sentence is superior for human interaction compared to the
@@ -39,7 +44,7 @@ security is improved but the sentence length increases. We refer to the
initial entropy length as ENT. The allowed size of ENT is 128-256 bits.
First, an initial entropy of ENT bits is generated. A checksum is generated by
-taking the first
ENT / 32
bits of its SHA256 hash. This checksum is
+taking the first ENT / 32 bits of its SHA256 hash. This checksum is
appended to the end of the initial entropy. Next, these concatenated bits
are split into groups of 11 bits, each encoding a number from 0-2047, serving
as an index into a wordlist. Finally, we convert these numbers into words and
@@ -138,59 +143,3 @@ Also see https://github.com/bip32JP/bip32JP.github.io/blob/master/test_JP_BIP39.
Reference implementation including wordlists is available from
http://github.com/trezor/python-mnemonic
-
-==Other Implementations==
-
-Go:
-* https://github.com/tyler-smith/go-bip39
-
-Python:
-* https://github.com/meherett/python-hdwallet
-
-Elixir:
-* https://github.com/aerosol/mnemo
-
-Objective-C:
-* https://github.com/nybex/NYMnemonic
-
-Haskell:
-* https://github.com/haskoin/haskoin
-
-.NET C# (PCL):
-* https://github.com/Thashiznets/BIP39.NET
-
-.NET C# (PCL):
-* https://github.com/NicolasDorier/NBitcoin
-
-JavaScript:
-* https://github.com/bitpay/bitcore/tree/master/packages/bitcore-mnemonic
-* https://github.com/bitcoinjs/bip39 (used by [[https://github.com/blockchain/My-Wallet-V3/blob/v3.8.0/src/hd-wallet.js#L121-L146|blockchain.info]])
-
-Java:
-* https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java
-
-Ruby:
-* https://github.com/sreekanthgs/bip_mnemonic
-
-Rust:
-* https://github.com/maciejhirsz/tiny-bip39/
-* https://github.com/koushiro/bip0039-rs
-
-Smalltalk:
-* https://github.com/eMaringolo/pharo-bip39mnemonic
-
-Swift:
-* https://github.com/CikeQiu/CKMnemonic
-* https://github.com/yuzushioh/WalletKit
-* https://github.com/pengpengliu/BIP39
-* https://github.com/matter-labs/web3swift/blob/develop/Sources/web3swift/KeystoreManager/BIP39.swift
-* https://github.com/zcash-hackworks/MnemonicSwift
-
-C++:
-* https://github.com/libbitcoin/libbitcoin-system/blob/master/include/bitcoin/system/wallet/mnemonic.hpp
-
-C (with Python/Java/Javascript bindings):
-* https://github.com/ElementsProject/libwally-core
-
-Python:
-* https://github.com/scgbckbone/btc-hd-wallet
diff --git a/bip-0039/bip-0039-wordlists.md b/bip-0039/bip-0039-wordlists.md
index f2c173c58d..e83cf130a1 100644
--- a/bip-0039/bip-0039-wordlists.md
+++ b/bip-0039/bip-0039-wordlists.md
@@ -28,7 +28,7 @@ for two smaller words (This would be a problem with any of the 3 character sets
### Spanish
-1. Words can be uniquely determined typing the first 4 characters (sometimes less).
+1. Words can be uniquely determined by typing the first 4 characters (sometimes less).
2. Special Spanish characters like 'ñ', 'ü', 'á', etc... are considered equal to 'n', 'u', 'a', etc... in terms of identifying a word. Therefore, there is no need to use a Spanish keyboard to introduce the passphrase, an application with the Spanish wordlist will be able to identify the words after the first 4 chars have been typed even if the chars with accents have been replaced with the equivalent without accents.
@@ -50,10 +50,10 @@ Credits: @Kirvx @NicolasDorier @ecdsa @EricLarch
4. Only infinitive verbs, adjectives and nouns.
5. No pronouns, no adverbs, no prepositions, no conjunctions, no interjections (unless a noun/adjective is also popular than its interjection like "mince;chouette").
6. No numeral adjectives.
-7. No words in the plural (except invariable words like "univers", or same spelling than singular like "heureux").
+7. No words in the plural (except invariable words like "univers", or same spelling as singular like "heureux").
8. No female adjectives (except words with same spelling for male and female adjectives like "magique").
9. No words with several senses AND different spelling in speaking like "verre-vert", unless a word has a meaning much more popular than another like "perle" and "pairle".
-10. No very similar words with 1 letter of difference.
+10. No very similar words with only 1 letter of difference.
11. No essentially reflexive verbs (unless a verb is also a noun like "souvenir").
12. No words with "ô;â;ç;ê;œ;æ;î;ï;û;ù;à;ë;ÿ".
13. No words ending by "é;ée;è;et;ai;ait".
@@ -76,7 +76,7 @@ Words chosen using the following rules:
6. No plural words.
7. No words that remind negative/sad/bad things.
8. If both female/male words are available, choose male version.
-9. No words with double vocals (like: lineetta).
+9. No words with double vowels (like: lineetta).
10. No words already used in other language mnemonic sets.
11. If 3 of the first 4 letters are already used in the same sequence in another mnemonic word, there must be at least other 3 different letters.
12. If 3 of the first 4 letters are already used in the same sequence in another mnemonic word, there must not be the same sequence of 3 or more letters.
@@ -92,26 +92,26 @@ Credits: @zizelevak (Jan Lansky zizelevak@gmail.com)
Words chosen using the following rules:
1. Words are 4-8 letters long.
-2. Words can be uniquely determined typing the first 4 letters.
-3. Only words containing all letters without diacritical marks. (It was the hardest task, because in one third of all Czech letters has diacritical marks.)
+2. Words can be uniquely determined by typing the first 4 letters.
+3. Only words containing all letters without diacritical marks. (It was the hardest task, because one third of all Czech letters has diacritical marks.)
4. Only nouns, verbs and adverbs, no other word types. All words are in basic form.
5. No personal names or geographical names.
6. No very similar words with 1 letter of difference.
-7. Words are sorting according English alphabet (Czech sorting has difference in "ch").
-8. No words already used in other language mnemonic sets (english, italian, french, spanish). Letters with diacritical marks from these sets are counted as analogous letters without diacritical marks.
+7. Words are sorted according to English alphabet (Czech sorting has difference in "ch").
+8. No words already used in other language mnemonic sets (english, italian, french, spanish). Letters with diacritical marks from these sets are counted as analogous letters without diacritical marks.
### Portuguese
Credits: @alegotardo @bitmover-studio @brenorb @kuthullu @ninjastic @sabotag3x @Trimegistus
-1. Words can be uniquely determined typing the first 4 characters.
+1. Words can be uniquely determined by typing the first 4 characters.
2. No accents or special characters.
3. No complex verb forms.
4. No plural words, unless there's no singular form.
5. No words with double spelling.
-6. No words with the exact sound of another word with different spelling.
+6. No words with the exact sound as another word with different spelling.
7. No offensive words.
8. No words already used in other language mnemonic sets.
9. The words which have not the same spelling in Brazil and in Portugal are excluded.
-10. No words that remind negative/sad/bad things.
-11. No very similar words with 1 letter of difference.
+10. No words that remind one of negative/sad/bad things.
+11. No very similar words with only 1 letter of difference.
diff --git a/bip-0042.mediawiki b/bip-0042.mediawiki
index 223076f59e..d9cde15634 100644
--- a/bip-0042.mediawiki
+++ b/bip-0042.mediawiki
@@ -13,9 +13,9 @@
==Abstract==
-Although it is widely believed that Satoshi was an inflation-hating goldbug he never said this, and in fact programmed Bitcoin's money supply to grow indefinitely, forever. He modeled the monetary supply as 4 gold mines being discovered per mibillenium (1024 years), with equal intervals between them, each one being depleted over the course of 140 years.
+Although it is widely believed that Satoshi was an inflation-hating goldbug he never said this, and in fact programmed Bitcoin's money supply to grow indefinitely, forever. He modeled the monetary supply as 4 gold mines being discovered per mibillennium (1024 years), with equal intervals between them, each one being depleted over the course of 140 years.
-This poses obvious problems, however. Prominent among them is the discussion on what to call 1 billion Bitcoin, which symbol color to use for it, and when wallet clients should switch to it by default.
+This poses obvious problems, however. Prominent among them is the discussion on what to call 1 billion bitcoin, which symbol color to use for it, and when wallet clients should switch to it by default.
To combat this, this document proposes a controversial change: making Bitcoin's monetary supply finite.
@@ -42,7 +42,7 @@ Note that several other programming languages do not exhibit this behaviour, mak
===Floating-point approximation===
-An obvious solution would be to reimplement the shape of the subsidy curve using floating-point approximations, such as simulated annealing or quantitative easing, which have already proven their worth in consensus systems. Unfortunately, since the financial crisis everyone considers numbers with decimal points in them fishy, and integers are not well supported by Javascript.
+An obvious solution would be to reimplement the shape of the subsidy curve using floating-point approximations, such as simulated annealing or quantitative easing, which have already proven their worth in consensus systems. Unfortunately, since the financial crisis everyone considers numbers with decimal points in them fishy, and integers are not well supported by Javascript.
===Truncation===
diff --git a/bip-0043.mediawiki b/bip-0043.mediawiki
index 67b799da4e..365550dc82 100644
--- a/bip-0043.mediawiki
+++ b/bip-0043.mediawiki
@@ -7,7 +7,7 @@
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0043
Status: Final
- Type: Informational
+ Type: Standards Track
Created: 2014-04-24
@@ -20,7 +20,7 @@ based on algorithm described in BIP-0032 (BIP32 from now on).
Although Hierarchical Deterministic Wallet structure as described by BIP32
is an important step in user experience and security of the cryptocoin wallets,
-the BIP32 specification offers implementors too many degrees of freedom.
+the BIP32 specification offers implementers too many degrees of freedom.
Multiple implementations may claim they are BIP32 compatible, but in fact
they can produce wallets with different logical structures making them
non-interoperable. This situation unfortunately renders "BIP32 compatible"
@@ -42,6 +42,8 @@ We encourage different schemes to apply for assigning a separate BIP number
and use the same number for purpose field, so addresses won't be generated
from overlapping BIP32 spaces.
+Purpose codes from 10001 to 19999 are reserved for [[https://github.com/satoshilabs/slips|SLIPs]].
+
Example: Scheme described in BIP44 should use 44' (or 0x8000002C) as purpose.
Note that m / 0' / * is already taken by BIP32 (default account), which
diff --git a/bip-0044.mediawiki b/bip-0044.mediawiki
index 4ddd56b2cc..5db540c70a 100644
--- a/bip-0044.mediawiki
+++ b/bip-0044.mediawiki
@@ -6,7 +6,7 @@
Pavol Rusnak
Comments-Summary: Mixed review (one person)
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0044
- Status: Proposed
+ Status: Final
Type: Standards Track
Created: 2014-04-24
diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
new file mode 100644
index 0000000000..fbab00fddc
--- /dev/null
+++ b/bip-0046.mediawiki
@@ -0,0 +1,193 @@
+
+
+== Abstract ==
+
+This BIP defines the derivation scheme for HD wallets which create timelocked addresses used for creating fidelity bonds. It also gives advice to wallet developers on how to use fidelity bonds to sign over messages, such as certificates, which are needed when using fidelity bonds that are stored offline.
+
+== Copyright ==
+
+This document is licensed under the Creative Commons CC0 1.0 Universal license.
+
+== Motivation ==
+
+Fidelity bonds are used to resist sybil attacks in certain decentralized anonymous protocols. They are created by locking up bitcoins using the `OP_CHECKLOCKTIMEVERIFY` opcode.
+
+Having a common derivation scheme allows users of wallet software to have a backup of their fidelity bonds by storing only the HD seed and a reference to this BIP. Importantly the user does not need to backup any timelock values.
+
+We largely use the same approach used in BIPs 49, 84 and 86 for ease of implementation.
+
+This allows keeping the private keys of fidelity bonds in cold storage, which increases the sybil resistance of a system without hot wallet risk.
+
+== Backwards Compatibility ==
+
+This BIP is not backwards compatible by design as described in the Considerations section of [[bip-0049.mediawiki|BIP 49]]. An incompatible wallet will not discover fidelity bonds at all and the user will notice that something is wrong.
+
+== Background ==
+
+=== Fidelity bonds ===
+
+A fidelity bond is a mechanism where bitcoin value is deliberately sacrificed to make a cryptographic identity expensive to obtain. A way to create a fidelity bond is to lock up bitcoins by sending them to a timelocked address. The valuable thing being sacrificed is the time-value-of-money.
+
+The sacrifice must be done in a way that can be proven to a third party. This proof can be made by showing the UTXO outpoint, the address redeemscript and a signature which signs a message using the private key corresponding to the public key in the redeemscript.
+
+The sacrificed value is an objective measurement that can't be faked and which can be verified by anybody (just like, for example PoW mining). Sybil attacks can be made very expensive by forcing a hypothetical sybil attacker to lock up many bitcoins for a long time. JoinMarket implements fidelity bonds for protection from sybil attackers. At the time of writing over 600 BTC in total have been locked up with some for many years. Their UTXOs and signatures have been advertised to the world as proof. We can calculate that for a sybil attacker to succeed in unmixing all the CoinJoins, they would have to lock up over 100k BTC for several years.
+
+=== Fidelity bonds in cold storage ===
+
+To allow for holding fidelity bonds in cold storage, there is an intermediate keypair called the certificate.
+
+ UTXO key ---signs---> certificate ---signs---> endpoint
+
+Where the endpoint might be a IRC nickname or Tor onion hostname. The certificate keypair can be kept online and used to prove ownership of the fidelity bond. Even if the hot wallet private keys are stolen, the coins in the timelocked address will still be safe, although the thief will be able to impersonate the fidelity bond until the expiry.
+
+== Rationale ==
+
+It is useful for the user to avoid having to keep a record of the timelocks in the time-locked addresses. So only a limited small set of timelocks are defined by this BIP. This way the user must only store their seed phrase, and knowledge that they have coins stored using this BIP standard. The user doesn't need to remember or store any dates.
+
+This standard is already implemented and deployed in JoinMarket. As most changes would require a protocol change of a live system, there is limited scope for changing this standard in review. This BIP is more about documenting something which already exists, warts and all.
+
+== Specifications ==
+
+This BIP defines the two needed steps to derive multiple deterministic addresses based on a [[bip-0032.mediawiki|BIP 32]] master private key. It also defines the format of the certificate that can be signed by the deterministic address key.
+
+=== Public key derivation ===
+
+To derive a public key from the root account, this BIP uses a similar account-structure as defined in BIP [[bip-0084.mediawiki|44]] but with change set to 2.
+
+
+m / 84' / 0' / 0' / 2 / index
+
+
+A key derived with this derivation path pattern will be referred to as derived_key further
+in this document.
+
+For index, addresses are numbered from 0 in a sequentially increasing manner with a fixed upper bound: The index only goes up to 959 inclusive. Only 960 addresses can be derived for a given BIP32 master key. Furthermore there is no concept of a gap limit, instead wallets must always generate all 960 addresses and check for all of them if they have a balance and history.
+
+=== Timelock derivation ===
+
+The timelock used in the time-locked address is derived from the index. The timelock is a unix time. It is always at the start of the first second at the beginning of the month (see [[#Test vectors|Test vectors]]). The index counts upwards the months from January 2020, ending in December 2099. At 12 months per year for 80 years this totals 960 timelocks. Note that care must be taken with the year 2038 problem on 32-bit systems.
+
+
+year = 2020 + index // 12
+month = 1 + index % 12
+
+
+
+=== Address derivation ===
+
+To derive the address from the above calculated public key and timelock, we create a witness script which locks the funds until the timelock, and then checks the signature of the derived_key. The witness script is hashed with SHA256 to produce a 32-byte hash value that forms the witness program in the output script of the P2WSH address.
+
+ witnessScript: OP_CHECKLOCKTIMEVERIFY OP_DROP OP_CHECKSIG
+ witness:
+ scriptSig: (empty)
+ scriptPubKey: 0 <32-byte-hash>
+ (0x0020{32-byte-hash})
+
+=== Message signing ===
+
+In order to support signing of certificates, implementers should support signing ASCII messages.
+
+The certificate message is defined as `"fidelity-bond-cert" || "|" || cert_pubkey || "|" || cert_expiry`.
+
+The certificate expiry `cert_expiry` is the number of the 2016-block period after which the certificate is no longer valid. For example, if `cert_expiry` is 330 then the certificate will become invalid after block height 665280 (:=330x2016). The purpose of the expiry parameter is so that in case the certificate keypair is compromised, the attacker can only impersonate the fidelity bond for a limited amount of time.
+
+A certificate message can be created by another application external to this standard. It is then prepended with the string `0x18 || "Bitcoin Signed Message:\n"` and a byte denoting the length of the certificate message. The whole thing is then signed with the private key of the derived_key. This part is identical to the "Sign Message" function which many wallets already implement.
+
+Almost all wallets implementing this standard can use their already-existing "Sign Message" function to sign the certificate message. As the certificate message itself is always an ASCII string, the wallet may not need to specially implement this section at all but just rely on users copypasting their certificate message into the already-existing "Sign Message" user interface. This works as long as the wallet knows how to use the private key of the timelocked address for signing messages.
+
+It is most important for wallet implementations of this standard to support creating the certificate signature. Verifying the certificate signature is less important.
+
+
+== Test vectors ==
+
+
+mnemonic = abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
+rootpriv = xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu
+rootpub = xpub661MyMwAqRbcFkPHucMnrGNzDwb6teAX1RbKQmqtEF8kK3Z7LZ59qafCjB9eCRLiTVG3uxBxgKvRgbubRhqSKXnGGb1aoaqLrpMBDrVxga8
+
+// First timelocked address = m/84'/0'/0'/2/0
+derived private_key = L2tQBEdhC48YLeEWNg3e4msk94iKfyVa9hdfzRwUERabZ53TfH3d
+derived public_key = 02a1b09f93073c63f205086440898141c0c3c6d24f69a18db608224bcf143fa011
+unix locktime = 1577836800
+string locktime = 2020-01-01 00:00:00
+redeemscript = 0400e10b5eb1752102a1b09f93073c63f205086440898141c0c3c6d24f69a18db608224bcf143fa011ac
+scriptPubKey = 0020bdee9515359fc9df912318523b4cd22f1c0b5410232dc943be73f9f4f07e39ad
+address = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xkspsqn84
+
+// Test certificate using the first timelocked address
+// Note that as signatures contains a random nonce, it might not be exactly the same when your code generates it
+// p2pkh address is the p2pkh address corresponding to the derived public key, it can be used to verify the message
+// signature in any wallet that supports Verify Message.
+// As mentioned before, it is more important for implementers of this standard to support signing such messages, not verifying them
+message = fidelity-bond-cert|020000000000000000000000000000000000000000000000000000000000000001|375
+address = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xkspsqn84
+p2pkh address = 16vmiGpY1rEaYnpGgtG7FZgr2uFCpeDgV6
+signature = H2b/90XcKnIU/D1nSCPhk8OcxrHebMCr4Ok2d2yDnbKDTSThNsNKA64CT4v2kt+xA1JmGRG/dMnUUH1kKqCVSHo=
+
+// 2nd timelocked address = m/84'/0'/0'/2/1
+derived private_key = KxctaFBzetyc9KXeUr6jxESCZiCEXRuwnQMw7h7hroP6MqnWN6Pf
+derived public_key = 02599f6db8b33265a44200fef0be79c927398ed0b46c6a82fa6ddaa5be2714002d
+unix locktime = 1580515200
+string locktime = 2020-02-01 00:00:00
+redeemscript = 0480bf345eb1752102599f6db8b33265a44200fef0be79c927398ed0b46c6a82fa6ddaa5be2714002dac
+scriptPubKey = 0020b8f898643991608524ed04e0c6779f632a57f1ffa3a3a306cd81432c5533e9ae
+address = bc1qhrufsepej9sg2f8dqnsvvaulvv490u0l5w36xpkds9pjc4fnaxhq7pcm4h
+
+// timelocked address after the year 2038 = m/84'/0'/0'/2/240
+derived private_key = L3SYqae23ZoDDcyEA8rRBK83h1MDqxaDG57imMc9FUx1J8o9anQe
+derived public_key = 03ec8067418537bbb52d5d3e64e2868e67635c33cfeadeb9a46199f89ebfaab226
+unix locktime = 2208988800
+string locktime = 2040-01-01 00:00:00
+redeemscript = 05807eaa8300b1752103ec8067418537bbb52d5d3e64e2868e67635c33cfeadeb9a46199f89ebfaab226ac
+scriptPubKey = 0020e7de0ad2720ae1d6cc9b6ad91af57eb74646762cf594c91c18f6d5e7a873635a
+address = bc1qul0q45njptsadnymdtv34at7karyva3v7k2vj8qc7m2702rnvddq0z20u5
+
+// last timelocked address = m/84'/0'/0'/2/959
+derived private_key = L5Z9DDMnj5RZMyyPiQLCvN48Xt7GGmev6cjvJXD8uz5EqiY8trNJ
+derived public_key = 0308c5751121b1ae5c973cdc7071312f6fc10ab864262f0cbd8134f056166e50f3
+unix locktime = 4099766400
+string locktime = 2099-12-01 00:00:00
+redeemscript = 0580785df400b175210308c5751121b1ae5c973cdc7071312f6fc10ab864262f0cbd8134f056166e50f3ac
+scriptPubKey = 0020803268e042008737cf439748cbb5a4449e311da9aa64ae3ac56d84d059654f85
+address = bc1qsqex3czzqzrn0n6rjayvhddygj0rz8df4fj2uwk9dkzdqkt9f7zs5c493u
+
+// Test certificate and endpoint signing using the first timelocked address = m/84'/0'/0'/2/0 (see above)
+bond private_key = L2tQBEdhC48YLeEWNg3e4msk94iKfyVa9hdfzRwUERabZ53TfH3d
+bond p2pkh address = 16vmiGpY1rEaYnpGgtG7FZgr2uFCpeDgV6
+
+certificate private_key = KyZpNDKnfs94vbrwhJneDi77V6jF64PWPF8x5cdJb8ifgg2DUc9d
+certificate public_key = 0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c
+certificate p2pkh address = 1JaUQDVNRdhfNsVncGkXedaPSM5Gc54Hso
+
+certificate message = fidelity-bond-cert|0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c|375
+certificate signature = INOP3cB9UW7F1e1Aglj8rI9QhnyxmgWDEPt+nOMvl7hJJne7rH/KCNDYvLiqNuB9qWaWUojutjRsgPJrvyDQ+0Y=
+
+// example endpoint signing two IRC nicknames (used in JoinMarket)
+endpoint message = J54LS6YyJPoseqFS|J55VZ6U6ZyFDNeuv
+endpoint signature = H18WE4MugDNoWZIf9jU0njhQptdUyBDUf7lToG9bpMKmeJK0lOoABaDs5bKnohSuZ0e9gnSco5OL9lXdKU7gP5E=
+
+
+Code generating these test vectors can be found here: https://github.com/chris-belcher/timelocked-addresses-fidelity-bond-bip-testvectors
+
+== Reference ==
+
+* [[https://gist.github.com/chris-belcher/18ea0e6acdb885a2bfbdee43dcd6b5af/|Design for improving JoinMarket's resistance to sybil attacks using fidelity bonds]]
+* [[https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/fidelity-bonds.md|JoinMarket fidelity bonds doc page]]
+* [[bip-0065.mediawiki|BIP65 - OP_CHECKLOCKTIMEVERIFY]]
+* [[bip-0032.mediawiki|BIP32 - Hierarchical Deterministic Wallets]]
+* [[bip-0044.mediawiki|BIP44 - Multi-Account Hierarchy for Deterministic Wallets]]
+* [[bip-0049.mediawiki|BIP49 - Derivation scheme for P2WPKH-nested-in-P2SH based accounts]]
+* [[bip-0084.mediawiki|BIP84 - Derivation scheme for P2WPKH based accounts]]
+* [[bip-0086.mediawiki|BIP86 - Key Derivation for Single Key P2TR Outputs]]
diff --git a/bip-0047.mediawiki b/bip-0047.mediawiki
index af801f96ac..c44bea9d3b 100644
--- a/bip-0047.mediawiki
+++ b/bip-0047.mediawiki
@@ -1,7 +1,7 @@
RECENT CHANGES:
+* (15 Feb 2021) Finalize specification
+* (28 Sep 2017) Adjust text to match test vectors
* (19 Apr 2016) Define version 2 payment codes
-* (17 Apr 2016) Clarify usage of outpoints in notification transactions
-* (18 Dec 2015) Update explanations to resolve FAQs
+==Status==
+
+This BIP can be considered final in terms of enabling compatibility with wallets that implement version 1 and version 2 reusable payment codes, however future developments of the reusable payment codes specification will not be distributed via the BIP process.
+
+The Open Bitcoin Privacy Project RFC repo should be consulted for specifications related to version 3 or higher payment codes: https://github.com/OpenBitcoinPrivacyProject/rfc
+
==Abstract==
This BIP defines a technique for creating a payment code which can be publicly advertised and associated with a real-life identity without creating the loss of security or privacy inherent to P2PKH address reuse.
@@ -150,7 +156,7 @@ It is assumed that Alice can easily obtain Bob's payment code via a suitable met
Prior to the first time Alice initiates a transaction to Bob, Alice MUST inform Bob of her payment code via the following procedure:
-Note: this procedure is used if Bob uses a version 1 payment code (regardless of the the version of Alice's payment code). If Bob's payment code is not version 1, see the appropriate section in this specification.
+Note: this procedure is used if Bob uses a version 1 payment code (regardless of the version of Alice's payment code). If Bob's payment code is not version 1, see the appropriate section in this specification.
# Alice constructs a transaction which sends a small quantity of bitcoins to Bob's notification address (notification transaction)
## The inputs selected for this transaction MUST NOT be easily associated with Alice's notification address
@@ -158,7 +164,7 @@ Note: this procedure is used if Bob uses a version 1 payment code (regardless of
## Alice selects the private key corresponding to the designated pubkey:
a
## Alice selects the public key associated with Bob's notification address:
B, where B = bG
## Alice calculates a secret point:
S = aB
-## Alice calculates a 64 byte blinding factor:
s = HMAC-SHA512(x, o)
+## Alice calculates a 64 byte blinding factor:
s = HMAC-SHA512(o, x)
### "x" is the x value of the secret point
### "o" is the outpoint being spent by the designated input
# Alice serializes her payment code in binary form.
@@ -229,7 +235,7 @@ The following actions are recommended to reduce this risk:
# Bob is watching for incoming payments on B' ever since he received the notification transaction from Alice.
-## Bob calculates n shared secrets with Alice, using the 0th public key derived Alice's payment code, and private keys 0 - n derived from Bob's payment code, where n is his desired lookahead window.
+## Bob calculates n shared secrets with Alice, using the 0th public key derived from Alice's payment code, and private keys 0 - n derived from Bob's payment code, where n is his desired lookahead window.
## Bob calculates the ephemeral deposit addresses using the same procedure as Alice:
B' = B + sG
## Bob calculate the private key for each ephemeral address as:
b' = b + s
@@ -269,7 +275,7 @@ Normal operation of a payment code-enabled wallet can be performed by an SPV cli
Recovering a wallet from a seed, however, does require access to a fully-indexed blockchain.
-The required data may be obtained from copy of the blockchain under the control of the user, or via a publicly-queriable blockchain explorer.
+The required data may be obtained from copy of the blockchain under the control of the user, or via a publicly-queryable blockchain explorer.
When querying a public blockchain explorer, wallets SHOULD connect to the explorer through Tor (or equivalent) and SHOULD avoid grouping queries in a manner that associates ephemeral addresses with each other.
@@ -344,12 +350,12 @@ Version 2 payment codes behave identifically to version 1 payment codes, except
====Definitions====
-* Notification change output: the change output from a notification transaction which which resides in the sender's wallet, but can be automatically located by the intended recipient
+* Notification change output: the change output from a notification transaction which resides in the sender's wallet, but can be automatically located by the intended recipient
* Payment code identifier: a 33 byte representation of a payment code constructed by prepending 0x02 to the SHA256 hash of the binary serialization of the payment code
====Notification Transaction====
-Note: this procedure is used if Bob uses a version 2 payment code (regardless of the the version of Alice's payment code). If Bob's payment code is not version 2, see the appropriate section in this specification.
+Note: this procedure is used if Bob uses a version 2 payment code (regardless of the version of Alice's payment code). If Bob's payment code is not version 2, see the appropriate section in this specification.
# Construct a notification transaction as per the version 1 instructions, except do not create the output to Bob's notification address
# Create a notification change address as follows:
diff --git a/bip-0048.mediawiki b/bip-0048.mediawiki
new file mode 100644
index 0000000000..e2596e89dc
--- /dev/null
+++ b/bip-0048.mediawiki
@@ -0,0 +1,275 @@
+
+
+==Abstract==
+
+This BIP defines a logical hierarchy for deterministic multi-sig wallets based on an algorithm
+described in BIP-0067 (BIP67 from now on), BIP-0032 (BIP32 from now on), purpose scheme described in
+BIP-0043 (BIP43 from now on), and multi-account hierarchy described in
+BIP-0044 (BIP44 from now on).
+
+This BIP is a particular application of BIP43.
+
+==Copyright==
+
+This BIP falls under the MIT License.
+
+==Motivation==
+
+The motivation of this BIP is to define the existing industry wide practice of utilizing m/48'
+derivation paths in hierarchical deterministic multi-sig wallets so that other developers may
+benefit from a standard. This BIP allows for future script types to easily be appended to the
+specification so that a new BIP is not required for every future script type.
+
+The hierarchy proposed in this paper is quite comprehensive. It allows the handling of
+multiple accounts, external and internal chains per account, multiple script types and
+millions of addresses per chain.
+
+This paper was inspired from BIP44.
+
+==Backwards compatibility==
+
+Currently a number of wallets utilize the m/48' derivation scheme for HD multi-sig accounts.
+This BIP is intended to maintain the *existing* real world use of the m/48' derivation.
+No breaking changes are made so as to avoid "loss of funds" to existing users.
+Wallets which currently support the m/48' derivation will not need to make any changes
+to comply with this BIP.
+
+==Specification==
+
+===Key sorting===
+
+Any wallet that supports BIP48 inherently supports deterministic key sorting as per BIP67 so that all possible
+multi-signature addresses/scripts are derived from deterministically sorted public keys.
+
+===Path levels===
+
+We define the following 6 levels in BIP32 path:
+
+
+
+h or ' in the path indicates that BIP32 hardened derivation is used.
+
+Each level has a special meaning, described in the chapters below.
+
+===Purpose===
+
+Purpose is a constant set to 48' following the BIP43 recommendation.
+It indicates that the subtree of this node is used according to this specification.
+
+Hardened derivation is used at this level.
+
+===Coin type===
+
+One master node (seed) can be used for multiple Bitcoin networks.
+Sharing the same space for various networks has some disadvantages.
+
+Avoiding reusing addresses across networks and improving privacy issues.
+
+Coin type 0 for mainnet and 1 for testnet.
+
+Hardened derivation is used at this level.
+
+===Account===
+
+This level splits the key space into independent user identities, following the BIP44 pattern,
+so the wallet never mixes the coins across different accounts.
+
+Users can use these accounts to organize the funds in the same
+fashion as bank accounts; for donation purposes (where all
+addresses are considered public), for saving purposes,
+for common expenses etc.
+
+Accounts are numbered from index 0 in sequentially increasing manner.
+This number is used as child index in BIP32 derivation.
+
+Hardened derivation is used at this level.
+
+===Script===
+
+This level splits the key space into three separate script_type(s). To provide
+forward compatibility for future script types this specification can be easily extended.
+
+Currently the only script types covered by this BIP are Native Segwit (p2wsh),
+Nested Segwit (p2sh-p2wsh), and Taproot (p2tr).
+
+The following path represents Nested Segwit (p2sh-p2wsh) mainnet, account 0:
+1': Nested Segwit (p2sh-p2wsh) m/48'/0'/0'/1'
+
+The following path represents Native Segwit (p2wsh) mainnet, account 0:
+2': Native Segwit (p2wsh) m/48'/0'/0'/2'
+
+The following path represents Taproot (p2tr) mainnet, account 0:
+3': Taproot (p2tr) m/48'/0'/0'/3'
+
+The recommended default for wallets is pay to witness script hash m/48'/0'/0'/2'.
+
+To add new script types submit a PR to this specification and include it in the list above:
+X': Future script type m/48'/0'/0'/X'
+
+===Change===
+
+Constant 0 is used for external chain and constant 1 for internal chain (also
+known as change addresses). External chain is used for addresses that are meant
+to be visible outside of the wallet (e.g. for receiving payments). Internal
+chain is used for addresses which are not meant to be visible outside of the
+wallet and is used for return transaction change.
+
+Public derivation is used at this level.
+
+===Index===
+
+Addresses are numbered from index 0 in sequentially increasing manner.
+This number is used as child index in BIP32 derivation.
+
+Public derivation is used at this level.
+
+==Examples==
+
+{|
+|network
+|account
+|script
+|chain
+|address
+|path
+|-
+|mainnet
+|first
+|p2sh-p2wsh
+|external
+|first
+|m / 48' / 0' / 0' / 1' / 0 / 0
+|-
+|mainnet
+|first
+|p2wsh
+|external
+|first
+|m / 48' / 0' / 0' / 2' / 0 / 0
+|-
+|mainnet
+|first
+|p2wsh
+|external
+|second
+|m / 48' / 0' / 0' / 2' / 0 / 1
+|-
+|mainnet
+|first
+|p2wsh
+|change
+|first
+|m / 48' / 0' / 0' / 2' / 1 / 0
+|-
+|mainnet
+|first
+|p2wsh
+|change
+|second
+|m / 48' / 0' / 0' / 2' / 1 / 1
+|-
+|mainnet
+|second
+|p2wsh
+|external
+|first
+|m / 48' / 0' / 1' / 2' / 0 / 0
+|-
+|mainnet
+|second
+|p2wsh
+|external
+|second
+|m / 48' / 0' / 1' / 2' / 0 / 1
+|-
+|mainnet
+|first
+|p2tr
+|external
+|first
+|m / 48' / 0' / 0' / 3' / 0 / 0
+|-
+|testnet
+|first
+|p2sh-p2wsh
+|external
+|first
+|m / 48' / 1' / 0' / 1' / 0 / 0
+|-
+|testnet
+|first
+|p2wsh
+|external
+|second
+|m / 48' / 1' / 0' / 2' / 0 / 1
+|-
+|testnet
+|first
+|p2wsh
+|change
+|first
+|m / 48' / 1' / 0' / 2' / 1 / 0
+|-
+|testnet
+|first
+|p2wsh
+|change
+|second
+|m / 48' / 1' / 0' / 2' / 1 / 1
+|-
+|testnet
+|second
+|p2wsh
+|external
+|first
+|m / 48' / 1' / 1' / 2' / 0 / 0
+|-
+|testnet
+|second
+|p2wsh
+|external
+|second
+|m / 48' / 1' / 1' / 2' / 0 / 1
+|-
+|testnet
+|second
+|p2wsh
+|change
+|first
+|m / 48' / 1' / 1' / 2' / 1 / 0
+|-
+|testnet
+|second
+|p2wsh
+|change
+|second
+|m / 48' / 1' / 1' / 2' / 1 / 1
+|-
+|testnet
+|first
+|p2tr
+|external
+|first
+|m / 48' / 1' / 0' / 3' / 0 / 0
+|}
+
+
+==Reference==
+
+* [[bip-0067.mediawiki|BIP67 - Deterministic Pay-to-script-hash multi-signature addresses through public key sorting]]
+* [[bip-0032.mediawiki|BIP32 - Hierarchical Deterministic Wallets]]
+* [[bip-0043.mediawiki|BIP43 - Purpose Field for Deterministic Wallets]]
+* [[bip-0044.mediawiki|BIP44 - Multi-Account Hierarchy for Deterministic Wallets]]
diff --git a/bip-0049.mediawiki b/bip-0049.mediawiki
index 7d8d2c7496..3e37a0164b 100644
--- a/bip-0049.mediawiki
+++ b/bip-0049.mediawiki
@@ -6,7 +6,7 @@
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0049
Status: Final
- Type: Informational
+ Type: Standards Track
Created: 2016-05-19
License: PD
@@ -92,10 +92,10 @@ This BIP is not backwards compatible by design as described under [[#considerati
// Account 0, first receiving private key = m/49'/1'/0'/0/0
account0recvPrivateKey = cULrpoZGXiuC19Uhvykx7NugygA3k86b3hmdCeyvHYQZSxojGyXJ
account0recvPrivateKeyHex = 0xc9bdb49cfbaedca21c4b1f3a7803c34636b1d7dc55a717132443fc3f4c5867e8
- account0recvPublickKeyHex = 0x03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f
+ account0recvPublicKeyHex = 0x03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f
// Address derivation
- keyhash = HASH160(account0recvPublickKeyHex) = 0x38971f73930f6c141d977ac4fd4a727c854935b3
+ keyhash = HASH160(account0recvPublicKeyHex) = 0x38971f73930f6c141d977ac4fd4a727c854935b3
scriptSig = <0 > = 0x001438971f73930f6c141d977ac4fd4a727c854935b3
addressBytes = HASH160(scriptSig) = 0x336caa13e08b96080a32b5d818d59b4ab3b36742
diff --git a/bip-0052.mediawiki b/bip-0052.mediawiki
new file mode 100644
index 0000000000..ab86ca2268
--- /dev/null
+++ b/bip-0052.mediawiki
@@ -0,0 +1,302 @@
+
+
+
+== Simple Summary ==
+
+Bitcoin's energy consumption is growing with its value (see Figure below).
+Although scaling PoW is necessary to maintain the security of the network,
+reliance on massive energy consumption has scaling drawbacks and leads to mining
+centralization. A major consequence of the central role of local electricity
+cost in mining is that today, most existing and potential participants in the
+Bitcoin network cannot profitably mine Bitcoin even if they have the capital to
+invest in mining hardware. From a practical perspective, Bitcoin adoption by
+companies like Tesla (which recently rescinded its acceptance of Bitcoin as
+payment) has been hampered by its massive energy consumption and perceived
+environmental impact.
+
+
+
+Figure. Bitcoin price and estimated Bitcoin energy consumption.
+Data sources: [https://cbeci.org Cambridge Bitcoin Electricity Consumption Index], [https://www.coindesk.com CoinDesk].
+
+We propose a novel proof-of-work paradigm for Bitcoin--Optical proof-of-work. It
+is designed to decouple Bitcoin mining from energy and make it feasible outside
+of regions with low electricity costs. ''Optical proof-of-work'' (oPoW) is a
+modification of Hashcash that is most efficiently computed using a new class of
+photonic processors. Without compromising the cryptographic or game-theoretical
+security of Hashcash, oPoW shifts the operating expenses of mining (OPEX), to
+capital expenses (CAPEX)--i.e. electricity to hardware. oPoW makes it possible
+for billions of new miners to enter the market simply by investing in a
+low-energy photonic miner. Shifting to a high-CAPEX PoW has the added benefit of
+making the hashrate resilient to Bitcoin's price fluctuations - once low-OPEX
+hardware is operating there is no reason to shut it down even if the value of
+mining rewards diminishes. oPoW is hardware-compatible with GPUs, FPGAs, and
+ASICs meaning that a transitional period of optical and traditional hardware
+mining in parallel on the network is feasible
+
+More information is available here: [https://www.powx.org/opow].
+
+== Abstract ==
+
+As Bitcoin gained utility and value over the preceding decade, the network incentivized the purchase of billions of dollars in mining equipment and electricity. With the growth of competition, home mining became unprofitable. Even the most sophisticated special-purpose hardware (ASIC miners) doesn’t cover its energy costs unless the miner also has direct access to very cheap electricity. This heavy reliance on energy makes it difficult for new miners to enter the market and leads to hashrate instability as miners shut off their machines when the price of Bitcoin falls. Additionally as the network stores ever more value, the percentage of world energy consumption that is associated with Bitcoin continues to grow, creating the potential for scaling failure and a general backlash. To ensure that Bitcoin can continue scaling and reach its full potential as a world currency and store of value, we propose a low-energy proof-of-work paradigm for Bitcoin. ''Optical proof of work (oPoW)'' is designed to decouple Bitcoin’s security from massive energy use and make bitcoin mining feasible outside of regions with low electricity costs. ''Optical proof-of-work'' is a modification of Hashcash that is most efficiently computed using a new class of photonic processors that has emerged as a leading solution for ultra-low energy computing over the last 5 years. oPoW shifts the operating expenses of mining (OPEX), to capital expenses (CAPEX)–i.e. electricity to hardware, without compromising the cryptographic or game-theoretical security of Hashcash. We provide an example implementation of oPoW, briefly discuss its cryptographic construction as well as the working principle of photonic processors. Additionally, we outline the potential benefits of oPoW to the bitcoin network, including geographic decentralization and democratization of mining as well as hashrate resilience to price fluctuations.
+
+== Copyright ==
+
+This BIP is dual-licensed under the Open Publication License and BSD 2-clause license.
+
+== Motivation ==
+
+As Bitcoin has grown over the past decade from a small network run by hobbyists to a global currency, the underlying Proof of Work protocol has not been updated. Initially pitched as a global decentralized network (“one CPU-one vote”), Bitcoin transactions today are secured by a small group of corporate entities. In practice, it is only feasible for [http://archive.is/YeDwh entities that can secure access to abundant, inexpensive energy]. The economics of mining limit profitability to places like Iceland, Texas, or Western China. Besides the negative environmental externalities, which may be significant, mining today is performed primarily with the consent (and in many cases, partnership) of large public utilities and the governments that control them. Although this may not be a problem in the short term, in the long term it stands to erode the censorship resistance and security of Bitcoin and other public blockchains through potential regulation or [https://arxiv.org/pdf/1605.07524.pdf partitioning attacks].
+
+Recent events, such as the [https://twitter.com/MustafaYilham/status/1384278267067203590 ~25% hashrate crash due to coal-powered grid failure in china] and Tesla’s rescinding of its acceptance of Bitcoin as a form of payment, show that there are practical real-world downsides to Proof of Works’s massive reliance on energy.
+
+
+
+Whether or not the Bitcoin community accepts this common criticism as entirely valid, it has real-world effects which will only get worse over time. Eliminating the exponentially growing energy use currently built into Bitcoin without eliminating the security of PoW would be ideal and should not be a partisan issue.
+
+New consensus mechanisms have been proposed as a means of securing cryptocurrencies whilst reducing energy cost, such as various forms of Proof of Stake and Proof of Space-Time. While many of these alternative mechanisms offer compelling guarantees, they generally require new security assumptions, which have not been stress-tested by live deployments at any adequate scale. Consequently, we still have relatively little empirical understanding of their safety. Completely changing the Bitcoin paradigm is likely to introduce new unforeseen problems. We believe that the major issues discussed above can be resolved by improving rather than eliminating Bitcoin’s fundamental security layer—Proof of Work. Instead of devising a new consensus architecture to fix these issues, it is sufficient to shift the economics of PoW. The financial cost imposed on miners need not be primarily composed of electricity. The situation can be significantly improved by reducing the operating expense (OPEX)—energy—as a major mining component. Then, by shifting the cost towards capital expense (CAPEX)—mining hardware—the dynamics of the mining ecosystem becomes much less dependent on electricity prices, and much less electricity is consumed as a whole.
+
+Moreover, a reduction in energy consumption automatically leads to
+geographically distributed mining, as mining becomes profitable even in regions
+with expensive electricity. Additionally, lower energy consumption will
+eliminate heating issues experienced by today’s mining operations, which will
+further decrease operating cost as well as noise associated with fans and
+cooling systems. All of this means that individuals and smaller entities would
+be able to enter the mining ecosystem simply for the cost of a miner, without
+first gaining access to cheap energy or a dedicated, temperature-controlled data
+center. To a degree, memory-hard PoW schemes like
+[https://github.com/tromp/cuckoo Cuckoo Cycle], which increase the use of SRAM
+in lieu of pure computation, push the CAPEX/OPEX ratio in the right direction by
+occupying ASIC chip area with memory. To maximize the CAPEX to OPEX ratio of the
+Optical Proof of Work algorithm, we developed
+[https://assets.pubpub.org/xi9h9rps/01581688887859.pdf ''HeavyHash''] [1].
+HeavyHash is a cryptographic construction that takes the place of SHA256 in
+Hashcash. Our algorithm is hardware-compatible with ultra-energy-efficient photonic co-processors that have been developed for machine learning hardware accelerators.
+
+HeavyHash uses a proven digital hash (SHA3) packaged with a large amount of MAC (Multiply-and-Accumulate) computation into a Proof of Work puzzle. Although HeavyHash can be computed on any standard digital hardware, it becomes hardware efficient only when a small digital core is combined with a low-power photonic co-processor for performing MAC operations. oPoW mining machines will have a small digital core flip-chipped onto a large, low-power photonic chip. This core will be bottlenecked by the throughput of the digital to analog and analog to digital converters. A prototype of such analogue optical matrix multiplier can be seen in the figure below.
+
+
+
+Figure. TOP: Photonic Circuit Diagram, A. Laser input (1550nm, common telecom wavelength) B. Metal pads for controlling modulators to transduce electrical data to optical C. Metal pads for tuning mesh of directional couplers D. Optical signal exits here containing the results of the computation and is output to fibers via a grating coupler the terminus of each waveguide. E. Alignment circuit for aligning fiber coupling stage. Bottom: a photograph of a bare oPoW miner prototype chip before wire and fiber bonding. On the right side of the die are test structures (F).
+
+The ''HeavyHash'' derives its name from the fact that it is bloated or weighted with additional computation. This means that a cost comparable oPoW miner will have a much lower nominal hashrate compared to a Bitcoin ASIC (HeavyHashes/second vs. SHA256 Hashes/second in equivalent ASIC). We provide the cryptographic security argument of the HeavyHash function in Section 3 in [https://assets.pubpub.org/xi9h9rps/01581688887859.pdf Towards Optical Proof of Work] [1]. In the article, we also provide a game-theoretic security argument for CAPEX-heavy PoW. For additional information, we recommend reading [https://uncommoncore.co/wp-content/uploads/2019/10/A-model-for-Bitcoins-security-and-the-declining-block-subsidy-v1.02.pdf this article].
+
+While traditional digital hardware relies on electrical currents, optical
+computing uses light as the basis for some of or all of its operations. Building
+on the development and commercialization of silicon photonic chips for telecom
+and datacom applications, modern photonic co-processors are silicon chips made
+using well-established and highly scalable silicon CMOS processes. However,
+unlike cutting edge electronics which require ever-smaller features (e.g. 5 nm),
+fabricated by exponentially more complex and expensive machinery, silicon
+photonics uses old fabrication nodes (90 nm). Due to the large de Broglie
+wavelength of photons, as compared to electrons, there is no benefit to using
+the small feature sizes. The result is that access to silicon photonic wafer
+fabrication is readily available, in contrast to the notoriously difficult
+process of accessing advanced nodes. Moreover, the overall cost of entry is
+lower as lithography masks for silicon photonics processes are an order of
+magnitude cheaper ($500k vs. $5M). Examples of companies developing optical
+processors for AI, which will be hardware-compatible with oPoW include [https://lightmatter.co/ Lightmatter], [https://www.lightelligence.ai/ Lightelligence], [https://luminous.co/ Luminous], [https://www.intel.com/content/www/us/en/architecture-and-technology/silicon-photonics/silicon-photonics-overview.html Intel], and other more recent entrants.
+
+== Specification ==
+
+=== HeavyHash ===
+
+The HeavyHash is performed in three stages:
+
+# Keccak hash
+# Matrix-vector multiplication
+# Keccak of the result xored with the hashed input
+
+Note that the most efficient matrix-vector multiplication is performed on a
+photonic miner. However, this linear algebra operation can be performed on any
+conventional computing hardware (CPU, GPU, etc.), therefore making the HeavyHash
+hardware-compatible with any digital device.
+
+The algorithm’s pseudo-code:
+
+
// M is a Matrix 64 x 64 of Unsigned 4 values
+
+// 256-bitVector
+x1 <- keccak(input)
+
+// Reshape the obtained bitvector
+// into a 64-vector of unsigned 4-bit values
+x2 <- reshape(x1, 64)
+
+// Perform a matrix-vector multiplication.
+// The result is 64-vector of 14-bit unsigned.
+x3 <- vector_matrix_mult(x2, M)
+
+// Truncate all values to 4 most significant bits.
+// This is due to the specifics of analog
+// computing by the photonic accelerator.
+// Obtain a 64-vector of 4-bit unsigned.
+x4 <- truncate_to_msb(x3, 4)
+
+// Interpret as a 256-bitvector
+x5 <- flatten(x4)
+
+// 256-bitVector
+result <- keccak(xor(x5, x1))
+=== Random matrix generation ===
+
+The random matrix M (which is a HeavyHash parameter) is obtained in a deterministic way and is changed every block. Matrix M coefficients are generated using a pseudo-random number generation algorithm (xoshiro) from the previous block header. If the matrix is not full rank, it is repeatedly generated again.
+
+An example code to obtain the matrix M:
+
+
+
+== Discussion ==
+
+=== Geographic Distribution of Mining Relative to CAPEX-OPEX Ratio of Mining Costs ===
+
+Below is a simple model showing several scenarios for the geographic distribution of mining activity relative to the CAPEX/OPEX ratio of the cost of operating a single piece of mining hardware. As the ratio of energy consumption to hardware cost decreases, geographic variations in energy cost cease to be a determining factor in miner distribution.
+
+Underlying assumptions: 1. Electricity price y is fixed in time but varies geographically. 2. Every miner has access to the same hardware. 3. Each miner’s budget is limited by both the cost of mining equipment as well as the local cost of the electricity they consume
+
+budget = a(p+ey),
+
+where a is the number of mining machines, p is the machine price, e is the total energy consumption over machine lifetime, and y is electricity price.
+
+Note that in locations where mining is not profitable, hashrate is zero.
+
+
+
+
+
+
+
+An interactive version of this diagram can be found [https://www.powx.org/opow here].
+
+=== Why does CAPEX to OPEX shift lead to lower energy consumption? ===
+
+A common misconception about oPoW is that it makes mining “cheaper” by enabling energy-efficient hardware. There is no impact on the dollar cost of mining a block, rather the mix of energy vs. hardware investment changes from about 50/50 to 10/90 or better. We discuss this at length and rigorously in our paper[1].
+
+=== Working Principles of Photonic Processors ===
+
+Photonics accelerators are made by fabricating waveguides in silicon using standard lithography processes. Silicon is transparent to infrared light and can act as a tiny on-chip fiber optical cable. Silicon photonics found its first use during the 2000s in transceivers for sending and receiving optical signals via fiber and has advanced tremendously over the last decade.
+
+By encoding a vector into optical intensities passing through a series of parallel waveguides, interfering these signals in a mesh of tunable interferometers (acting as matrix coefficients), and then detecting the output using on-chip Germanium photodetectors, a matrix-vector multiplication is achieved. A generalized discussion of matrix multiplication setups using photonics/interference can be found in [https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.73.58 Reck et al.] and [https://arxiv.org/abs/1506.06220 Russell et al.] A detailed discussion of several integrated photonic architectures for matrix multiplication and corresponding tuning algorithms can be found in [https://arxiv.org/pdf/1909.06179.pdf Pai et al.]
+
+Below is a conceptual representation of a 3D-packaged oPoW mining chip. Note that the majority of the real estate and cost comes from the photonic die and the laser, with only a small digital SHA3 die needed (as opposed to a conventional miner of the same cost, which would have many copies of this die running in parallel).
+
+
+
+=== Block Reward Considerations ===
+
+Although it is out of the scope of this proposal, the authors strongly recommend the consideration of a change in the block reward schedule currently implemented in Bitcoin. There is no clear way to incentivize miners with transaction fees only, as has been successfully shown in [https://www.cs.princeton.edu/~smattw/CKWN-CCS16.pdf On the Instability of Bitcoin Without the Block Reward] and other publications, therefore looking a decade or two ahead it will be important to implement a fixed block reward or to slow the decay of the block reward to maintain the security of the network. Given that oPoW miners have low operating costs, once a large number of machines are running the reward level sufficient to keep them in operation and providing robust security can potentially be significantly smaller than in the case of the current SHA256 ASICs securing Bitcoin.
+
+=== Implementation on the Bitcoin Network ===
+
+A hard fork is not necessarily required for the Bitcoin network to test and eventually implement oPoW. It’s possible to add oPoW as a dual PoW to Bitcoin as a soft fork. Tuning the parameters to ensure that, for example, 99.9% of the security budget would be earned by miners via the SHA256 Hashcash PoW and 0.1% via oPoW would create sufficient incentive for oPoW to be stress-tested and to incentivize the manufacture of dedicated oPoW miners. If this test is successful, the parameters can be tuned continuously over time, e.g. oPoW share doubling at every halving, such that oPoW accounts for some target percentage (up to 100% in a complete SHA256 phase-out).
+
+
+==== Reverse compatibility ====
+
+Our understanding is that oPoW will not be reverse compatible.
+
+
+=== ASICBOOST ===
+
+Any new PoW algorithm carries the risk of hardware developers discovering and patenting an architecture with a significant speedup, as happened in the case of ASICBOOST for SHA256. HeavyHash is comprised of an SHA hash and 4-bit linear matrix-vector operations. The intent is for the matrix-vector multiplications to account for the majority of the work involved in computing a single HeavyHash operation. As we show in the Minimum Effective Hardness section of Towards Optical Proof of Work[1], there is no workaround to performing the matrix operations when computing HeavyHash, and since the SHA hashes are negligible, a true ASICBOOST-type speed up would require a speed up in linear matrix processing. Since matrix-vector multiplication is at the heart of neural networks and many other common computational workloads, it has been optimized very heavily and is generally very well understood. The acceleration of matrix-vector multiplication hardware (e.g. photonic coprocessors, memristors, etc.) is a very general problem and there are dozens of companies working on it, making it very unlikely for a single party to corner the market.
+
+== Endnotes ==
+
+With significant progress in optical and analog matrix-vector-multiplication chipsets over the last year, we hope to demonstrate commercial low-energy mining on our network in the next 6 months. The current generation of optical matrix processors under development is expected to have 10x better energy consumption per MAC operation than digital implementations, and we expect this to improve by another order of magnitude in future generations.
+
+PoWx will also be publishing the designs of the current optical miner prototypes in the near term under an open-source hardware license.
+
+== Acknowledgments ==
+
+We thank all the members of the Bitcoin community who have already given us feedback over the last several years as well as others in the optical computing community and beyond that have given their input.
+
+
+
+
+[1] M. Dubrovsky et al. Towards Optical Proof of Work, CES conference (2020) https://assets.pubpub.org/xi9h9rps/01581688887859.pdf
+
+[2] https://sciencex.com/news/2020-05-powering-bitcoin-silicon-photonics-power.html
+
+[3] KISS random number generator http://www.cse.yorku.ca/~oz/marsaglia-rng.html
+
diff --git a/bip-0052/btc_energy-small.png b/bip-0052/btc_energy-small.png
new file mode 100644
index 0000000000..32ffde301d
Binary files /dev/null and b/bip-0052/btc_energy-small.png differ
diff --git a/bip-0052/btc_energy.png b/bip-0052/btc_energy.png
new file mode 100644
index 0000000000..cc37d3ade5
Binary files /dev/null and b/bip-0052/btc_energy.png differ
diff --git a/bip-0052/emusk_tweet.png b/bip-0052/emusk_tweet.png
new file mode 100644
index 0000000000..6e7f0655b4
Binary files /dev/null and b/bip-0052/emusk_tweet.png differ
diff --git a/bip-0052/optical_chip.png b/bip-0052/optical_chip.png
new file mode 100644
index 0000000000..f3ec05c583
Binary files /dev/null and b/bip-0052/optical_chip.png differ
diff --git a/bip-0052/optminer.png b/bip-0052/optminer.png
new file mode 100644
index 0000000000..4fd639b89a
Binary files /dev/null and b/bip-0052/optminer.png differ
diff --git a/bip-0052/sim1.png b/bip-0052/sim1.png
new file mode 100644
index 0000000000..4b6b86324f
Binary files /dev/null and b/bip-0052/sim1.png differ
diff --git a/bip-0052/sim2.png b/bip-0052/sim2.png
new file mode 100644
index 0000000000..043cfc25e2
Binary files /dev/null and b/bip-0052/sim2.png differ
diff --git a/bip-0052/sim3.png b/bip-0052/sim3.png
new file mode 100644
index 0000000000..ee5f71ec55
Binary files /dev/null and b/bip-0052/sim3.png differ
diff --git a/bip-0054.md b/bip-0054.md
new file mode 100644
index 0000000000..9b055966da
--- /dev/null
+++ b/bip-0054.md
@@ -0,0 +1,234 @@
+```
+ BIP: 54
+ Layer: Consensus (soft fork)
+ Title: Consensus Cleanup
+ Author: Antoine Poinsot
+ Matt Corallo
+ Comments-Summary: No comments yet.
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0054
+ Status: Draft
+ Type: Standards Track
+ Created: 2024-04-11
+ License: CC0-1.0
+```
+
+## Abstract
+
+This document proposes new consensus rules in order to fix the timewarp attack, reduce the worst
+case block validation time, prevent Merkle tree weaknesses, and avoid duplicate transactions without
+[bip-0030][BIP30] validation.
+
+## Motivation
+
+This proposal addresses a number of long-standing vulnerabilities and weaknesses in the Bitcoin
+protocol. Bundling these fixes together allows to overcome the fixed cost of deploying a Bitcoin
+soft fork.
+
+The timewarp bug permits a majority hashrate attacker to arbitrarily increase the block rate,
+allowing them to steal block subsidy from future miners and increase validation costs to nodes that
+have to deal with the increased average transaction rate. By strategically setting the block
+timestamp, the [timewarp bug][SE timewarp] lets miners bring down the difficulty to its minimum
+within 38 days of starting the attack. The existence of this bug not only significantly empowers a
+51% attacker, but also makes it notably harder to reason about miners' incentives. It could indeed
+be in the interest of short-sighted miners as well as short-sighted users to exploit this
+vulnerability in a small enough proportion to increase the block rate without fatally hurting the
+network, as the effectively increased block space would — all other things being equal — bring fee
+rates down for users.
+
+Specially crafted blocks may be expensive to process, with validation times ranging from a few
+minutes up to more than an hour on lower-end devices. Long block validation times are a nuisance to
+users, increasing the cost to independently fully validate the consensus rules. In addition they can
+be used by miners to attack their competition, creating perverse incentives, centralization
+pressures and leading to reduced network security.
+
+In computing a block's Merkle root, a 64-byte transaction can be interpreted as an intermediate
+node in the tree in addition to a leaf. This makes it possible to fake inclusion proofs by
+pretending a 64-byte block transaction is an inner node, as well as to pretend the inner nodes on
+one level of the tree are the actual block transactions.
+
+Since [bip-0034][BIP34] activation, explicit [bip-0030][BIP30] validation is not necessary until
+block height 1,983,702[^0]. Mandating new coinbase transactions be different from the early
+[bip-0034][BIP34] violations makes it possible to get rid of [bip-0030][BIP30] validation forever.
+Besides its unnecessary cost, another downside of [bip-0030][BIP30] validation is that it cannot be
+performed by Utreexo clients. Finally, leveraging the coinbase transaction's `nLockTime` field
+allows applications to recover the block height corresponding to a coinbase transaction without
+having to parse Script.
+
+## Specification
+
+For all blocks after activation the following new rules apply.
+
+Given a block at height `N`:
+- if `N % 2016` is equal to 0, the timestamp of the block must be set to a value higher than or
+ equal to the value of the timestamp of block at height `N-1` minus 7200 (TN ≥
+ TN−1 − 7200);
+- if `N % 2016` is equal to 2015, the timestamp of the block must be set to a value higher than
+ or equal to the value of the timestamp of the block at height `N-2015` (TN ≥
+ TN−2015).
+
+A limit is set on the number of potentially executed signature operations in validating a
+transaction. It applies to all transactions in the block except the coinbase transaction[^1]. For
+each input in the transaction, count the number of `CHECKSIG` and `CHECKMULTISIG` in the input
+scriptSig and previous output's scriptPubKey, including the P2SH redeemScript. The accounting is the
+same as for [bip-0016][BIP16 specs]: a `CHECKSIG`/`CHECKSIGVERIFY` operation accounts for 1 and a
+`CHECKMULTISIG`/`CHECKMULTISIGVERIFY` accounts for the number of public keys associated, or 20 if
+the number of public keys is greater than 16. A `CHECKMULTISIG`/`CHECKMULTISIGVERIFY` not directly
+preceded by a minimally-pushed number between 1 and 16 (included) accounts for 20. If the
+total is strictly higher than 2500, the transaction is invalid.
+
+Transactions whose witness-stripped serialized size is exactly 64 bytes are invalid.
+
+The coinbase transaction's `nLockTime` field must be set to the height of the block minus 1[^2]
+and its `nSequence` field must not be equal to 0xffffffff.
+
+## Rationale
+
+The restrictions on the timestamp of the first and last blocks of a difficulty adjustment period fix
+the timewarp and Murch–Zawy vulnerabilities[^3]. The latter poses mostly theoretical concerns but is
+extremely low risk to fix: the duration of an adjustment period has never been, and should never be,
+negative. The former is fixed by preventing the timestamp of the first block of a difficulty period
+from being lower than the previous block's, with a two-hour grace period. A [previous
+proposal][BIP-XXXX] to fix timewarp used a ten-minute grace period instead, also adopted for
+[testnet4][BIP94 timewarp]. Out of an abundance of caution and because it only trivially worsens the
+block rate increase under attack, a two-hour grace period is used here[^4].
+
+Disabling some Script operations and functionalities was [previously proposed][BIP-XXXX] to reduce
+the worst case block validation time but was met with resistance due to confiscation concerns[^5]. A
+delicate balance needs to be struck between minimizing the confiscation risks of a mitigation, even
+if merely theoretical, and bounding the costs one could impose on all other users of the system. To
+this effect a limit on the number of potentially executed signature operations pinpoints exactly the
+harmful behaviour, leaving maximum flexibility in how Script functionalities may have been used.
+Such a limit reduces the worst case block validation time by a factor of 40 and drastically
+increases the preparation cost of an attack to make it uneconomical for a miner[^6]. The maximum of
+2500 was chosen as the tightest value that did not make any non-pathological standard transaction
+invalid[^7].
+
+In the presence of 64-byte transactions a block header's Merkle root may be valid for different sets
+of transactions. This is because in the Merkle tree construction a 64-byte transaction may be
+interpreted as the catenation of two 32-byte hashes, or the catenation of two 32-byte hashes may be
+interpreted as a transaction. The former allows to fake a block inclusion proof and the latter makes
+it such that for a valid block the Merkle root in the block header is not a unique identifier for
+the corresponding list of valid transactions[^8]. 64-byte transactions can only contain a
+scriptPubKey that lets anyone spend the funds, or one that burns them. 64-byte transactions have
+also been non-standard since 2019. It was suggested that the known vulnerabilities could instead be
+mitigated by committing to the Merkle tree depth in the header's version field[^9]. The authors
+believe it is preferable to address the root cause by invalidating 64-byte transactions. This
+approach also fixes the vulnerability without developers of SPV verifiers having to implement the
+mitigation or to know it is necessary in the first place.
+
+Several blocks prior to [bip-0034][BIP34] activation contain a coinbase transaction whose scriptSig
+contains a valid [bip-0034][BIP34] commitment to a future block height. This offers an opportunity
+to duplicate these coinbase transactions in the future[^10] and for this reason [bip-0030][BIP30]
+validation will need to be re-activated from block 1,983,702. A simple way to prevent this is to
+mandate that future coinbase transactions vary from coinbase transactions before [bip-0034][BIP34]
+activation. There are multiple ways of achieving this, but setting and enforcing the timelock for
+the coinbase transaction makes it so all coinbase transactions past Consensus Cleanup activation
+could not have been valid before this height and therefore cannot be a duplicate[^11].
+
+## Backward compatibility
+
+This proposal only tightens the block validation rules: there is no block that is valid under the
+rules proposed in this BIP but not under the existing Bitcoin consensus rules. As a consequence
+these changes are backward-compatible with non-upgraded node software. That said, the authors
+strongly encourage node operators to upgrade in order to fully validate all consensus rules.
+
+## Miner forward compatibility
+
+Bitcoin Core version [29.0][Core 29.0] and later will not generate a block template that violates
+the timestamp restrictions introduced in this BIP. Although it would be extremely unlikely due to
+the grace period used in this proposal, miners should use the `curtime` or `mintime` field from the
+`getblocktemplate` result for their block's timestamp to make sure they always create blocks valid
+according to this proposal. Note this is not a new requirement: using a timestamp lower than the
+`mintime` field from the `getblocktemplate` result already leads to creating an invalid block.
+
+Bitcoin Core as of version 29.0 may relay and create a block template including a transaction that
+violates the signature operations limit introduced in this BIP. A newer version of Bitcoin Core
+that makes this type of transaction non-standard should be widely adopted before this soft fork is
+considered for activation.
+
+Bitcoin Core version [0.16.1][Core 0.16.1] and later will neither relay nor create block templates
+that include 64-byte transactions.
+
+The coinbase transaction is usually crafted by mining pool software. To the best of the authors'
+knowledge, there does not exist an open source reference broadly in use today for such software.
+We encourage mining pools to update their software to craft coinbase transactions that are
+forward-compatible with the changes proposed in this BIP.
+
+## Acknowledgements
+
+This document builds upon an [earlier proposal][BIP-XXXX] by Matt Corallo.
+
+The authors would like to thank everyone involved in researching the most appropriate mitigation for
+each of these bugs. We would like to thank in particular Anthony Towns and Sjors Provoost for their
+direct contributions to this proposal, as well as @0xb10c and Brian Groll for providing the authors
+with data to analyze the proposed mitigations.
+
+## Copyright
+
+This document is licensed under the Creative Commons CC0 1.0 Universal license.
+
+
+[^0]: Block 1,983,702 is the earliest future block which could contain a duplicate coinbase
+transaction while still respecting [bip-0034][BIP34]. See [this post][Delving duplicable] for a list
+of all such future blocks.
+[^1]: Technically this limit *cannot* apply to a coinbase transaction as the size of its sole
+input's scriptSig is limited.
+[^2]: The locktime validation, which is also performed for coinbase transactions, enforces that the
+nLockTime value is the last block at which a transaction is invalid, not the first one at which it
+is valid.
+[^3]: The timewarp attack is described [here][SE timewarp] and the Murch–Zawy attack [here][Delving
+Murch-Zawy].
+[^4]: The testnet4 difficulty exception pushed blocks' timestamps in the future when abused,
+revealing how some broken pool software may produce blocks that don't respect a 10 minutes grace
+period. Some [raised concerns][Sjors grace period] similarly broken software might be used on
+mainnet. Using a grace period of 2 hours instead of 10 minutes only reduces the expected block
+interval time under attack by ~2.2 seconds. See [this post][grace period debate summary] for more.
+[^5]: The argument is about someone having a timelocked presigned transaction using some of those
+features in its output script. The transaction cannot be mined before activation. Such outputs would
+not be covered by an amnesty for old UTxOs. See for instance [here][O'Connor OP_CODESEPARATOR] and
+[here][O'Connor sighash type] for discussions on this topic.
+[^6]: It is important to reduce the worst case block validation time as well as the ratio of
+validation time imposed over preparation cost. The former is to limit the damages an externally
+motivated attacker can do. The latter is to disincentivize miners slowing down their competition by
+mining expensive blocks. See [this thread][ML thread validation time] for more.
+[^7]: A non-pathological transaction would have a public key per signature operation and at least
+one signature per input. Per standardness a single P2SH input may not have more than 15 signature
+operations. Even by using 1-of-15 `CHECKMULTISIG`s a transaction would bump against the maximum
+standard transaction size before running into the newly introduced limit. To run against the newly
+introduced limit but not the transaction size a transaction would need to spend P2SH inputs with a
+redeem script similar to `CHECKSIG DROP CHECKSIG DROP ...`. This type of redeem script serves no
+purpose beyond increasing its validation cost, which is exactly what this proposal aims to mitigate.
+[^8]: See [this writeup][Suhas Merkle] by Suhas Daftuar for an explanation as well as a discussion
+of the consequences.
+[^9]: By Sergio Demian Lerner in a [blog post][Sergio post] surfaced [by Eric Voskuil][Eric
+version]. Eric also pushed back against the importance of fixing this issue. See [this post][64
+bytes debate] for an attempt at summarizing the arguments for both sides of this debate.
+[^10]: See [here][BIP34 list] for a full list of the heights of historical blocks including a valid
+bip-0034 height commitment and the corresponding future block height.
+[^11]: Technically it could be argued a duplicate could in principle always be possible before block
+31,001 when `nLockTime` enforcement [was originally soft-forked][Harding nLockTime]. But treating
+coinbase transactions as not having duplicate past Consensus Cleanup activation would be consistent
+for any implementation which enforces `nLockTime` from the genesis block, which is the behaviour
+notably of Bitcoin Core but also of all other implementations the authors are aware of.
+
+[BIP30]: https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki
+[BIP-XXXX]: https://github.com/TheBlueMatt/bips/blob/7f9670b643b7c943a0cc6d2197d3eabe661050c2/bip-XXXX.mediawiki
+[BIP34]: https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki
+[BIP16 specs]: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki#specification
+[SE timewarp]: https://bitcoin.stackexchange.com/questions/75831/what-is-time-warp-attack-and-how-does-it-work-in-general/75834#75834
+[Delving Murch-Zawy]: https://delvingbitcoin.org/t/zawy-s-alternating-timestamp-attack/1062#variant-on-zawys-attack-2
+[BIP94 timewarp]: https://github.com/bitcoin/bips/blob/master/bip-0094.mediawiki#user-content-Time_Warp_Fix
+[Sjors grace period]: https://delvingbitcoin.org/t/timewarp-attack-600-second-grace-period/1326
+[grace period debate summary]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/66
+[O'Connor OP_CODESEPARATOR]: https://gnusha.org/pi/bitcoindev/CAMZUoKneArC+YZ36YFwxNTKsDtJhEz5P2cosXKxJS8Rf_3Nyuw@mail.gmail.com
+[O'Connor sighash type]: https://gnusha.org/pi/bitcoindev/CAMZUoK=1kgZLR1YZ+cJgzwmEOwrABYFs=2Ri=xGX=BCr+w=VQw@mail.gmail.com
+[ML thread validation time]: https://gnusha.org/pi/bitcoindev/VsltJ2PHqWfzG4BU9YETTXjL7fYBbJhjVXKZQyItemySIA1okvNee9kf0zAOyLMeJ4Nqv1VOrYbWns5nP4TANCWvPJYu1ew_yxQSaudizzk=@protonmail.com
+[Suhas Merkle]: https://gnusha.org/pi/bitcoindev/CAFp6fsGtEm9p-ZQF_XqfqyQGzZK7BS2SNp2z680QBsJiFDraEA@mail.gmail.com
+[Sergio post]: https://bitslog.com/2018/06/09/leaf-node-weakness-in-bitcoin-merkle-tree-design
+[Eric version]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/37
+[64 bytes debate]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/41
+[BIP34 list]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/4
+[Harding nLockTime]: https://bitcoin.stackexchange.com/questions/90229/nlocktime-in-bitcoin-core
+[Delving duplicable]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/4
+[Core 0.16.1]: https://bitcoincore.org/en/releases/0.16.1
+[Core 29.0]: https://bitcoincore.org/en/releases/29.0
diff --git a/bip-0060.mediawiki b/bip-0060.mediawiki
index 8e9f289f05..80a5f5637c 100644
--- a/bip-0060.mediawiki
+++ b/bip-0060.mediawiki
@@ -5,7 +5,7 @@
Author: Amir Taaki
Comments-Summary: Discouraged for implementation (one person)
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0060
- Status: Draft
+ Status: Rejected
Type: Standards Track
Created: 2013-06-16
License: PD
@@ -23,14 +23,14 @@ The implementation is problematic because the RelayTransactions flag is an optio
One property of Bitcoin messages is their fixed number of fields. This keeps the format simple and easily understood. Adding optional fields to messages will cause deserialisation issues when other fields come after the optional one.
-As an example, the length of version messages might be checked to ensure the byte stream is consistent. With optional fields, this checking is no longer possible. This is desirable to check for consistency inside internal deserialization code, and proper formatting of version messages originating from other nodes. In the future with diversification of the Bitcoin network, it will become desirable to enforce this kind of strict adherance to standard messages with field length compliance with every protocol version.
+As an example, the length of version messages might be checked to ensure the byte stream is consistent. With optional fields, this checking is no longer possible. This is desirable to check for consistency inside internal deserialization code, and proper formatting of version messages originating from other nodes. In the future with diversification of the Bitcoin network, it will become desirable to enforce this kind of strict adherence to standard messages with field length compliance with every protocol version.
Another property of fixed-length field messages is the ability to pass stream operators around for deserialization. This property is also lost, as now the deserialisation code must know the remaining length of bytes to parse. The parser now requires an additional piece of information (remaining size of the stream) for parsing instead of being a dumb reader.
==Specification==
=== version ===
-When a node creates an outgoing connection, it will immediately advertise its version. The remote node will respond with its version. No futher communication is possible until both peers have exchanged their version.
+When a node creates an outgoing connection, it will immediately advertise its version. The remote node will respond with its version. No further communication is possible until both peers have exchanged their version.
Payload:
diff --git a/bip-0061.mediawiki b/bip-0061.mediawiki
index b08739ddc1..f15b71a7a9 100644
--- a/bip-0061.mediawiki
+++ b/bip-0061.mediawiki
@@ -57,7 +57,7 @@ Every reject message begins with the following fields. Some messages append extr
|}
The human-readable string is intended only for debugging purposes; in particular, different implementations may
-use different strings. The string should not be shown to users or used for anthing besides diagnosing
+use different strings. The string should not be shown to users or used for anything besides diagnosing
interoperability problems.
The following reject code categories are used; in the descriptions below, "server" is the peer generating
@@ -149,7 +149,7 @@ The reject message is backwards-compatible; older peers that do not recognize th
== Implementation notes ==
-Implementors must consider what happens if an attacker either sends them
+Implementers must consider what happens if an attacker either sends them
reject messages for valid transactions/blocks or sends them random
reject messages, and should beware of possible denial-of-service attacks.
For example, notifying the user of every reject message received
diff --git a/bip-0062.mediawiki b/bip-0062.mediawiki
index 7dd2b5b6db..418c2e45ff 100644
--- a/bip-0062.mediawiki
+++ b/bip-0062.mediawiki
@@ -34,7 +34,7 @@ Several sources of malleability are known:
# '''Non-DER encoded ECDSA signatures''' Right now, the Bitcoin reference client uses OpenSSL to validate signatures. As OpenSSL accepts more than serializations that strictly adhere to the DER standard, this is a source of malleability. Since v0.8.0, non-DER signatures are no longer relayed already.
# '''Non-push operations in scriptSig''' Any sequence of script operations in scriptSig that results in the intended data pushes, but is not just a push of that data, results in an alternative transaction with the same validity.
-# '''Push operations in scriptSig of non-standard size type''' The Bitcoin scripting language has several push operators (OP_0, single-byte pushes, data pushes of up to 75 bytes, OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4). As the later ones have the same result as the former ones, they result in additional possibilities.
+# '''Push operations in scriptSig of non-standard size type''' The Bitcoin scripting language has several push operators (OP_0, single-byte pushes, data pushes of up to 75 bytes, OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4). As the latter ones have the same result as the former ones, they result in additional possibilities.
# '''Zero-padded number pushes''' In cases where scriptPubKey opcodes use inputs that are interpreted as numbers, they can be zero padded.
# '''Inherent ECDSA signature malleability''' ECDSA signatures themselves are already malleable: taking the negative of the number S inside (modulo the curve order) does not invalidate it.
# '''Superfluous scriptSig operations''' Adding extra data pushes at the start of scripts, which are not consumed by the corresponding scriptPubKey, is also a source of malleability.
diff --git a/bip-0064.mediawiki b/bip-0064.mediawiki
index 82a6cfdc84..02c4c2a8ea 100644
--- a/bip-0064.mediawiki
+++ b/bip-0064.mediawiki
@@ -86,7 +86,7 @@ If the requesting client is looking up outputs for a signed transaction that the
client can partly verify the returned output by running the input scripts with it. Currently this
verifies only that the script is correct. A future version of the Bitcoin protocol is likely to also
allow the value to be checked in this way. It does not show that the output is really unspent or was
-ever actually created in the block chain however. Additionally, the form of the provided scriptPubKey
+ever actually created in the block chain however. Additionally, the form of the provided scriptPubKey
should be checked before execution to ensure the remote peer doesn't just set the script to OP_TRUE.
If the requesting client has a mapping of chain heights to block hashes in the best chain e.g.
diff --git a/bip-0065.mediawiki b/bip-0065.mediawiki
index 1365884c09..db10c0ca9f 100644
--- a/bip-0065.mediawiki
+++ b/bip-0065.mediawiki
@@ -170,7 +170,7 @@ Proving the sacrifice of some limited resource is a common technique in a
variety of cryptographic protocols. Proving sacrifices of coins to mining fees
has been proposed as a ''universal public good'' to which the sacrifice could
be directed, rather than simply destroying the coins. However doing so is
-non-trivial, and even the best existing technqiue - announce-commit sacrifices
+non-trivial, and even the best existing technique - announce-commit sacrifices
- could encourage mining centralization. CHECKLOCKTIMEVERIFY can be used to
create outputs that are provably spendable by anyone (thus to mining fees
assuming miners behave optimally and rationally) but only at a time
@@ -205,19 +205,19 @@ transaction output ''can'' be spent.
Refer to the reference implementation, reproduced below, for the precise
semantics and detailed rationale for those semantics.
-
+
case OP_NOP2:
{
// CHECKLOCKTIMEVERIFY
//
// (nLockTime -- nLockTime )
-
+
if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY))
break; // not enabled; treat as a NOP
-
+
if (stack.size() < 1)
return false;
-
+
// Note that elsewhere numeric opcodes are limited to
// operands in the range -2**31+1 to 2**31-1, however it is
// legal for opcodes to produce results exceeding that
@@ -233,13 +233,13 @@ semantics and detailed rationale for those semantics.
// to 5-byte bignums, which are good until 2**32-1, the
// same limit as the nLockTime field itself.
const CScriptNum nLockTime(stacktop(-1), 5);
-
+
// In the rare event that the argument may be < 0 due to
// some arithmetic being done first, you can always use
// 0 MAX CHECKLOCKTIMEVERIFY.
if (nLockTime < 0)
return false;
-
+
// There are two types of nLockTime: lock-by-blockheight
// and lock-by-blocktime, distinguished by whether
// nLockTime < LOCKTIME_THRESHOLD.
@@ -252,12 +252,12 @@ semantics and detailed rationale for those semantics.
(txTo.nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)
))
return false;
-
+
// Now that we know we're comparing apples-to-apples, the
// comparison is a simple numeric one.
if (nLockTime > (int64_t)txTo.nLockTime)
return false;
-
+
// Finally the nLockTime feature can be disabled and thus
// CHECKLOCKTIMEVERIFY bypassed if every txin has been
// finalized by setting nSequence to maxint. The
@@ -270,9 +270,9 @@ semantics and detailed rationale for those semantics.
// required to prove correct CHECKLOCKTIMEVERIFY execution.
if (txTo.vin[nIn].IsFinal())
return false;
-
+
break;
-
+
}
https://github.com/petertodd/bitcoin/commit/ab0f54f38e08ee1e50ff72f801680ee84d0f1bf4
diff --git a/bip-0066.mediawiki b/bip-0066.mediawiki
index 936d50754e..53289f5521 100644
--- a/bip-0066.mediawiki
+++ b/bip-0066.mediawiki
@@ -75,7 +75,7 @@ bool static IsValidSignatureEncoding(const std::vector &sig) {
// Verify that the length of the signature matches the sum of the length
// of the elements.
if ((size_t)(lenR + lenS + 7) != sig.size()) return false;
-
+
// Check whether the R element is an integer.
if (sig[2] != 0x02) return false;
@@ -140,7 +140,7 @@ An implementation for the reference client is available at https://github.com/bi
==Acknowledgements==
-This document is extracted from the previous BIP62 proposal, which had input from various people, in particular Greg Maxwell and Peter Todd, who gave feedback about this document as well.
+This document is extracted from the previous BIP62 proposal, which had input from various people, in particular Greg Maxwell and Peter Todd, who gave feedback about this document as well.
==Disclosures==
diff --git a/bip-0067.mediawiki b/bip-0067.mediawiki
index b1642894ed..30ed407517 100644
--- a/bip-0067.mediawiki
+++ b/bip-0067.mediawiki
@@ -19,7 +19,7 @@ This BIP describes a method to deterministically generate multi-signature pay-to
==Motivation==
-Pay-to-script-hash (BIP-0011[https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki BIP-0011]) is a transaction type that allows funding of arbitrary scripts, where the recipient carries the cost of fee's associated with using longer, more complex scripts.
+Pay-to-script-hash (BIP-0011[https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki BIP-0011]) is a transaction type that allows funding of arbitrary scripts, where the recipient carries the cost of fee's associated with using longer, more complex scripts.
Multi-signature pay-to-script-hash transactions are defined in BIP-0016[https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki BIP-0016]. The redeem script does not require a particular ordering or encoding for public keys. This means that for a given set of keys and number of required signatures, there are as many as 2(n!) possible standard redeem scripts, each with its separate P2SH address. Adhering to an ordering and key encoding would ensure that a multi-signature “account” (set of public keys and required signature count) has a canonical P2SH address.
@@ -27,36 +27,36 @@ By adopting a sorting and encoding standard, compliant wallets will always produ
While most web wallets do not presently facilitate the setup of multisignature accounts with users of a different service, conventions which ensure cross-compatibility should make it easier to achieve this.
-Many wallet as a service providers use a 2of3 multi-signature schema where the user stores 1 of the keys (offline) as backup while using the other key for daily use and letting the service cosign his transactions.
+Many wallet as a service providers use a 2of3 multi-signature schema where the user stores 1 of the keys (offline) as backup while using the other key for daily use and letting the service cosign his transactions.
This standard will help in enabling a party other than the service provider to recover the wallet without any help from the service provider.
==Specification==
For a set of public keys, ensure that they have been received in compressed form:
-
+
022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da
- 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
+ 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18
-
-Sort them lexicographically according to their binary representation:
-
+
+Sort them lexicographically according to their binary representation:
+
021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18
022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da
03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
-..before using the resulting list of keys in a standard multisig redeem script:
-
+..before using the resulting list of keys in a standard multisig redeem script:
+
OP_2 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 OP_3 OP_CHECKMULTISIG
Hash the redeem script according to BIP-0016 to get the P2SH address.
-
+
3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba
-
+
==Compatibility==
-* Uncompressed keys are incompatible with this specificiation. A compatible implementation should not automatically compress keys. Receiving an uncompressed key from a multisig participant should be interpreted as a sign that the user has an incompatible implementation.
-* P2SH addressses do not reveal information about the script that is receiving the funds. For this reason it is not technically possible to enforce this BIP as a rule on the network. Also, it would cause a hard fork.
+* Uncompressed keys are incompatible with this specification. A compatible implementation should not automatically compress keys. Receiving an uncompressed key from a multisig participant should be interpreted as a sign that the user has an incompatible implementation.
+* P2SH addresses do not reveal information about the script that is receiving the funds. For this reason it is not technically possible to enforce this BIP as a rule on the network. Also, it would cause a hard fork.
* Implementations that do not conform with this BIP will have compatibility issues with strictly-compliant wallets.
-* Implementations which do adopt this standard will be cross-compatible when choosing multisig addressses.
+* Implementations which do adopt this standard will be cross-compatible when choosing multisig addresses.
* If a group of users were not entirely compliant, there is the possibility that a participant will derive an address that the others will not recognize as part of the common multisig account.
==Test vectors==
@@ -75,11 +75,11 @@ Vector 1
** 39bgKC7RFbpoCRbtD5KEdkYKtNyhpsNa3Z
Vector 2 (Already sorted, no action required)
-* List:
+* List:
** 02632b12f4ac5b1d1b72b2a3b508c19172de44f6f46bcee50ba33f3f9291e47ed0
** 027735a29bae7780a9755fae7a1c4374c656ac6a69ea9f3697fda61bb99a4f3e77
** 02e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290ad188d11b404
-* Sorted:
+* Sorted:
** 02632b12f4ac5b1d1b72b2a3b508c19172de44f6f46bcee50ba33f3f9291e47ed0
** 027735a29bae7780a9755fae7a1c4374c656ac6a69ea9f3697fda61bb99a4f3e77
** 02e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290ad188d11b404
@@ -89,12 +89,12 @@ Vector 2 (Already sorted, no action required)
** 3CKHTjBKxCARLzwABMu9yD85kvtm7WnMfH
Vector 3:
-* List:
+* List:
** 030000000000000000000000000000000000004141414141414141414141414141
** 020000000000000000000000000000000000004141414141414141414141414141
** 020000000000000000000000000000000000004141414141414141414141414140
** 030000000000000000000000000000000000004141414141414141414141414140
-* Sorted:
+* Sorted:
** 020000000000000000000000000000000000004141414141414141414141414140
** 020000000000000000000000000000000000004141414141414141414141414141
** 030000000000000000000000000000000000004141414141414141414141414140
@@ -105,11 +105,11 @@ Vector 3:
** 32V85igBri9zcfBRVupVvwK18NFtS37FuD
Vector 4: (from bitcore)
-* List:
+* List:
** 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da
-** 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
+** 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
** 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18
-* Sorted:
+* Sorted:
** 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18
** 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da
** 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
@@ -119,14 +119,14 @@ Vector 4: (from bitcore)
** 3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba
==Acknowledgements==
-The authors wish to thank BtcDrak and Luke-Jr for their involvement & contributions in the early discussions of this BIP.
-
-==Usage & Implementations==
-* [[https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki#address-generation-procedure|BIP-0045]] - Structure for Deterministic P2SH Multisignature Wallets
-* [[https://github.com/bitpay/bitcore/blob/50a868cb8cdf2be04bb1c5bf4bcc064cc06f5888/lib/script/script.js#L541|Bitcore]]
-* [[https://github.com/haskoin/haskoin/blob/master/Network/Haskoin/Script/Parser.hs#L112-122|Haskoin]] Bitcoin implementation in haskell
-* [[https://github.com/etotheipi/BitcoinArmory/blob/268db0f3fa20c989057bd43343a43b2edbe89aeb/armoryengine/ArmoryUtils.py#L1441|Armory]]
-* [[https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/script/ScriptBuilder.java#L331|BitcoinJ]]
+The authors wish to thank BtcDrak and Luke-Jr for their involvement & contributions in the early discussions of this BIP.
+
+==Usage & Implementations==
+* [[https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki#address-generation-procedure|BIP-0045]] - Structure for Deterministic P2SH Multisignature Wallets
+* [[https://github.com/bitpay/bitcore/blob/50a868cb8cdf2be04bb1c5bf4bcc064cc06f5888/lib/script/script.js#L541|Bitcore]]
+* [[https://github.com/haskoin/haskoin-core/blob/b41b1deb0989334a7ead6fc993fb8b02f0c00810/haskoin-core/Network/Haskoin/Script/Parser.hs#L112-L122|Haskoin]] - Bitcoin implementation in Haskell
+* [[https://github.com/etotheipi/BitcoinArmory/blob/268db0f3fa20c989057bd43343a43b2edbe89aeb/armoryengine/ArmoryUtils.py#L1441|Armory]]
+* [[https://github.com/bitcoinj/bitcoinj/blob/f7ea0b92a619800c143b0142dc70306da33119a9/core/src/main/java/org/bitcoinj/script/ScriptBuilder.java#L331|BitcoinJ]]
== References ==
diff --git a/bip-0068.mediawiki b/bip-0068.mediawiki
index ea0761d5b2..d66c3cc17b 100644
--- a/bip-0068.mediawiki
+++ b/bip-0068.mediawiki
@@ -21,7 +21,7 @@ This BIP introduces relative lock-time (RLT) consensus-enforced semantics of the
Bitcoin transactions have a sequence number field for each input. The original idea appears to have been that a transaction in the mempool would be replaced by using the same input with a higher sequence value. Although this was not properly implemented, it assumes miners would prefer higher sequence numbers even if the lower ones were more profitable to mine. However, a miner acting on profit motives alone would break that assumption completely. The change described by this BIP repurposes the sequence number for new use cases without breaking existing functionality. It also leaves room for future expansion and other use cases.
-The transaction nLockTime is used to prevent the mining of a transaction until a certain date. nSequence will be repurposed to prevent mining of a transaction until a certain age of the spent output in blocks or timespan. This, among other uses, allows bi-directional payment channels as used in [https://github.com/ElementsProject/lightning/raw/master/doc/deployable-lightning.pdf Hashed Timelock Contracts (HTLCs)] and [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Bidirectional_Payment_Channels BIP112].
+The transaction nLockTime is used to prevent the mining of a transaction until a certain date. nSequence will be repurposed to prevent mining of a transaction until a certain age of the spent output in blocks or timespan. This, among other uses, allows bi-directional payment channels as used in [https://github.com/ElementsProject/lightning/raw/master/doc/miscellaneous/deployable-lightning.pdf Hashed Timelock Contracts (HTLCs)] and [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Bidirectional_Payment_Channels BIP112].
==Specification==
@@ -33,7 +33,7 @@ If bit (1 << 31) of the sequence number is set, then no consensus meaning is app
If bit (1 << 31) of the sequence number is not set, then the sequence number is interpreted as an encoded relative lock-time.
-The sequence number encoding is interpreted as follows:
+The sequence number encoding is interpreted as follows:
Bit (1 << 22) determines if the relative lock-time is time-based or block based: If the bit is set, the relative lock-time specifies a timespan in units of 512 seconds granularity. The timespan starts from the median-time-past of the output’s previous block, and ends at the MTP of the previous block. If the bit is not set, the relative lock-time specifies a number of blocks.
@@ -65,7 +65,7 @@ enum {
/* Interpret sequence numbers as relative lock-time constraints. */
LOCKTIME_VERIFY_SEQUENCE = (1 << 0),
};
-
+
/* Setting nSequence to this value for every input in a transaction
* disables nLockTime. */
static const uint32_t SEQUENCE_FINAL = 0xffffffff;
@@ -203,7 +203,7 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags)
return error("%s: Missing input", __func__);
}
if (coins.nHeight == MEMPOOL_HEIGHT) {
- // Assume all mempool transaction confirm in the next block
+ // Assume all mempool transactions are confirmed in the next block
prevheights[txinIndex] = tip->nHeight + 1;
} else {
prevheights[txinIndex] = coins.nHeight;
@@ -245,7 +245,7 @@ The most efficient way to calculate sequence number from relative lock-time is w
// 0 <= nHeight < 65,535 blocks (1.25 years)
nSequence = nHeight;
nHeight = nSequence & 0x0000ffff;
-
+
// 0 <= nTime < 33,554,431 seconds (1.06 years)
nSequence = (1 << 22) | (nTime >> 9);
nTime = (nSequence & 0x0000ffff) << 9;
@@ -261,5 +261,5 @@ BIP112: https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki
BIP113: https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki
-Hashed Timelock Contracts (HTLCs): https://github.com/ElementsProject/lightning/raw/master/doc/deployable-lightning.pdf
+Hashed Timelock Contracts (HTLCs): https://github.com/ElementsProject/lightning/raw/master/doc/miscellaneous/deployable-lightning.pdf
diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index 3aa946341c..7b5034eb7f 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -147,7 +147,7 @@ Outputs:
==References==
* [[https://bitcoinmagazine.com/20273/bitstamp-exchange-activity-trackable-due-multisig-wallet-implementation/|1: Bitstamp Info Leak]]
-* [[https://github.com/OpenBitcoinPrivacyProject/wallet-ratings/blob/master/2015-1/criteria.md|2: OBPP Random Indexing as Countermeasure]]
+* [[https://github.com/OpenBitcoinPrivacyProject/wallet-ratings/blob/5a7e2e1555e91bb48edeca3aa710272777d98c2a/2015-1/criteria.md|2: OBPP Random Indexing as Countermeasure]]
* [[https://github.com/aantonop/bitcoinbook/blob/develop/ch05.asciidoc|3: Mastering Bitcoin]]
* [[https://en.bitcoin.it/wiki/Script|4: Bitcoin Wiki on Script]]
* [[http://www.cplusplus.com/reference/algorithm/lexicographical_compare|5: std::lexicographical_compare]]
diff --git a/bip-0069/bip-0069_examples.py b/bip-0069/bip-0069_examples.py
index e2f52eddb3..8fa1a4521e 100644
--- a/bip-0069/bip-0069_examples.py
+++ b/bip-0069/bip-0069_examples.py
@@ -29,7 +29,7 @@ def input_cmp(input_tuple1, input_tuple2):
elif (input_tuple1[1] > input_tuple2[1]):
return 1
else:
- raise ValueError('Matching previous transaction hash and previous transaction output index for two disinct inputs. Invalid!')
+ raise ValueError('Matching previous transaction hash and previous transaction output index for two distinct inputs. Invalid!')
def sort_inputs(input_tuples):
return sorted(input_tuples, cmp=input_cmp)
diff --git a/bip-0070.mediawiki b/bip-0070.mediawiki
index 28349ee300..fce60234cb 100644
--- a/bip-0070.mediawiki
+++ b/bip-0070.mediawiki
@@ -314,7 +314,7 @@ http://datatracker.ietf.org/wg/jose/
Wikipedia's page on Invoices: http://en.wikipedia.org/wiki/Invoice
especially the list of Electronic Invoice standards
-sipa's payment protocol proposal: https://gist.github.com/1237788
+sipa's payment protocol proposal: https://gist.github.com/sipa/1237788
ThomasV's "Signed Aliases" proposal : http://ecdsa.org/bitcoin_URIs.html
diff --git a/bip-0072.mediawiki b/bip-0072.mediawiki
index d5e295e189..ab9c32d098 100644
--- a/bip-0072.mediawiki
+++ b/bip-0072.mediawiki
@@ -69,4 +69,4 @@ bitcoin:?r=https://merchant.com/pay.php?h%3D2a8628fc2fbe
==References==
-[[http://www.w3.org/Protocols/rfc2616/rfc2616.html|RFC 2616]] : Hypertext Transfer Protocol -- HTTP/1.1
+[[http://www.w3.org/Protocols/rfc2616/rfc2616.html|RFC 2616]] : Hypertext Transfer Protocol -- HTTP/1.1
diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki
index 8c49645d19..6970ee927c 100644
--- a/bip-0075.mediawiki
+++ b/bip-0075.mediawiki
@@ -18,11 +18,11 @@
This BIP is an extension to BIP 70 that provides two enhancements to the existing Payment Protocol.
-# It allows the requester (Sender) of a PaymentRequest to voluntarily sign the original request and provide a certificate to allow the payee to know the identity of who they are transacting with.
+# It allows the requester (Sender) of a PaymentRequest to voluntarily sign the original request and provide a certificate to allow the payee to know the identity of who they are transacting with.
# It encrypts the PaymentRequest that is returned, before handing it off to the SSL/TLS layer to prevent man in the middle viewing of the Payment Request details.
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in RFC 2119.
==Copyright==
@@ -177,7 +177,7 @@ This BIP introduces version 1 of this protocol. All messages sent using these ba
When initiating communication, the version field of the first message SHOULD be set to the highest version number the sender understands. All clients MUST be able to understand all version numbers less than the highest number they support. If a client receives a message with a version number higher than they understand, they MUST send the message back to the sender with a status code of 101 ("version too high") and the version field set to the highest version number the recipient understands. The sender must then resend the original message using the same version number returned by the recipient or abort.
===EncryptedProtocolMessage===
-The '''EncryptedProtocolMessage''' message is an encapsualting wrapper for any Payment Protocol message. It allows two-way, authenticated and encrypted communication of Payment Protocol messages in order to keep their contents secret. The message also includes a status code and status message that is used for error communication such that the protocol does not rely on transport-layer error handling.
+The '''EncryptedProtocolMessage''' message is an encapsulating wrapper for any Payment Protocol message. It allows two-way, authenticated and encrypted communication of Payment Protocol messages in order to keep their contents secret. The message also includes a status code and status message that is used for error communication such that the protocol does not rely on transport-layer error handling.
message EncryptedProtocolMessage {
required uint64 version = 1 [default = 1];
@@ -217,9 +217,9 @@ message EncryptedProtocolMessage {
|}
==Payment Protocol Process with InvoiceRequests==
-The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below.
+The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below.
-All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProcotolMessage|EncryptedProtocolMessage]]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]].
+All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]].
All Payment Protocol messages SHOULD be communicated using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#InvoiceRequest|InvoiceRequest]] MAY be communicated using the [[#ProtocolMessage|ProtocolMessage]] if the receiver's public key is unknown.
@@ -257,14 +257,14 @@ When communicated via '''HTTP''', the listed messages MUST be transmitted via TL
===Payment Protocol Status Communication===
-Every [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST include a status code which conveys information about the last message received, if any (for the first message sent, use a status of 1 "OK" even though there was no previous message). In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a ProtocolMessage or EncryptedProtocolMessage SHOULD be returned by the party generating the error. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately.
+Every [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST include a status code which conveys information about the last message received, if any (for the first message sent, use a status of 1 "OK" even though there was no previous message). In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a ProtocolMessage or EncryptedProtocolMessage SHOULD be returned by the party generating the error. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately.
The status_message value SHOULD be set with a human readable explanation of the status code.
====Payment Protocol Status Codes====
{| class="wikitable"
! Status Code !! Description
-|-
+|-
| 1 || OK
|-
| 2 || Cancel
@@ -301,7 +301,7 @@ The status_message value SHOULD be set with a human readable explanation of the
If a participant to a transaction would like to inform the other party that a previous message should be canceled, they can send the same message with a status code of 2 ("Cancel") and, where applicable, an updated nonce. How recipients make use of the "Cancel" message is up to developers. For example, wallet developers may want to offer users the ability to cancel payment requests they have sent to other users, and have that change reflected in the recipient's UI. Developers using the non-encrypted ProtocolMessage may want to ignore "Cancel" messages, as it may be difficult to authenticate that the message originated from the same user.
===Transport Layer Communication Errors===
-Communication errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging faciltiies. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]).
+Communication errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging facilities. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]).
==Extended Payment Protocol Process Details==
This BIP extends the Payment Protocol as defined in [[bip-0070.mediawiki|BIP70]].
@@ -324,7 +324,7 @@ For the following we assume the Sender already knows the Receiver's public key,
** Set '''signature''' value to the computed signature
===InvoiceRequest Validation===
-* Validate '''sender_public_key''' is a valid EC public key
+* Validate '''sender_public_key''' is a valid EC public key
* Validate '''notification_url''', if set, contains characters deemed valid for a URL (avoiding XSS related characters, etc).
* If '''pki_type''' is None, [[#InvoiceRequest|InvoiceRequest]] is VALID
* If '''pki_type''' is x509+sha256 and '''signature''' is valid for the serialized [[#InvoiceRequest|InvoiceRequest]] where signature is set to "", [[#InvoiceRequest|InvoiceRequest]] is VALID
@@ -366,7 +366,7 @@ For the following we assume the Sender already knows the Receiver's public key,
The 16 byte authentication tag resulting from the AES-GCM encrypt operation MUST be prefixed to the returned ciphertext. The decrypt operation will use the first 16 bytes of the ciphertext as the GCM authentication tag and the remainder of the ciphertext as the ciphertext in the decrypt operation.
====AES-256 GCM Additional Authenticated Data====
-When either '''status_code''' OR '''status_message''' are present, the AES-256 GCM authenticated data used in both the encrypt and decrypt operations MUST be: STRING(status_code) || status_message. Otherwise, there is no additional authenticated data. This provides that, while not encrypted, the status_code and status_message are authenticated.
+When either '''status_code''' OR '''status_message''' are present, the AES-256 GCM authenticated data used in both the encrypt and decrypt operations MUST be: STRING(status_code) || status_message. Otherwise, there is no additional authenticated data. This provides that, while not encrypted, the status_code and status_message are authenticated.
===Initial Public Key Retrieval for InvoiceRequest Encryption===
Initial public key retrieval for [[#InvoiceRequest|InvoiceRequest]] encryption via [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulation can be done in a number of ways including, but not limited to, the following:
@@ -387,7 +387,7 @@ Clients SHOULD keep in mind Receivers can broadcast a transaction without return
==Public Key & Signature Encoding==
* All x.509 certificates included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded.
-* All EC public keys ('''sender_public_key''', '''receiver_public_key''') in any message defined in this BIP MUST be [[SECP256k1|http://www.secg.org/sec2-v2.pdf]] ECDSA Public Key ECPoints encoded using [[SEC 2.3.3 Encoding|http://www.secg.org/sec1-v2.pdf]]. Encoding MAY be compressed.
+* All EC public keys ('''sender_public_key''', '''receiver_public_key''') in any message defined in this BIP MUST be [[SECP256k1|http://www.secg.org/sec2-v2.pdf]] ECDSA Public Key ECPoints encoded using [[SEC 2.3.3 Encoding|http://www.secg.org/sec1-v2.pdf]]. Encoding MAY be compressed.
* All ECC signatures included in any message defined in this BIP MUST use the SHA-256 hashing algorithm and MUST be DER [ITU.X690.1994] encoded.
* All OpenPGP certificates must follow [[https://tools.ietf.org/html/rfc4880|RFC4880]], sections 5.5 and 12.1.
diff --git a/bip-0075/paymentrequest.proto b/bip-0075/paymentrequest.proto
index 5097abb7f2..21f1343ec8 100644
--- a/bip-0075/paymentrequest.proto
+++ b/bip-0075/paymentrequest.proto
@@ -2,8 +2,8 @@
// Simple Bitcoin Payment Protocol messages
//
// Use fields 1000+ for extensions;
-// to avoid conflicts, register extensions via pull-req at
-// https://github.com/bitcoin/bips/bip-0070/extensions.mediawiki
+// to avoid conflicts, register extensions via pull request to update
+// https://github.com/bitcoin/bips/blob/master/bip-0070/extensions.mediawiki
//
package payments;
diff --git a/bip-0078.mediawiki b/bip-0078.mediawiki
index 3c2fe2efa5..a865543a83 100644
--- a/bip-0078.mediawiki
+++ b/bip-0078.mediawiki
@@ -95,7 +95,7 @@ The payjoin proposal PSBT is sent in the HTTP response body, base64 serialized w
To ensure compatibility with web-wallets and browser-based-tools, all responses (including errors) must contain the HTTP header Access-Control-Allow-Origin: *.
-The sender must ensure that the url refers to a scheme or protocol using authenticated encryption, for example TLS with certificate validation, or a .onion link to a hidden service whose public key identifier has already been communicated via a TLS connection. Senders SHOULD NOT accept a url representing an unencrypted or unauthenticated connection.
+The sender must ensure that the URL refers to a scheme or protocol using authenticated encryption, for example TLS with certificate validation, or a .onion link to a hidden service whose public key identifier has already been communicated via a TLS connection. Senders SHOULD NOT accept a URL representing an unencrypted or unauthenticated connection.
The original PSBT MUST:
* Have all the witnessUTXO or nonWitnessUTXO information filled in.
@@ -106,14 +106,20 @@ The original PSBT MUST:
The original PSBT MAY:
* Have outputs unrelated to the payment for batching purpose.
+The original PSBT SHOULD NOT:
+* Include mixed input types until September 2024. Mixed inputs were previously completely disallowed so this gives some grace period for receivers to update.
+
The payjoin proposal MUST:
* Use all the inputs from the original PSBT.
-* Use all the outputs which do not belongs to the receiver from the original PSBT.
+* Use all the outputs which do not belong to the receiver from the original PSBT.
* Only finalize the inputs added by the receiver. (Referred later as additional inputs)
* Only fill the witnessUTXO or nonWitnessUTXO for the additional inputs.
The payjoin proposal MAY:
-* Add, remove or modify the outputs belonging to the receiver.
+* Add, or replace the outputs belonging to the receiver unless output substitution is disabled.
+
+The payjoin proposal SHOULD NOT:
+* Include mixed input types until September 2024. Mixed inputs were previously completely disallowed so this gives some grace period for senders to update.
The payjoin proposal MUST NOT:
* Shuffle the order of inputs or outputs, the additional outputs or additional inputs must be inserted at a random index.
@@ -125,6 +131,8 @@ This proposal is defining the following new [[bip-0021.mediawiki|BIP 21 URI]] pa
* pj=: Represents an http(s) endpoint which the sender can POST the original PSBT.
* pjos=0: Signal to the sender that they MUST disallow [[#output-substitution|payment output substitution]]. (See [[#unsecured-payjoin|Unsecured payjoin server]])
+Note: the amount parameter is *not* required.
+
===Optional parameters===
When the payjoin sender posts the original PSBT to the receiver, he can optionally specify the following HTTP query string parameters:
@@ -143,7 +151,7 @@ If the receiver does not support the version of the sender, they should send an
}
-* additionalfeeoutputindex=, if the sender is willing to pay for increased fee, this indicate output can have its value substracted to pay for it.
+* additionalfeeoutputindex=, if the sender is willing to pay for increased fee, this indicate output can have its value subtracted to pay for it.
If the additionalfeeoutputindex is out of bounds or pointing to the payment output meant for the receiver, the receiver should ignore the parameter. See [[#fee-output|fee output]] for more information.
@@ -187,10 +195,10 @@ The well-known error codes are:
|The receiver rejected the original PSBT.
|}
-The receiver is allowed to return implementation specific errors which may assist the sender to diagnose any issue.
+The receiver is allowed to return implementation-specific errors which may assist the sender to diagnose any issue.
However, it is important that error codes that are not well-known and that the message do not appear on the sender's software user interface.
-Such error codes or messages could be used maliciously to phish a non technical user.
+Such error codes or messages could be used maliciously to phish a non-technical user.
Instead those errors or messages can only appear in debug logs.
It is advised to hard code the description of the well known error codes into the sender's software.
@@ -198,9 +206,9 @@ It is advised to hard code the description of the well known error codes into th
===Fee output===
In some situation, the sender might want to pay some additional fee in the payjoin proposal.
-If such is the case, the sender must use both [[#optional-params|optional parameters]] additionalfeeoutputindex= and maxadditionalfeecontribution= to indicate which output and how much the receiver can substract fee.
+If such is the case, the sender must use both [[#optional-params|optional parameters]] additionalfeeoutputindex= and maxadditionalfeecontribution= to indicate which output and how much the receiver can subtract fee.
-There is several cases where a fee output is useful:
+There are several cases where a fee output is useful:
* The sender's original transaction's fee rate is at the minimum accepted by the network, aka minimum relay transaction fee rate, which is typically 1 satoshi per vbyte.
@@ -213,25 +221,9 @@ To prevent this, the sender can agree to pay more fee so the receiver make sure
* The sender's transaction is time sensitive.
-When a sender pick a specific fee rate, the sender expects the transaction to be confirmed after a specific amount of time. But if the receiver adds an input without bumping the fee of the transaction, the payjoin transaction fee rate will be lower, and thus, longer to confirm.
-
-Our recommendation for maxadditionalfeecontribution= is originalPSBTFeeRate * vsize(sender_input_type).
-
-{| class="wikitable"
-!sender_input_type
-!vsize(sender_input_type)
-|-
-|P2WPKH
-|68
-|-
-|P2PKH
-|148
-|-
-|P2SH-P2WPKH
-|91
-|}
-
+When a sender picks a specific fee rate, the sender expects the transaction to be confirmed after a specific amount of time. But if the receiver adds an input without bumping the fee of the transaction, the payjoin transaction fee rate will be lower, and thus, longer to confirm.
+Our recommendation for maxadditionalfeecontribution= is originalPSBTFeeRate * 110.
===Receiver's original PSBT checklist===
@@ -239,10 +231,9 @@ The receiver needs to do some check on the original PSBT before proceeding:
* Non-interactive receivers (like a payment processor) need to check that the original PSBT is broadcastable. *
* If the sender included inputs in the original PSBT owned by the receiver, the receiver must either return error original-psbt-rejected or make sure they do not sign those inputs in the payjoin proposal.
-* If the sender's inputs are all from the same scriptPubKey type, the receiver must match the same type. If the receiver can't match the type, they must return error unavailable.
* Make sure that the inputs included in the original transaction have never been seen before.
-** This prevent [[#probing-attack|probing attacks]].
-** This prevent reentrant payjoin, where a sender attempts to use payjoin transaction as a new original transaction for a new payjoin.
+** This prevents [[#probing-attack|probing attacks]].
+** This prevents reentrant payjoin, where a sender attempts to use payjoin transaction as a new original transaction for a new payjoin.
*: Interactive receivers are not required to validate the original PSBT because they are not exposed to [[#probing-attack|probing attacks]].
@@ -254,26 +245,24 @@ The sender should check the payjoin proposal before signing it to prevent a mali
* If the receiver's BIP21 signalled pjos=0, disable payment output substitution.
* Verify that the transaction version, and the nLockTime are unchanged.
* Check that the sender's inputs' sequence numbers are unchanged.
-* For each inputs in the proposal:
-** Verify that no keypaths is in the PSBT input
+* For each input in the proposal:
+** Verify that no keypaths are in the PSBT input
** Verify that no partial signature has been filled
-** If it is one of the sender's input
+** If it is one of the sender's inputs:
*** Verify that input's sequence is unchanged.
*** Verify the PSBT input is not finalized
-*** Verify that non_witness_utxo and witness_utxo are not specified.
-** If it is one of the receiver's input
+** If it is one of the receiver's inputs:
*** Verify the PSBT input is finalized
*** Verify that non_witness_utxo or witness_utxo are filled in.
-** Verify that the payjoin proposal did not introduced mixed input's sequence.
-** Verify that the payjoin proposal did not introduced mixed input's type.
+** Verify that the payjoin proposal inputs all specify the same sequence value.
** Verify that all of sender's inputs from the original PSBT are in the proposal.
-* For each outputs in the proposal:
-** Verify that no keypaths is in the PSBT output
+* For each output in the proposal:
+** Verify that no keypaths are in the PSBT output
** If the output is the [[#fee-output|fee output]]:
-*** The amount that was substracted from the output's value is less than or equal to maxadditionalfeecontribution. Let's call this amount actual contribution.
-*** Make sure the actual contribution is only paying fee: The actual contribution is less than or equals to the difference of absolute fee between the payjoin proposal and the original PSBT.
-*** Make sure the actual contribution is only paying for fee incurred by additional inputs: actual contribution is less than or equals to originalPSBTFeeRate * vsize(sender_input_type) * (count(payjoin_proposal_inputs) - count(original_psbt_inputs)). (see [[#fee-output|Fee output]] section)
-** If the output is the payment output and payment output substitution is allowed.
+*** The amount that was subtracted from the output's value is less than or equal to maxadditionalfeecontribution. Let's call this amount actual contribution.
+*** Make sure the actual contribution is only going towards fees: The actual contribution is less than or equals to the difference of absolute fee between the payjoin proposal and the original PSBT.
+*** Make sure the actual contribution is only paying for fees incurred by additional inputs: actual contribution is less than or equal to originalPSBTFeeRate * vsize(sender_input_type) * (count(payjoin_proposal_inputs) - count(original_psbt_inputs)). (see [[#fee-output|Fee output]] section)
+** If the output is the payment output and payment output substitution is allowed,
*** Do not make any check
** Else
*** Make sure the output's value did not decrease.
@@ -284,15 +273,15 @@ The sender must be careful to only sign the inputs that were present in the orig
Note:
* The sender must allow the receiver to add/remove or modify the receiver's own outputs. (if payment output substitution is disabled, the receiver's outputs must not be removed or decreased in value)
-* The sender should allow the receiver to not add any inputs. This is useful for the receiver to change the paymout output scriptPubKey type.
-* If no input have been added, the sender's wallet implementation should accept the payjoin proposal, but not mark the transaction as an actual payjoin in the user interface.
+* The sender should allow the receiver to not add any inputs. This is useful for the receiver to change the payment output scriptPubKey type.
+* If the receiver added no inputs, the sender's wallet implementation should accept the payjoin proposal, but not mark the transaction as an actual payjoin in the user interface.
Our method of checking the fee allows the receiver and the sender to batch payments in the payjoin transaction.
It also allows the receiver to pay the fee for batching adding his own outputs.
==Rationale==
-There is several consequences of our proposal:
+There are several consequences of our proposal:
* The receiver can bump the fee of the original transaction.
* The receiver can modify the outputs of the original PSBT.
@@ -341,8 +330,8 @@ On top of this the receiver can poison analysis by randomly faking a round amoun
===Payment output substitution===
-Unless disallowed by sender explicitely via `disableoutputsubstitution=true` or by the BIP21 url via query parameter the `pjos=0`, the receiver is free to decrease the amount, remove, or change the scriptPubKey output paying to himself.
-Note that if payment output substitution is disallowed, the reveiver can still increase the amount of the output. (See [[#reference-impl|the reference implementation]])
+Unless disallowed by the sender explicitly via disableoutputsubstitution=true or by the BIP21 URL via the query parameter pjos=0, the receiver is free to decrease the amount or change the scriptPubKey output paying to himself.
+Note that if payment output substitution is disallowed, the receiver can still increase the amount of the output. (See [[#reference-impl|the reference implementation]])
For example, if the sender's scriptPubKey type is P2WPKH while the receiver's payment output in the original PSBT is P2SH, then the receiver can substitute the payment output to be P2WPKH to match the sender's scriptPubKey type.
@@ -355,7 +344,7 @@ A compromised payjoin server could steal the hot wallet outputs of the receiver,
===Impacted heuristics===
-Our proposal of payjoin is breaking the following blockchain heuristics:
+Our proposal of payjoin breaks the following blockchain heuristics:
* Common inputs heuristics.
@@ -405,12 +394,12 @@ With payjoin, the maximum amount of money that can be lost is equal to two payme
==Reference sender's implementation==
Here is pseudo code of a sender implementation.
-RequestPayjoin takes the bip21 URI of the payment, the wallet and the signedPSBT.
+RequestPayjoin takes the BIP21 URI of the payment, the wallet and the signedPSBT.
The signedPSBT represents a PSBT which has been fully signed, but not yet finalized.
We then prepare originalPSBT from the signedPSBT via the CreateOriginalPSBT function and get back the proposal.
-While we verify the proposal, we also import into it informations about our own inputs and outputs from the signedPSBT.
+While we verify the proposal, we also import into it information about our own inputs and outputs from the signedPSBT.
At the end of this RequestPayjoin, the proposal is verified and ready to be signed.
We logged the different PSBT involved, and show the result in our [[#test-vectors|test vectors]].
@@ -426,7 +415,6 @@ public async Task RequestPayjoin(
var endpoint = bip21.ExtractPayjointEndpoint();
if (signedPSBT.IsAllFinalized())
throw new InvalidOperationException("The original PSBT should not be finalized.");
- ScriptPubKeyType inputScriptType = wallet.ScriptPubKeyType();
PSBTOutput feePSBTOutput = null;
bool allowOutputSubstitution = !optionalParameters.DisableOutputSubstitution;
@@ -494,9 +482,6 @@ public async Task RequestPayjoin(
// Verify the PSBT input is not finalized
if (proposedPSBTInput.IsFinalized())
throw new PayjoinSenderException("The receiver finalized one of our inputs");
- // Verify that non_witness_utxo and witness_utxo are not specified.
- if (proposedPSBTInput.NonWitnessUtxo != null || proposedPSBTInput.WitnessUtxo != null)
- throw new PayjoinSenderException("The receiver added non_witness_utxo or witness_utxo to one of our inputs");
sequences.Add(proposedTxIn.Sequence);
// Fill up the info from the original PSBT input so we can sign and get fees.
@@ -517,9 +502,6 @@ public async Task RequestPayjoin(
if (proposedPSBTInput.NonWitnessUtxo == null && proposedPSBTInput.WitnessUtxo == null)
throw new PayjoinSenderException("The receiver did not specify non_witness_utxo or witness_utxo for one of their inputs");
sequences.Add(proposedTxIn.Sequence);
- // Verify that the payjoin proposal did not introduced mixed inputs' type.
- if (inputScriptType != proposedPSBTInput.GetInputScriptPubKeyType())
- throw new PayjoinSenderException("Mixed input type detected in the proposal");
}
}
@@ -541,22 +523,29 @@ public async Task RequestPayjoin(
// Verify that no keypaths is in the PSBT output
if (proposedPSBTOutput.HDKeyPaths.Count != 0)
throw new PayjoinSenderException("The receiver added keypaths to an output");
- bool isOriginalOutput = originalOutputs.Count > 0 && originalOutputs.Peek().OriginalTxOut.ScriptPubKey == proposedPSBTOutput.ScriptPubKey;
- if (isOriginalOutput)
+ if (originalOutputs.Count == 0)
+ continue;
+ var originalOutput = originalOutputs.Peek();
+ bool isOriginalOutput = originalOutput.OriginalTxOut.ScriptPubKey == proposedPSBTOutput.ScriptPubKey;
+ bool substitutedOutput = !isOriginalOutput &&
+ allowOutputSubstitution &&
+ originalOutput.OriginalTxOut.ScriptPubKey == paymentScriptPubKey;
+ if (isOriginalOutput || substitutedOutput)
{
- var originalOutput = originalOutputs.Dequeue();
- if (output.OriginalTxOut == feeOutput)
+ originalOutputs.Dequeue();
+ if (originalOutput.OriginalTxOut == feeOutput)
{
var actualContribution = feeOutput.Value - proposedPSBTOutput.Value;
- // The amount that was substracted from the output's value is less than or equal to maxadditionalfeecontribution
+ // The amount that was subtracted from the output's value is less than or equal to maxadditionalfeecontribution
if (actualContribution > optionalParameters.MaxAdditionalFeeContribution)
throw new PayjoinSenderException("The actual contribution is more than maxadditionalfeecontribution");
// Make sure the actual contribution is only paying fee
if (actualContribution > additionalFee)
throw new PayjoinSenderException("The actual contribution is not only paying fee");
// Make sure the actual contribution is only paying for fee incurred by additional inputs
+ // This assumes an additional input can be up to 110 bytes.
int additionalInputsCount = proposalGlobalTx.Inputs.Count - originalGlobalTx.Inputs.Count;
- if (actualContribution > originalFeeRate * GetVirtualSize(inputScriptType) * additionalInputsCount)
+ if (actualContribution > originalFeeRate * 110 * additionalInputsCount)
throw new PayjoinSenderException("The actual contribution is not only paying for additional inputs");
}
else if (allowOutputSubstitution && output.OriginalTxOut.ScriptPubKey == paymentScriptPubKey)
@@ -591,21 +580,6 @@ public async Task RequestPayjoin(
return proposal;
}
-int GetVirtualSize(ScriptPubKeyType? scriptPubKeyType)
-{
- switch (scriptPubKeyType)
- {
- case ScriptPubKeyType.Legacy:
- return 148;
- case ScriptPubKeyType.Segwit:
- return 68;
- case ScriptPubKeyType.SegwitP2SH:
- return 91;
- default:
- return 110;
- }
-}
-
// Finalize the signedPSBT and remove confidential information
PSBT CreateOriginalPSBT(PSBT signedPSBT)
{
@@ -633,11 +607,11 @@ A successful exchange with:
{| class="wikitable"
!InputScriptType
-!Orginal PSBT Fee rate
+!Original PSBT Fee rate
!maxadditionalfeecontribution
!additionalfeeoutputindex
|-
-|P2SH-P2WSH
+|P2SH-P2WPKH
|2 sat/vbyte
|0.00000182
|0
@@ -650,7 +624,7 @@ A successful exchange with:
@@ -665,7 +639,7 @@ A successful exchange with:
==Backward compatibility==
-The receivers are advertising payjoin capabilities through [[bip-0021.mediawiki|BIP21's URI Scheme]].
+The receivers advertise payjoin capabilities through [[bip-0021.mediawiki|BIP21's URI Scheme]].
Senders not supporting payjoin will just ignore the pj variable and thus, will proceed to normal payment.
diff --git a/bip-0079.mediawiki b/bip-0079.mediawiki
index 797c8f145a..905853aa3b 100644
--- a/bip-0079.mediawiki
+++ b/bip-0079.mediawiki
@@ -74,7 +74,7 @@ Should the receiver reject a transaction, it should not attempt to propagate it
The receiver must add at least one input to the transaction (the "contributed inputs"). If the receiver has no inputs, it should use a 500 internal server error, so the client can send the transaction as per normal (or try again later). Its generally advised to only add a single contributed input, however they are circumstances where adding more than a single input can be useful.
-To prevent an attack where a receiver is continually sent variations of the same transaction to enumerate the receivers utxo set, it is essential that the receiver always returns the same contributed inputs when it's seen the same inputs.
+To prevent an attack where a receiver is continually sent variations of the same transaction to enumerate the receiver's utxo set, it is essential that the receiver always returns the same contributed inputs when it's seen the same inputs.
It is strongly preferable that the receiver makes an effort to pick a contributed input of the same type as the other transaction inputs if possible.
@@ -84,7 +84,7 @@ After adding inputs to the transaction, the receiver generally will want to adju
=== Returning the partial transaction ===
-The receiver must sign all contributed inputs in the partial transaction. The partial transaction should also remove all witnesses from the the original template transaction as they are no longer valid, and need to be recalculated by the sender. The receiver returns the partial transaction as a binary-encoded HTTP response with a status code of 200. To ensure compatibility with web-wallets and browser-based-tools, all responses (including errors) must contain the HTTP header "Access-Control-Allow-Origin: *"
+The receiver must sign all contributed inputs in the partial transaction. The partial transaction should also remove all witnesses from the original template transaction as they are no longer valid, and need to be recalculated by the sender. The receiver returns the partial transaction as a binary-encoded HTTP response with a status code of 200. To ensure compatibility with web-wallets and browser-based-tools, all responses (including errors) must contain the HTTP header "Access-Control-Allow-Origin: *"
=== Sender Validation ===
@@ -97,7 +97,7 @@ The sender *must* do important validation on the partial transaction. They *must
=== Creating Final Transaction ===
-After validating the partial transaction, the sender signs all its inputs to create what is now the final transaction. It is important that the sender is careful to not be tricked by the receiver into signing other inputs it owns. The sender must only sign inputs that existed in the template transaction. If the sender is not careful the receiver may "contribute" inputs that are actually owned with by the sender, with the hope the sender blindly signs everything.
+After validating the partial transaction, the sender signs all its inputs to create what is now the final transaction. It is important that the sender is careful to not be tricked by the receiver into signing other inputs it owns. The sender must only sign inputs that existed in the template transaction. If the sender is not careful the receiver may "contribute" inputs that are actually owned by the sender, with the hope the sender blindly signs everything.
=== Transaction Publishing ===
diff --git a/bip-0080.mediawiki b/bip-0080.mediawiki
index 0cade1994b..f367c71a70 100644
--- a/bip-0080.mediawiki
+++ b/bip-0080.mediawiki
@@ -35,7 +35,7 @@ Each level has a special meaning, described in the chapters below.
===Purpose===
-Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "80" with the most signifigant bit set to indicate hardened derivation (0x80000050). It indicates that the subtree of this node is used according to this specification.
+Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "80" with the most significant bit set to indicate hardened derivation (0x80000050). It indicates that the subtree of this node is used according to this specification.
Hardened derivation is used at this level.
diff --git a/bip-0081.mediawiki b/bip-0081.mediawiki
index 96ac8d1bb0..923917c550 100644
--- a/bip-0081.mediawiki
+++ b/bip-0081.mediawiki
@@ -35,7 +35,7 @@ Each level has a special meaning, described in the chapters below.
===Purpose===
-Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "81" with the most signifigant bit set to indicate hardened derivation (0x80000051). It indicates that the subtree of this node is used according to this specification.
+Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "81" with the most significant bit set to indicate hardened derivation (0x80000051). It indicates that the subtree of this node is used according to this specification.
Hardened derivation is used at this level.
diff --git a/bip-0083.mediawiki b/bip-0083.mediawiki
index d7bbe8ea82..8c6f4443f7 100644
--- a/bip-0083.mediawiki
+++ b/bip-0083.mediawiki
@@ -53,7 +53,7 @@ p //' n instead of p / 0' / n
Rather than specifying upfront which path is to be used for a specific purpose (i.e. external invoicing vs. internal change), different applications can specify arbitrary parent nodes and derivation paths. This allows for nesting of sublevels to arbitrary depth with application-specified semantics. Rather than trying to specify use cases upfront, we leave the design completely open-ended. Different applications can exchange these mappings for interoperability. Eventually, if certain mappings become popular, application user interfaces can provide convenient shortcuts or use them as defaults.
-Note that BIP32 suggests reserving child 0 for the derivation of signing keys rather than sublevels. It is not really necessary to reserve signing key parents, however, as each key's parent's path can be explicitly stated. But unless we reserve a child for sublevel derivation, we lose the ability to nest deeper levels into the hierarchy. While we could reserve any arbitrary index for nesting sublevels, reserving child 0 seems simplest to implement, leaving all indices > 0 for contiguously indexed signing keys. We could also use MAX_INDEX (231 - 1) for this purpose. However, we believe doing so introduces more ideosyncracies into the semantics and will present a problem if we ever decide to extend the scheme to use indices larger than 31 bits.
+Note that BIP32 suggests reserving child 0 for the derivation of signing keys rather than sublevels. It is not really necessary to reserve signing key parents, however, as each key's parent's path can be explicitly stated. But unless we reserve a child for sublevel derivation, we lose the ability to nest deeper levels into the hierarchy. While we could reserve any arbitrary index for nesting sublevels, reserving child 0 seems simplest to implement, leaving all indices > 0 for contiguously indexed signing keys. We could also use MAX_INDEX (231 - 1) for this purpose. However, we believe doing so introduces more idiosyncrasies into the semantics and will present a problem if we ever decide to extend the scheme to use indices larger than 31 bits.
==Use Cases==
@@ -83,7 +83,7 @@ We can continue creating subaccounts indefinitely using this scheme.
In order to create a bidirectional payment channel, it is necessary that previous commitments be revokable. In order to revoke previous commitments, each party reveals a secret to the other that would allow them to steal the funds in the channel if a transaction for a previous commitment is inserted into the blockchain.
-By allowing for arbitrary nesting of sublevels, we can construct decision trees of arbitrary depth and revoke an entire branch by revealing a parent node used to derive all the children.
+By allowing for arbitrary nesting of sublevels, we can construct decision trees of arbitrary depth and revoke an entire branch by revealing a parent node used to derive all the children.
==References==
diff --git a/bip-0084.mediawiki b/bip-0084.mediawiki
index dc5a05d93d..93fe64bb82 100644
--- a/bip-0084.mediawiki
+++ b/bip-0084.mediawiki
@@ -5,8 +5,8 @@
Author: Pavol Rusnak
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0084
- Status: Draft
- Type: Informational
+ Status: Final
+ Type: Standards Track
Created: 2017-12-28
License: CC0-1.0
@@ -61,7 +61,7 @@ Additional registered version bytes are listed in [[https://github.com/satoshila
==Backwards Compatibility==
-This BIP is not backwards compatible by design as described under [#considerations]. An incompatible wallet will not discover accounts at all and the user will notice that something is wrong.
+This BIP is not backwards compatible by design as described under [[#considerations|considerations]]. An incompatible wallet will not discover accounts at all and the user will notice that something is wrong.
==Test vectors==
diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki
index 6e7dd0e95e..b88d3730b4 100644
--- a/bip-0085.mediawiki
+++ b/bip-0085.mediawiki
@@ -3,9 +3,10 @@
Layer: Applications
Title: Deterministic Entropy From BIP32 Keychains
Author: Ethan Kosakovsky
+ Aneesh Karve
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0085
- Status: Draft
+ Status: Final
Type: Informational
Created: 2020-03-20
License: BSD-2-Clause
@@ -14,15 +15,19 @@
==Abstract==
-''"One Seed to rule them all,''
-''One Key to find them,''
-''One Path to bring them all,''
+''"One Seed to rule them all,''
+''One Key to find them,''
+''One Path to bring them all,''
''And in cryptography bind them."''
It is not possible to maintain one single (mnemonic) seed backup for all keychains used across various wallets because there are a variety of incompatible standards. Sharing of seeds across multiple wallets is not desirable for security reasons. Physical storage of multiple seeds is difficult depending on the security and redundancy required.
As HD keychains are essentially derived from initial entropy, this proposal provides a way to derive entropy from the keychain which can be fed into whatever method a wallet uses to derive the initial mnemonic seed or root key.
+==Copyright==
+
+This BIP is dual-licensed under the Open Publication License and BSD 2-clause license.
+
==Definitions==
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
@@ -33,13 +38,16 @@ The terminology related to keychains used in the wild varies widely, for example
# '''BIP39 mnemonic''' is the mnemonic phrase that is calculated from the entropy used before hashing of the mnemonic in BIP39.
# '''BIP39 seed''' is the result of hashing the BIP39 mnemonic seed.
+When in doubt, assume big endian byte serialization, such that the leftmost
+byte is the most significant.
+
==Motivation==
-Most wallets implement BIP32 which defines how a BIP32 root key can be used to derive keychains. As a consequence, a backup of just the BIP32 root key is sufficient to include all keys derived from it. BIP32 does not have a human friendly serialization of the BIP32 root key (or BIP32 extended keys in general) which makes paper backups or manually restoring the key more error-prone. BIP39 was designed to solve this problem but rather than serialize the BIP32 root key, it takes some entropy, encoded to a "seed mnemonic", which is then hashed to derive the BIP39 seed which can be turned into the BIP32 root key. Saving the BIP39 mnemonic is enough to reconstruct the entire BIP32 keychain, but a BIP32 root key cannot be reversed back to the BIP39 mnemonic.
+Most wallets implement BIP32 which defines how a BIP32 root key can be used to derive keychains. As a consequence, a backup of just the BIP32 root key is sufficient to include all keys derived from it. BIP32 does not have a human-friendly serialization of the BIP32 root key (or BIP32 extended keys in general), which makes paper backups or manually restoring the key more error-prone. BIP39 was designed to solve this problem, but rather than serialize the BIP32 root key, it takes some entropy, encoded to a "seed mnemonic", which is then hashed to derive the BIP39 seed, which can be turned into the BIP32 root key. Saving the BIP39 mnemonic is enough to reconstruct the entire BIP32 keychain, but a BIP32 root key cannot be reversed back to the BIP39 mnemonic.
-Most wallets implement BIP39, so on initialization or restoration, the user must interact with a BIP39 mnemonic. Most wallets do not support BIP32 extended private keys, so each wallet must either share the same BIP39 mnemonic, or have a separate BIP39 mnemonic entirely. Neither scenarios are particularly satisfactory for security reasons. For example, some wallets may be inherently less secure like hot wallets on smartphones, Join Market servers, or Lightning Network nodes. Having multiple seeds is far from desirable, especially for those who rely on split key or redundancy backups in different geological locations. Adding is necessarily difficult and may result in users being more lazy with subsequent keys, resulting in compromised security or loss of keys.
+Most wallets implement BIP39, so on initialization or restoration, the user must interact with a BIP39 mnemonic. Most wallets do not support BIP32 extended private keys, so each wallet must either share the same BIP39 mnemonic, or have a separate BIP39 mnemonic entirely. Neither scenario is particularly satisfactory for security reasons. For example, some wallets may be inherently less secure, like hot wallets on smartphones, JoinMarket servers, or Lightning Network nodes. Having multiple seeds is far from desirable, especially for those who rely on split key or redundancy backups in different geological locations. Adding keys is necessarily difficult and may result in users being more lazy with subsequent keys, resulting in compromised security or loss of keys.
-There is added complication with wallets that implement other standards, or no standards at all. Bitcoin Core wallet uses a WIF as the ''hdseed'', and yet other wallets like Electrum use different mnemonic schemes to derive the BIP32 root key. Other cryptocurrencies like Monero also use an entirely different mnemonic scheme.
+There is an added complication with wallets that implement other standards, or no standards at all. The Bitcoin Core wallet uses a WIF as the ''hdseed'', and yet other wallets, like Electrum, use different mnemonic schemes to derive the BIP32 root key. Other cryptocurrencies, like Monero, use an entirely different mnemonic scheme.
Ultimately, all of the mnemonic/seed schemes start with some "initial entropy" to derive a mnemonic/seed, and then process the mnemonic into a BIP32 key, or private key. We can use BIP32 itself to derive the "initial entropy" to then recreate the same mnemonic or seed according to the specific application standard of the target wallet. We can use a BIP44-like categorization to ensure uniform derivation according to the target application type.
@@ -47,9 +55,13 @@ Ultimately, all of the mnemonic/seed schemes start with some "initial entropy" t
We assume a single BIP32 master root key. This specification is not concerned with how this was derived (e.g. directly or via a mnemonic scheme such as BIP39).
-For each application that requires its own wallet, a unique private key is derived from the BIP32 master root key using a fully hardened derivation path. The resulting private key (k) is then processed with HMAC-SHA512, where the key is "bip-entropy-from-k", and the message payload is the private key k: HMAC-SHA512(key="bip-entropy-from-k", msg=k). The result produces 512 bits of entropy. Each application SHOULD use up to the required number of bits necessary for their operation truncating the rest.
+For each application that requires its own wallet, a unique private key is derived from the BIP32 master root key using a fully hardened derivation path. The resulting private key (k) is then processed with HMAC-SHA512, where the key is "bip-entropy-from-k", and the message payload is the private key k: HMAC-SHA512(key="bip-entropy-from-k", msg=k)
+
+The reason for running the derived key through HMAC-SHA512 and truncating the result as necessary is to prevent leakage of the parent tree should the derived key (''k'') be compromised. While the specification requires the use of hardened key derivation which would prevent this, we cannot enforce hardened derivation, so this method ensures the derived entropy is hardened. Also, from a semantic point of view, since the purpose is to derive entropy and not a private key, we are required to transform the child key. This is done out of an abundance of caution, in order to ward off unwanted side effects should ''k'' be used for a dual purpose, including as a nonce ''hash(k)'', where undesirable and unforeseen interactions could occur.
+.
+The result produces 512 bits of entropy. Each application SHOULD use up to the required number of bits necessary for their operation, and truncate the rest.
-The HMAC-SHA512 function is specified in [http://tools.ietf.org/html/rfc4231 RFC 4231].
+The HMAC-SHA512 function is specified in [https://tools.ietf.org/html/rfc4231 RFC 4231].
===Test vectors===
@@ -78,7 +90,7 @@ BIP85-DRNG-SHAKE256 is a deterministic random number generator for cryptographic
RSA key generation is an example of a function that requires orders of magnitude more than 64 bytes of random input. Further, it is not possible to precalculate the amount of random input required until the function has completed.
drng_reader = BIP85DRNG.new(bip85_entropy)
- rsa_key = RSA.generate_key(4096, drng_reader.read())
+ rsa_key = RSA.generate_key(4096, drng_reader.read)
===Test Vectors===
INPUT:
@@ -91,28 +103,13 @@ OUTPUT
* DRNG(80 bytes)=b78b1ee6b345eae6836c2d53d33c64cdaf9a696487be81b03e822dc84b3f1cd883d7559e53d175f243e4c349e822a957bbff9224bc5dde9492ef54e8a439f6bc8c7355b87a925a37ee405a7502991111
-==Reference Implementation==
-
-* Python library implementation: [https://github.com/ethankosakovsky/bip85]
-* JavaScript library implementation: [https://github.com/hoganri/bip85-js]
-
-===Other Implementations===
-
-* JavaScript library implementation: [https://github.com/hoganri/bip85-js]
-
-* Coldcard Firmware: [https://github.com/Coldcard/firmware/pull/39]
-
-* Ian Coleman's Mnemonic Code Converter: [https://github.com/iancoleman/bip39] and [https://iancoleman.io/bip39/]
-
-* AirGap Vault: [https://github.com/airgap-it/airgap-vault/commit/d64332fc2f332be622a1229acb27f621e23774d6]
-
-btc_hd_wallet: [https://github.com/scgbckbone/btc-hd-wallet]
-
==Applications==
The Application number defines how entropy will be used post processing. Some basic examples follow:
-Derivation path uses the format m/83696968'/{app_no}'/{index}' where ''{app_no}'' is the path for the application, and ''{index}'' is the index.
+Derivation paths follow the format m/83696968'/{app_no}'/{index}', where ''{app_no}'' is the path for the application, and ''{index}'' is the index.
+
+Application numbers should be semantic in some way, such as a BIP number or ASCII character code sequence.
===BIP39===
Application number: 39'
@@ -155,6 +152,10 @@ Language Table
|-
| Czech
| 8'
+|-
+| Portuguese
+| 9'
+|-
|}
Words Table
@@ -168,10 +169,18 @@ Words Table
| 128 bits
| 12'
|-
+| 15 words
+| 160 bits
+| 15'
+|-
| 18 words
| 192 bits
| 18'
|-
+| 21 words
+| 224 bits
+| 21'
+|-
| 24 words
| 256 bits
| 24'
@@ -219,7 +228,16 @@ OUTPUT:
===HD-Seed WIF===
Application number: 2'
-Uses 256 bits[1] of entropy as the secret exponent to derive a private key and encode as a compressed WIF which will be used as the hdseed for Bitcoin Core wallets.
+Uses the most significant 256 bits
+There is a very small chance that you'll make an invalid
+key that is zero or larger than the order of the curve. If this occurs, software
+should hard fail (forcing users to iterate to the next index). From BIP32:
+
+In case parse256(IL) ≥ n or ki = 0, the resulting key is invalid, and one should proceed with the next value for i. (Note: this has probability lower than 1 in 2127.)
+
+
+of entropy as the secret exponent to derive a private key and encode as a compressed
+WIF that will be used as the hdseed for Bitcoin Core wallets.
Path format is m/83696968'/2'/{index}'
@@ -234,7 +252,11 @@ OUTPUT
===XPRV===
Application number: 32'
-Taking 64 bytes of the HMAC digest, the first 32 bytes are the chain code, and second 32 bytes[1] are the private key for BIP32 XPRV value. Child number, depth, and parent fingerprint are forced to zero.
+Taking 64 bytes of the HMAC digest, the first 32 bytes are the chain code, and the second 32 bytes are the private key for the BIP32 XPRV value. Child number, depth, and parent fingerprint are forced to zero.
+
+''Warning'': The above order reverses the order of BIP32, which takes the first 32 bytes as the private key, and the second 32 bytes as the chain code.
+
+Applications may support Testnet by emitting TPRV keys if and only if the input root key is a Testnet key.
Path format is m/83696968'/32'/{index}'
@@ -244,7 +266,7 @@ INPUT:
OUTPUT
* DERIVED ENTROPY=ead0b33988a616cf6a497f1c169d9e92562604e38305ccd3fc96f2252c177682
-* DERIVED WIF=xprv9s21ZrQH143K2srSbCSg4m4kLvPMzcWydgmKEnMmoZUurYuBuYG46c6P71UGXMzmriLzCCBvKQWBUv3vPB3m1SATMhp3uEjXHJ42jFg7myX
+* DERIVED XPRV=xprv9s21ZrQH143K2srSbCSg4m4kLvPMzcWydgmKEnMmoZUurYuBuYG46c6P71UGXMzmriLzCCBvKQWBUv3vPB3m1SATMhp3uEjXHJ42jFg7myX
===HEX===
Application number: 128169'
@@ -262,6 +284,82 @@ INPUT:
OUTPUT
* DERIVED ENTROPY=492db4698cf3b73a5a24998aa3e9d7fa96275d85724a91e71aa2d645442f878555d078fd1f1f67e368976f04137b1f7a0d19232136ca50c44614af72b5582a5c
+===PWD BASE64===
+Application number: 707764'
+
+The derivation path format is: m/83696968'/707764'/{pwd_len}'/{index}'
+
+`20 <= pwd_len <= 86`
+
+[https://datatracker.ietf.org/doc/html/rfc4648 Base64] encode all 64 bytes of entropy.
+Remove any spaces or new lines inserted by Base64 encoding process. Slice base64 result string
+on index 0 to `pwd_len`. This slice is the password. As `pwd_len` is limited to 86, passwords will not contain padding.
+
+Entropy calculation:
+R = 64 (base64 - do not count padding)
+L = pwd_len
+Entropy = log2(R ** L)
+
+{| class="wikitable" style="margin:auto"
+! pwd_length !! (cca) entropy
+|-
+| 20 || 120.0
+|-
+| 24 || 144.0
+|-
+| 32 || 192.0
+|-
+| 64 || 384.0
+|-
+| 86 || 516.0
+|}
+
+INPUT:
+* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
+* PATH: m/83696968'/707764'/21'/0'
+
+OUTPUT
+* DERIVED ENTROPY=74a2e87a9ba0cdd549bdd2f9ea880d554c6c355b08ed25088cfa88f3f1c4f74632b652fd4a8f5fda43074c6f6964a3753b08bb5210c8f5e75c07a4c2a20bf6e9
+* DERIVED PWD=dKLoepugzdVJvdL56ogNV
+
+===PWD BASE85===
+Application number: 707785'
+
+The derivation path format is: m/83696968'/707785'/{pwd_len}'/{index}'
+
+`10 <= pwd_len <= 80`
+
+Base85 encode all 64 bytes of entropy.
+Remove any spaces or new lines inserted by Base64 encoding process. Slice base85 result string
+on index 0 to `pwd_len`. This slice is the password. `pwd_len` is limited to 80 characters.
+
+Entropy calculation:
+R = 85
+L = pwd_len
+Entropy = log2(R ** L)
+
+{| class="wikitable" style="margin:auto"
+! pwd_length !! (cca) entropy
+|-
+| 10 || 64.0
+|-
+| 15 || 96.0
+|-
+| 20 || 128.0
+|-
+| 30 || 192.0
+|-
+| 80 || 512.0
+|}
+
+INPUT:
+* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
+* PATH: m/83696968'/707785'/12'/0'
+
+OUTPUT
+* DERIVED ENTROPY=f7cfe56f63dca2490f65fcbf9ee63dcd85d18f751b6b5e1c1b8733af6459c904a75e82b4a22efff9b9e69de2144b293aa8714319a054b6cb55826a8e51425209
+* DERIVED PWD=_s`{TW89)i4`
+
===RSA===
Application number: 828365'
@@ -288,35 +386,94 @@ The resulting RSA key can be used to create a GPG key where the creation date MU
Note on GPG key capabilities on smartcard/hardware devices:
-GPG capable smart-cards SHOULD be be loaded as follows: The encryption slot SHOULD be loaded with the ENCRYPTION capable key; the authentication slot SHOULD be loaded with the AUTHENTICATION capable key. The signature capable slot SHOULD be loaded with the SIGNATURE capable key.
+GPG capable smart-cards SHOULD be loaded as follows: The encryption slot SHOULD be loaded with the ENCRYPTION capable key; the authentication slot SHOULD be loaded with the AUTHENTICATION capable key. The signature capable slot SHOULD be loaded with the SIGNATURE capable key.
However, depending on available slots on the smart-card, and preferred policy, the CERTIFY capable key MAY be flagged with CERTIFY and SIGNATURE capabilities and loaded into the SIGNATURE capable slot (for example where the smart-card has only three slots and the CERTIFY capability is required on the same card). In this case, the SIGNATURE capable sub-key would be disregarded because the CERTIFY capable key serves a dual purpose.
+===DICE===
+
+Application number: 89101'
+
+The derivation path format is: m/83696968'/89101'/{sides}'/{rolls}'/{index}'
+
+ 2 <= sides <= 2^32 - 1
+ 1 <= rolls <= 2^32 - 1
+
+Use this application to generate PIN numbers, numeric secrets, and secrets over custom alphabets.
+For example, applications could generate alphanumeric passwords from a 62-sided die (26 + 26 + 10).
+
+Roll values are zero-indexed, such that an N-sided die produces values in the range
+[0, N-1], inclusive. Applications should separate printed rolls by a comma or similar.
+
+Create a BIP85 DRNG whose seed is the derived entropy.
+
+Calculate the following integers:
+
+ bits_per_roll = ceil(log_2(sides))
+ bytes_per_roll = ceil(bits_per_roll / 8)
+
+Read bytes_per_roll bytes from the DRNG.
+Trim any bits in excess of bits_per_roll (retain the most
+significant bits). The resulting integer represents a single roll or trial.
+If the trial is greater than or equal to the number of sides, skip it and
+move on to the next one. Repeat as needed until all rolls are complete.
+
+INPUT:
+* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
+* PATH: m/83696968'/89101'/6'/10'/0'
+OUTPUT
+* DERIVED ENTROPY=5e41f8f5d5d9ac09a20b8a5797a3172b28c806aead00d27e36609e2dd116a59176a738804236586f668da8a51b90c708a4226d7f92259c69f64c51124b6f6cd2
+* DERIVED ROLLS=1,0,0,2,0,1,5,5,2,4
+
==Backwards Compatibility==
This specification is not backwards compatible with any other existing specification.
This specification relies on BIP32 but is agnostic to how the BIP32 root key is derived. As such, this standard is able to derive wallets with initialization schemes like BIP39 or Electrum wallet style mnemonics.
-==Discussion==
+==References==
-The reason for running the derived key through HMAC-SHA512 and truncating the result as necessary is to prevent leakage of the parent tree should the derived key (''k'') be compromized. While the specification requires the use of hardended key derivation which would prevent this, we cannot enforce hardened derivation, so this method ensures the derived entropy is hardened. Also, from a semantic point of view, since the purpose is to derive entropy and not a private key, we are required to transform the child key. This is done out of an abundance of caution, in order to ward off unwanted side effects should ''k'' be used for a dual purpose, including as a nonce ''hash(k)'', where undesirable and unforeseen interactions could occur.
+BIP32, BIP39
-==Acknowledgements==
+==Reference Implementations==
-Many thanks to Peter Gray and Christopher Allen for their input, and to Peter for suggesting extra application use cases.
+* 1.3.0 Python 3.x library implementation: [https://github.com/akarve/bipsea]
+* 1.1.0 Python 2.x library implementation: [https://github.com/ethankosakovsky/bip85]
+* 1.0.0 JavaScript library implementation: [https://github.com/hoganri/bip85-js]
-==References==
+==Changelog==
-BIP32, BIP39
+===1.3.0 (2024-10-22)===
-==Footnotes==
+====Added====
-[1] There is a very small chance that you'll make an invalid key that is zero or bigger than the order of the curve. If this occurs, software should hard fail (forcing users to iterate to the next index).
+* Dice application 89101'
+* Czech language code to application 39'
+* TPRV guidance for application 32'
+* Warning on application 32' key and chain code ordering
-From BIP32:
-In case parse256(IL) is 0 or ≥ n, the resulting key is invalid, and one should proceed with the next value for i. (Note: this has probability lower than 1 in 2127.)
+===1.2.0 (2022-12-04)===
-==Copyright==
+====Added====
-This BIP is dual-licensed under the Open Publication License and BSD 2-clause license.
+* Base64 application 707764'
+* Base85 application 707785'
+
+===1.1.0 (2020-11-19)===
+
+====Added====
+
+* BIP85-DRNG-SHAKE256
+* RSA application 828365'
+
+===1.0.0 (2020-06-11)===
+
+* Initial version
+
+==Footnotes==
+
+
+
+==Acknowledgements==
+
+Many thanks to Peter Gray and Christopher Allen for their input, and to Peter for suggesting extra application use cases.
diff --git a/bip-0086.mediawiki b/bip-0086.mediawiki
index f724884e8a..7bcaf14666 100644
--- a/bip-0086.mediawiki
+++ b/bip-0086.mediawiki
@@ -2,10 +2,10 @@
BIP: 86
Layer: Applications
Title: Key Derivation for Single Key P2TR Outputs
- Author: Andrew Chow
+ Author: Ava Chow
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0086
- Status: Draft
+ Status: Final
Type: Standards Track
Created: 2021-06-22
License: BSD-2-Clause
diff --git a/bip-0087.mediawiki b/bip-0087.mediawiki
index d270027e57..5470b47509 100644
--- a/bip-0087.mediawiki
+++ b/bip-0087.mediawiki
@@ -40,7 +40,7 @@ A modern standardization is needed for multisig derivation paths. There are som
m / purpose' / cosigner_index / change / address_index
-BIP45 unecessarily demands a single script type (here, P2SH). In addition, BIP45 sets cosigner_index in order to sort the purpose' public keys of each cosigner. This too is redundant, as descriptors can set the order of the public keys with multi or have them sorted lexicographically (as described in [https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki BIP67]) with sortedmulti. Sorting public keys between cosigners in order to create the full derivation path, prior to sending the key record to the coordinator to create the descriptor, merely adds additional unnecessary communication rounds.
+BIP45 unnecessarily demands a single script type (here, P2SH). In addition, BIP45 sets cosigner_index in order to sort the purpose' public keys of each cosigner. This too is redundant, as descriptors can set the order of the public keys with multi or have them sorted lexicographically (as described in [https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki BIP67]) with sortedmulti. Sorting public keys between cosigners in order to create the full derivation path, prior to sending the key record to the coordinator to create the descriptor, merely adds additional unnecessary communication rounds.
The second multisignature "standard" in use is m/48', which specifies:
@@ -48,7 +48,7 @@ The second multisignature "standard" in use is m/48', which specifies:
m / purpose' / coin_type' / account' / script_type' / change / address_index
-Rather than following in BIP 44/49/84's path and having a separate BIP per script after P2SH (BIP45), vendors decided to insert script_type' into the derivation path (where P2SH-P2WSH=1, P2WSH=2, Future_Script=3, etc). As described previously, this is unnecessary, as the descriptor sets the script. While it attempts to reduce maintainence work by getting rid of new BIPs-per-script, it still requires maintaining an updated, redundant, script_type list.
+Rather than following in BIP 44/49/84's path and having a separate BIP per script after P2SH (BIP45), vendors decided to insert script_type' into the derivation path (where P2SH-P2WSH=1, P2WSH=2, Future_Script=3, etc). As described previously, this is unnecessary, as the descriptor sets the script. While it attempts to reduce maintenance work by getting rid of new BIPs-per-script, it still requires maintaining an updated, redundant, script_type list.
The structure proposed later in this paper solves these issues and is quite comprehensive. It allows for the handling of multiple accounts, external and internal chains per account, and millions of addresses per chain, in a multi-party, multisignature, hierarchical deterministic wallet regardless of the script type '''Why propose this structure only for multisignature wallets?''' Currently, single-sig wallets are able to restore funds using just the master private key data (in the format of BIP39 usually). Even if the user doesn't recall the derivation used, the wallet implementation can iterate through common schemes (BIP44/49/84). With this proposed hierarchy, the user would either have to now backup additional data (the descriptor), or the wallet would have to attempt all script types for every account level when restoring. Because of this, even though the descriptor language handles the signature type just like it does the script type, it is best to restrict this script-agnostic hierarchy to multisignature wallets only..
@@ -105,7 +105,7 @@ Hardened derivation is used at this level.
It is crucial that this level is increased for each new wallet joined or private/public keys created; for both privacy and cryptographic purposes.
For example, before sending a new key record to a coordinator, the wallet must increment the account' level.
-This prevents key reuse - across ECDSA and Schnorr signatures, across different script types, and inbetween the same wallet types.
+This prevents key reuse - across ECDSA and Schnorr signatures, across different script types, and in between the same wallet types.
===Change===
diff --git a/bip-0088.mediawiki b/bip-0088.mediawiki
index 936f2ca931..7de164b933 100644
--- a/bip-0088.mediawiki
+++ b/bip-0088.mediawiki
@@ -27,7 +27,7 @@ This BIP is licensed under the 2-clause BSD license.
BIP32 derivation path format is universal, and a number of schemes for derivation were proposed
in BIP43 and other documents, such as BIPs 44,45,49,84. The flexibility of the format also allowed
-industry participants to implement custom derivation shemes that fit particular purposes,
+industry participants to implement custom derivation schemes that fit particular purposes,
but not necessarily useful in general.
Even when existing BIPs for derivation schemes are used, their usage is not uniform across
@@ -41,18 +41,18 @@ addresses differently than the one they used before.
The problem is common enough to warrant the creation of a dedicated website
([https://walletsrecovery.org/ walletsrecovery.org]) that tracks paths used by different wallets.
-At the time of writing, this website has used their own format to succintly describe multiple
-derivation paths. As far as author knows, it was the only publicitly used format to describe
+At the time of writing, this website has used their own format to succinctly describe multiple
+derivation paths. As far as author knows, it was the only publicly used format to describe
path templates before introduction of this BIP. The format was not specified anywhere beside
the main page of the website. It used | to denote alternative derivation indexes
(example: m/|44'|49'|84'/0'/0') or whole alternative paths (m/44'/0'/0'|m/44'/1'/0').
It was not declared as a template format to use for processing by software, and seems to be
an ad-hoc format only intended for illustration. In contrast to this ad-hoc format, the format
-described in this BIP is intended for unambigouos parsing by software, and to be easily read by humans
+described in this BIP is intended for unambiguous parsing by software, and to be easily read by humans
at the same time. Humans can visually detect the 'templated' parts of the path more easily than the use
of | in the template could allow. Wider range of paths can be defined in a single template more
-succintly and unambiguously.
+succinctly and unambiguously.
===Intended use and advantages===
@@ -71,7 +71,7 @@ into using well-known paths, or convince other vendors to support their custom p
scales poorly.
A flexible approach proposed in this document is to define a standard notation for "BIP32 path templates"
-that succintly describes the constraints to impose on the derivation path.
+that succinctly describes the constraints to impose on the derivation path.
Wide support for these path templates will increase interoperability and flexibility of solutions,
and will allow vendors and individual developers to easily define their own custom restrictions.
@@ -89,7 +89,7 @@ installation of malicious or incorrect profiles, though.
==Specification==
-The format for the template was choosen to make it easy to read, convenient and visually unambigous.
+The format for the template was chosen to make it easy to read, convenient and visually unambiguous.
Template starts with optional prefix m/, and then one or more sections delimited by the slash character (/).
@@ -127,13 +127,13 @@ Constraints:
# To avoid ambiguity, an index range that matches a single value MUST be specified as Unit range.
# To avoid ambiguity, an index range 0-2147483647 is not allowed, and MUST be specified as Wildcard index template instead
# For Non-unit range, range_end MUST be larger than range_start.
-# If there is more than one index range within the Ranged index template, range_start of the second and any subsequent range MUST be larger than the range_end of the preceeding range.
+# If there is more than one index range within the Ranged index template, range_start of the second and any subsequent range MUST be larger than the range_end of the preceding range.
# To avoid ambiguity, all representations of integer values larger than 0 MUST NOT start with character 0 (no leading zeroes allowed).
# If hardened marker appears within any section in the path template, all preceding sections MUST also specify hardened matching.
# To avoid ambiguity, if a hardened marker appears within any section in the path template, all preceding sections MUST also use the same hardened marker (either h or ').
# To avoid ambiguity, trailing slashes (for example, 1/2/) and duplicate slashes (for example, 0//1) MUST NOT appear in the template.
-It may be desireable to have fully unambiguous encoding, where for each valid path template string, there is no other valid template string that matches the exact same set of paths. This would enable someone to compare templates for equality through a simple string equality check, without any parsing.
+It may be desirable to have fully unambiguous encoding, where for each valid path template string, there is no other valid template string that matches the exact same set of paths. This would enable someone to compare templates for equality through a simple string equality check, without any parsing.
To achieve this, two extra rules are needed:
@@ -212,7 +212,7 @@ There is a discussion on path templating for bitcoin script descriptors at https
m/{44,49,84}'/0'/0'/{0-1}/{0-50000} specifies a full template that matches both external and internal chains of BIP44, BIP49 and BIP84 paths, with a constraint that the address index cannot be larger than 50000
Its representation after parsing can be (using Python syntax, ignoring full/partial distinction):
- [[(2147483692, 2147483692), (2147483697, 2147483697), (2147483732, 2147483732)),
+ [[(2147483692, 2147483692), (2147483697, 2147483697), (2147483732, 2147483732)],
[(2147483648, 2147483648)],
[(2147483648, 2147483648)],
[(0, 1)],
diff --git a/bip-0090.mediawiki b/bip-0090.mediawiki
index 4c96698683..48d415194b 100644
--- a/bip-0090.mediawiki
+++ b/bip-0090.mediawiki
@@ -82,7 +82,7 @@ https://github.com/bitcoin/bitcoin/pull/8391.
==References==
-[https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki BIP34 Block v2, Height in Coinbase]
+[https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki BIP34 Block v2, Height in Coinbase]
[https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki BIP66 Strict DER signatures]
diff --git a/bip-0093.mediawiki b/bip-0093.mediawiki
new file mode 100644
index 0000000000..22a7ba32e9
--- /dev/null
+++ b/bip-0093.mediawiki
@@ -0,0 +1,599 @@
+
+
+==Introduction==
+
+===Abstract===
+
+This document describes a standard for backing up and restoring the master seed of a
+[https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP-0032] hierarchical deterministic wallet, using Shamir's secret sharing.
+It includes an encoding format, a BCH error-correcting checksum, and algorithms for share generation and secret recovery.
+Secret data can be split into up to 31 shares.
+A minimum threshold of shares, which can be between 1 and 9, is needed to recover the secret, whereas without sufficient shares, no information about the secret is recoverable.
+
+===Copyright===
+
+This document is licensed under the 3-clause BSD license.
+
+===Motivation===
+
+BIP-0032 master seed data is the source entropy used to derive all private keys in an HD wallet.
+Safely storing this secret data is the hardest and most important part of self-custody.
+However, there is a tension between security, which demands limiting the number of backups, and resilience, which demands widely replicated backups.
+Encrypting the seed does not change this fundamental tradeoff, since it leaves essentially the same problem of how to back up the encryption key(s).
+
+To allow users freedom to make this tradeoff, we use Shamir's secret sharing, which guarantees that any number of shares less than the threshold leaks no information about the secret.
+This approach allows increasing safety by widely distributing the generated shares, while also providing security against the compromise of one or more shares (as long as fewer than the threshold have been compromised).
+
+[https://github.com/satoshilabs/slips/blob/master/slip-0039.md SLIP-0039] has essentially the same motivations as this standard.
+However, unlike SLIP-0039,
+
+* this standard aims to be simple enough for hand computation
+* we use the bech32 alphabet rather than a word list, resulting in fixed-length compact encodings
+* we do not support multi-level secret sharing (splitting of shares), although it is technically possible and may be added in a future BIP
+* because of the need to support hand computation, we '''do not''' support passphrases or key hardening
+
+Users who demand a higher level of security for particular secrets, or have a general distrust in digital electronic devices, have the option of using hand computation to backup and restore secret data in an interoperable manner.
+In particular, all computations can be done with simple lookup tables.
+'''It is therefore possible to compute and verify checksums, and to split and recover seeds, entirely using pen and paper.'''
+For long-lived rarely-used seeds, the ability to hand-verify checksums has a significant benefit even for users who do not care to do any other part of this process by hand.
+It means that they can verify the integrity (against non-malicious tampering) of their shares regularly, say, on an annual basis, without needing to continually expose secret data to new hardware.
+
+The ability to compute properties by hand comes from our choice of a small field and our use of linear error correcting codes.
+It does not come with any reduction in security, as long as users use high-quality randomness.
+Note that hand computation is optional, the particular details of hand computation are outside the scope of this standard, and implementers do not need to be concerned with this possibility.
+
+[https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP-0039] serves the same purpose as this standard: encoding master seeds for storage by users.
+However, BIP-0039 has no error-correcting ability, cannot sensibly be extended to support secret sharing, has no support for versioning or other metadata, and has many technical design decisions that make implementation and interoperability difficult (for example, the use of SHA-512 to derive seeds, or the use of 11-bit words).
+
+==Specification==
+
+===codex32===
+
+A codex32 string is similar to a bech32 string defined in [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki BIP-0173].
+It reuses the base-32 character set from BIP-0173, and consists of:
+
+* A human-readable part, which is the string "ms" (or "MS").
+* A separator, which is always "1".
+* A data part which is in turn subdivided into:
+** A threshold parameter, which MUST be a single digit between "2" and "9", or the digit "0".
+*** If the threshold parameter is "0" then the share index, defined below, MUST have a value of "s" (or "S").
+** An identifier consisting of 4 bech32 characters.
+** A share index, which is any bech32 character. Note that a share index value of "s" (or "S") is special and denotes the unshared secret (see section "Unshared Secret").
+** A payload which is a sequence of up to 74 bech32 characters. (However, see '''Long codex32 Strings''' below for an exception to this limit.)
+** A checksum which consists of 13 bech32 characters as described below.
+
+As with bech32 strings, a codex32 string MUST be entirely uppercase or entirely lowercase.
+For presentation, lowercase is usually preferable, but uppercase SHOULD be used for handwritten codex32 strings.
+If a codex32 string is encoded in a QR code, it SHOULD use the uppercase form, as this is encoded more compactly.
+
+===Checksum===
+
+The last thirteen characters of the data part form a checksum and contain no information.
+Valid strings MUST pass the criteria for validity specified by the Python 3 code snippet below.
+The function ms32_verify_checksum must return true when its argument is the data part as a list of integers representing the characters converted using the bech32 character table from BIP-0173.
+
+To construct a valid checksum given the data-part characters (excluding the checksum), the ms32_create_checksum function can be used.
+
+
+MS32_CONST = 0x10ce0795c2fd1e62a
+
+def ms32_polymod(values):
+ GEN = [
+ 0x19dc500ce73fde210,
+ 0x1bfae00def77fe529,
+ 0x1fbd920fffe7bee52,
+ 0x1739640bdeee3fdad,
+ 0x07729a039cfc75f5a,
+ ]
+ residue = 0x23181b3
+ for v in values:
+ b = (residue >> 60)
+ residue = (residue & 0x0fffffffffffffff) << 5 ^ v
+ for i in range(5):
+ residue ^= GEN[i] if ((b >> i) & 1) else 0
+ return residue
+
+def ms32_verify_checksum(data):
+ if len(data) >= 96: # See Long codex32 Strings
+ return ms32_verify_long_checksum(data)
+ if len(data) <= 93:
+ return ms32_polymod(data) == MS32_CONST
+ return False
+
+def ms32_create_checksum(data):
+ if len(data) > 80: # See Long codex32 Strings
+ return ms32_create_long_checksum(data)
+ values = data
+ polymod = ms32_polymod(values + [0] * 13) ^ MS32_CONST
+ return [(polymod >> 5 * (12 - i)) & 31 for i in range(13)]
+
+
+===Error Correction===
+
+A codex32 string without a valid checksum MUST NOT be used.
+The checksum is designed to be an error correcting code that can correct up to 4 character substitutions, up to 8 unreadable characters (called erasures), or up to 13 consecutive erasures.
+Implementations SHOULD provide the user with a corrected valid codex32 string if possible.
+However, implementations SHOULD NOT automatically proceed with a corrected codex32 string without user confirmation of the corrected string, either by prompting the user, or returning a corrected string in an error message and allowing the user to repeat their action.
+We do not specify how an implementation should implement error correction. However, we recommend that:
+
+* Implementations make suggestions to substitute non-bech32 characters with bech32 characters in some situations, such as replacing "B" with "8", "O" with "0", "I" with "l", etc.
+* Implementations interpret "?" as an erasure.
+* Implementations optionally interpret other non-bech32 characters, or characters with incorrect case, as erasures.
+* If a string with 8 or fewer erasures can have those erasures filled in to make a valid codex32 string, then the implementation suggests such a string as a correction.
+* If a string consisting of valid bech32 characters in the proper case can be made valid by substituting 4 or fewer characters, then the implementation suggests such a string as a correction.
+
+===Unshared Secret===
+
+When the share index of a valid codex32 string (converted to lowercase) is the letter "s", we call the string a codex32 secret.
+The payload in a codex32 secret is a direct encoding of a BIP-0032 HD master seed.
+
+The master seed is decoded by converting the payload to bytes:
+
+* Translate the characters to 5 bits values using the bech32 character table from BIP-0173, most significant bit first.
+* Re-arrange those bits into groups of 8 bits. Any incomplete group at the end MUST be 4 bits or less, and is discarded.
+
+Note that unlike the decoding process in BIP-0173, we do NOT require that the incomplete group be all zeros.
+
+For an unshared secret, the threshold parameter (the first character of the data part) is ignored (beyond the fact it must be a digit for the codex32 string to be valid).
+We recommend using the digit "0" for the threshold parameter in this case.
+The 4 character identifier also has no effect beyond aiding users in distinguishing between multiple different master seeds in cases where they have more than one.
+
+===Recovering Master Seed===
+
+When the share index of a valid codex32 string (converted to lowercase) is not the letter "s", we call the string an codex32 share.
+The first character of the data part indicates the threshold of the share, and it is required to be a non-"0" digit.
+
+In order to recover a master seed, one needs a set of valid codex32 shares such that:
+
+* All shares have the same threshold value, the same identifier, and the same length.
+* All of the share index values are distinct.
+* The number of codex32 shares is exactly equal to the (common) threshold value.
+
+If all the above conditions are satisfied, the ms32_recover function will return a codex32 secret when its argument is the list of codex32 shares with each share represented as a list of integers representing the characters converted using the bech32 character table from BIP-0173.
+
+
+bech32_inv = [
+ 0, 1, 20, 24, 10, 8, 12, 29, 5, 11, 4, 9, 6, 28, 26, 31,
+ 22, 18, 17, 23, 2, 25, 16, 19, 3, 21, 14, 30, 13, 7, 27, 15,
+]
+
+def bech32_mul(a, b):
+ res = 0
+ for i in range(5):
+ res ^= a if ((b >> i) & 1) else 0
+ a *= 2
+ a ^= 41 if (32 <= a) else 0
+ return res
+
+def bech32_lagrange(l, x):
+ n = 1
+ c = []
+ for i in l:
+ n = bech32_mul(n, i ^ x)
+ m = 1
+ for j in l:
+ m = bech32_mul(m, (x if i == j else i) ^ j)
+ c.append(m)
+ return [bech32_mul(n, bech32_inv[i]) for i in c]
+
+def ms32_interpolate(l, x):
+ w = bech32_lagrange([s[5] for s in l], x)
+ res = []
+ for i in range(len(l[0])):
+ n = 0
+ for j in range(len(l)):
+ n ^= bech32_mul(w[j], l[j][i])
+ res.append(n)
+ return res
+
+def ms32_recover(l):
+ return ms32_interpolate(l, 16)
+
+
+===Generating Shares===
+
+If we already have ''t'' valid codex32 strings such that:
+
+* All strings have the same threshold value ''t'', the same identifier, and the same length
+* All of the share index values are distinct
+
+Then we can derive additional shares with the ms32_interpolate function by passing it a list of exactly ''t'' of these codex32 strings, together with a fresh share index distinct from all of the existing share indexes.
+The newly derived share will have the provided share index.
+
+Once a user has generated ''n'' codex32 shares, they may discard the codex32 secret (if it exists).
+The ''n'' shares form a ''t'' of ''n'' Shamir's secret sharing scheme of a codex32 secret.
+
+There are two ways to create an initial set of ''t'' valid codex32 strings, depending on whether the user already has an existing master seed to split.
+
+====For a fresh master seed====
+
+In the case that the user wishes to generate a fresh master seed, the user generates random initial shares, as follows:
+
+# Choose a bitsize, between 128 and 512, which must be a multiple of 8.
+# Choose a threshold value ''t'' between 2 and 9, inclusive
+# Choose a 4 bech32 character identifier
+#* We do not define how to choose the identifier, beyond noting that it SHOULD be distinct for every master seed the user may need to disambiguate.
+# ''t'' many times, generate a random share by:
+## Take the next available letter from the bech32 alphabet, in alphabetical order, as a, c, d, ..., to be the share index
+## Set the first nine characters to be the prefix ms1, the threshold value ''t'', the 4-character identifier, and then the share index
+## Choose the next ceil(''bitlength / 5'') characters uniformly at random
+## Generate a valid checksum in accordance with the Checksum section, and append this to the resulting shares
+
+The result will be ''t'' distinct shares, all with the same initial 8 characters, and a distinct share index as the 9th character.
+
+With this set of ''t'' codex32 shares, new shares can be derived as discussed above. This process generates a fresh master seed, whose value can be retrieved by running the recovery process on any ''t'' of these shares.
+
+====For an existing master seed====
+
+Before generating shares for an existing master seed, it first must be converted into a codex32 secret, as described above.
+The conversion process consists of:
+
+# Choose a threshold value ''t'' between 2 and 9, inclusive
+# Choose a 4 bech32 character identifier
+#* We do not define how to choose the identifier, beyond noting that it SHOULD be distinct for every master seed the user may need to disambiguate.
+# Set the share index to s
+# Set the payload to a bech32 encoding of the master seed, padded with arbitrary bits
+# Generating a valid checksum in accordance with the Checksum section
+
+Along with the codex32 secret, the user must generate ''t''-1 other codex32 shares, each with the same threshold value, the same identifier, and a distinct share index.
+These shares should be generated as described in the "fresh master seed" section.
+
+The codex32 secret and the ''t''-1 codex32 shares form a set of ''t'' valid codex32 strings from which additional shares can be derived as described above.
+
+===Long codex32 Strings===
+
+The 13 character checksum design only supports up to 80 data characters.
+Excluding the threshold, identifier and index characters, this limits the payload to 74 characters or 46 bytes.
+While this is enough to support the 32-byte advised size of BIP-0032 master seeds, BIP-0032 allows seeds to be up to 64 bytes in size.
+We define a long codex32 string format to support these longer seeds by defining an alternative checksum.
+
+
+MS32_LONG_CONST = 0x43381e570bf4798ab26
+
+def ms32_long_polymod(values):
+ GEN = [
+ 0x3d59d273535ea62d897,
+ 0x7a9becb6361c6c51507,
+ 0x543f9b7e6c38d8a2a0e,
+ 0x0c577eaeccf1990d13c,
+ 0x1887f74f8dc71b10651,
+ ]
+ residue = 0x23181b3
+ for v in values:
+ b = (residue >> 70)
+ residue = (residue & 0x3fffffffffffffffff) << 5 ^ v
+ for i in range(5):
+ residue ^= GEN[i] if ((b >> i) & 1) else 0
+ return residue
+
+def ms32_verify_long_checksum(data):
+ return ms32_long_polymod(data) == MS32_LONG_CONST
+
+def ms32_create_long_checksum(data):
+ values = data
+ polymod = ms32_long_polymod(values + [0] * 15) ^ MS32_LONG_CONST
+ return [(polymod >> 5 * (14 - i)) & 31 for i in range(15)]
+
+
+A long codex32 string follows the same specification as a regular codex32 string with the following changes.
+
+* The payload is a sequence of between 75 and 103 bech32 characters.
+* The checksum consists of 15 bech32 characters as defined above.
+
+A codex32 string with a data part of 94 or 95 characters is never legal as a regular codex32 string is limited to 93 data characters and a long codex32 string is at least 96 characters.
+
+Generation of long shares and recovery of the master seed from long shares proceeds in exactly the same way as for regular shares with the ms32_interpolate function.
+
+The long checksum is designed to be an error correcting code that can correct up to 4 character substitutions, up to 8 unreadable characters (called erasures), or up to 15 consecutive erasures.
+As with regular checksums we do not specify how an implementation should implement error correction, and all our recommendations for error correction of regular codex32 strings also apply to long codex32 strings.
+
+==Rationale==
+
+This scheme is based on the observation that the Lagrange interpolation of valid codewords in a BCH code will always be a valid codeword.
+This means that derived shares will always have valid checksum, and a sufficient threshold of shares with valid checksums will derive a secret with a valid checksum.
+
+The header system is also compatible with Lagrange interpolation, meaning all derived shares will have the same identifier and will have the appropriate share index.
+This fact allows the header data to be covered by the checksum.
+
+The checksum size and identifier size have been chosen so that the encoding of 128-bit seeds and shares fit within 48 characters.
+This is a standard size for many common seed storage formats, which has been popularized by the 12 four-letter word format of the BIP-0039 mnemonic.
+
+The 13 character checksum is adequate to correct 4 errors in up to 93 characters (80 characters of data and 13 characters of the checksum).
+We can correct up to 8 erasures (errors with known locations), and up to 13 consecutive errors (burst errors).
+Beyond that, our code is guaranteed to detect up to 8 errors.
+More generally, any number of random errors will be detected with overwhelming (1 - 2^65) probability. However, the checksum does not protect against maliciously constructed errors.
+These parameters are slightly better than those of the checksum used in SLIP-0039.
+
+For 256-bit seeds and shares our strings are 74 characters, which fits into the 96 character format of the 24 four-letter word format of the BIP-0039 mnemonic, with plenty of room to spare.
+
+A longer checksum is needed to support up to 512-bit seeds, the longest seed length specified in BIP-0032, as the 13 character checksum isn't adequate for more than 80 data characters.
+While we could use the 15 character checksum for both cases, we prefer to keep the strings as short as possible for the more common cases of 128-bit and 256-bit master seeds.
+We only guarantee to correct 4 characters no matter how long the string is.
+Longer strings mean more chances for transcription errors, so shorter strings are better.
+
+The longest data part using the regular 13 character checksum is 93 characters and corresponds to a 400-bit secret.
+At this length, the prefix MS1 is not covered by the checksum.
+This is acceptable because the checksum scheme itself requires you to know that the MS1 prefix is being used in the first place.
+If the prefix is damaged and a user is guessing that the data might be using this scheme, then the user can enter the available data explicitly using the suspected MS1 prefix.
+
+===Not BIP-0039 Entropy===
+
+Instead of encoding a BIP-0032 master seed, an alternative would be to encode BIP-0039 entropy.
+However this alternative approach is fraught with difficulties.
+
+On approach would be to encode the BIP-0039 entropy along with the BIP-0039 checksum data.
+This data can directly be recovered from the BIP-0039 mnemonic, and the process can be reversed if one knows the target language.
+However, for a 128-bit seed, there is a 4 bit checksum yielding 132 bits of data that needs to be encoded.
+This exceeds the 130-bits of room that we have for storing 128 bit seeds.
+We would have to compromise on the 48 character size, or the size of the headers, or the size of the checksum in order to add room for an additional character of data.
+
+This approach would also eliminate our short cut generation of a fresh master secret from generating random shares.
+One would be required to first generate BIP-0039 entropy, and then add a BIP-0039 checksum, before adding a Codex32 checksum and then generate other shares.
+In particular, this process could no longer be performed by hand since it is effectively impossible to hand compute a BIP-0039 checksum.
+
+An alternative approach is to discard the BIP-0039 checksum, since it is inadequate for error correction anyways, and rely on the Codex32 checksum.
+However, this approach ends up eliminating the benefits of BIP-0039 compatibility.
+While it is now possible to hand generate fresh shares, it is impossible to recover compatible BIP-0039 words by hand because, again, the BIP-0039 checksum is not hand computable.
+The only way of generating the compatible BIP-0039 mnemonic is to use wallet software.
+But if the wallet software is need to support this approach to decoding entropy, we may as well bypass all of the overhead of BIP-0039 and directly encode the entropy of a BIP-0032 master seed, which is what we do in our Codex32 proposal.
+
+Beyond the problems above, BIP-0039 does not define a single transformation from entropy to BIP-0032 master seed.
+Instead every different language has it own word list (or word lists) and each choice of word list yields a different transformation from entropy to master seed.
+We would need to encode the choice of word list in our share's meta-data, which takes up even more room, and is difficult to specify due to the ever-evolving choice of word lists.
+
+Alternatively we could standardize on the choice of the English word list, something that is nearly a de facto standard, and simply be incompatible with BIP-0039 wallets of other languages.
+Such a choice also risks users of BIP-0039 recovering their entropy from their language, encoding it in Codex32 and then failing to recover their wallet because the English word lists has replaced their language's word list.
+
+The main advantage of this alternative approach would be that wallets could give users an option switch between backing up their entropy as a BIP-0039 mnemonic and in Codex32 format, but again, only if their language choice happens to be the English word list.
+In practice, we do not expect users in switch back and forth between backup formats, and instead just generate a fresh master seed using Codex32.
+
+Seeing little value with BIP-0039 compatibility (English-only), all the difficulties with BIP-0039 language choice, not to mention the PBKDF2 overhead of using BIP-0039, we think it is best to abandon BIP-0039 and encode BIP-0032 master seeds directly.
+Our approach is semi-convertible with BIP-0039's 512-bit master seeds (in all languages, see Backwards Compatibility) and fully interconvertible with SLIP-39 encoded master seeds or any other encoding of BIP-0032 master seeds.
+
+==Backwards Compatibility==
+
+codex32 is an alternative to BIP-0039 and SLIP-0039.
+It is technically possible to derive the BIP32 master seed from seed words encoded in one of these schemes, and then to encode this seed in codex32.
+For BIP-0039 this process is irreversible, since it involves hashing the original words.
+Furthermore, the resulting seed will be 512 bits long, which may be too large to be safely and conveniently handled.
+
+SLIP-0039 seed words can be reversibly converted to master seeds, so it is possible to interconvert between SLIP-0039 and codex32.
+However, SLIP-0039 '''shares''' cannot be converted to codex32 shares because the two schemes use a different underlying field.
+
+The authors of this BIP do not recommend interconversion.
+Instead, users who wish to switch to codex32 should generate a fresh seed and sweep their coins.
+
+==Reference Implementation==
+
+Our [https://github.com/BlockstreamResearch/codex32 reference implementation repository] contains implementations in Rust and PostScript.
+The inline code in this BIP text can be used as a Python reference.
+
+==Test Vectors==
+
+===Test vector 1===
+
+This example shows the codex32 format, when used without splitting the secret into any shares.
+The payload contains 26 bech32 characters, which corresponds to 130 bits. We truncate the last two bits in order to obtain a 128-bit master seed.
+
+codex32 secret (bech32): ms10testsxxxxxxxxxxxxxxxxxxxxxxxxxx4nzvca9cmczlw
+
+Master secret (hex): 318c6318c6318c6318c6318c6318c631
+
+* human-readable part: ms
+* separator: 1
+* k value: 0 (no secret splitting)
+* identifier: test
+* share index: s (the secret)
+* payload: xxxxxxxxxxxxxxxxxxxxxxxxxx
+* checksum: 4nzvca9cmczlw
+* master node xprv: xprv9s21ZrQH143K3taPNekMd9oV5K6szJ8ND7vVh6fxicRUMDcChr3bFFzuxY8qP3xFFBL6DWc2uEYCfBFZ2nFWbAqKPhtCLRjgv78EZJDEfpL
+
+===Test vector 2===
+
+This example shows generating a new master seed using "random" codex32 shares, as well as deriving an additional codex32 share, using ''k''=2 and an identifier of NAME.
+Although codex32 strings are canonically all lowercase, it's also valid to use all uppercase.
+
+Share with index A: MS12NAMEA320ZYXWVUTSRQPNMLKJHGFEDCAXRPP870HKKQRM
+
+Share with index C: MS12NAMECACDEFGHJKLMNPQRSTUVWXYZ023FTR2GDZMPY6PN
+
+* Derived share with index D: MS12NAMEDLL4F8JLH4E5VDVULDLFXU2JHDNLSM97XVENRXEG
+* Secret share with index S: MS12NAMES6XQGUZTTXKEQNJSJZV4JV3NZ5K3KWGSPHUH6EVW
+* Master secret (hex): d1808e096b35b209ca12132b264662a5
+* master node xprv: xprv9s21ZrQH143K2NkobdHxXeyFDqE44nJYvzLFtsriatJNWMNKznGoGgW5UMTL4fyWtajnMYb5gEc2CgaKhmsKeskoi9eTimpRv2N11THhPTU
+
+Note that per BIP-0173, the lowercase form is used when determining a character's value for checksum purposes.
+In particular, given an all uppercase codex32 string, we still use lowercase ms as the human-readable part during checksum construction.
+
+===Test vector 3===
+
+This example shows splitting an existing 128-bit master seed into "random" codex32 shares, using ''k''=3 and an identifier of cash.
+We appended two zero bits in order to obtain 26 bech32 characters (130 bits of data) from the 128-bit master seed.
+
+Master secret (hex): ffeeddccbbaa99887766554433221100
+
+Secret share with index s: ms13cashsllhdmn9m42vcsamx24zrxgs3qqjzqud4m0d6nln
+
+Share with index a: ms13casha320zyxwvutsrqpnmlkjhgfedca2a8d0zehn8a0t
+
+Share with index c: ms13cashcacdefghjklmnpqrstuvwxyz023949xq35my48dr
+
+* Derived share with index d: ms13cashd0wsedstcdcts64cd7wvy4m90lm28w4ffupqs7rm
+* Derived share with index e: ms13casheekgpemxzshcrmqhaydlp6yhms3ws7320xyxsar9
+* Derived share with index f: ms13cashf8jh6sdrkpyrsp5ut94pj8ktehhw2hfvyrj48704
+* master node xprv: xprv9s21ZrQH143K266qUcrDyYJrSG7KA3A7sE5UHndYRkFzsPQ6xwUhEGK1rNuyyA57Vkc1Ma6a8boVqcKqGNximmAe9L65WsYNcNitKRPnABd
+
+Any three of the five shares among acdef can be used to recover the secret.
+
+Note that the choice to append two zero bits was arbitrary, and any of the following four secret shares would have been valid choices.
+However, each choice would have resulted in a different set of derived shares.
+
+* ms13cashsllhdmn9m42vcsamx24zrxgs3qqjzqud4m0d6nln
+* ms13cashsllhdmn9m42vcsamx24zrxgs3qpte35dvzkjpt0r
+* ms13cashsllhdmn9m42vcsamx24zrxgs3qzfatvdwq5692k6
+* ms13cashsllhdmn9m42vcsamx24zrxgs3qrsx6ydhed97jx2
+
+===Test vector 4===
+
+This example shows converting a 256-bit secret into a codex32 secret, without splitting the secret into any shares.
+We appended four zero bits in order to obtain 52 bech32 characters (260 bits of data) from the 256-bit secret.
+
+256-bit secret (hex): ffeeddccbbaa99887766554433221100ffeeddccbbaa99887766554433221100
+
+* codex32 secret: ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqqtum9pgv99ycma
+* master node xprv: xprv9s21ZrQH143K3s41UCWxXTsU4TRrhkpD1t21QJETan3hjo8DP5LFdFcB5eaFtV8x6Y9aZotQyP8KByUjgLTbXCUjfu2iosTbMv98g8EQoqr
+
+Note that the choice to append four zero bits was arbitrary, and any of the following sixteen codex32 secrets would have been valid:
+
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqqtum9pgv99ycma
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqpj82dp34u6lqtd
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqzsrs4pnh7jmpj5
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqrfcpap2w8dqezy
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqy5tdvphn6znrf0
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyq9dsuypw2ragmel
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqx05xupvgp4v6qx
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyq8k0h5p43c2hzsk
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqgum7hplmjtr8ks
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqf9q0lpxzt5clxq
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyq28y48pyqfuu7le
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqt7ly0paesr8x0f
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqvrvg7pqydv5uyz
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqd6hekpea5n0y5j
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqwcnrwpmlkmt9dt
+* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyq0pgjxpzx0ysaam
+
+===Test vector 5===
+
+This example shows generating a new 512-bit master seed using "random" codex32 characters and appending a checksum.
+The payload contains 103 bech32 characters, which corresponds to 515 bits. The last three bits are discarded when converting to a 512-bit master seed.
+
+This is an example of a '''Long codex32 String'''.
+
+* Secret share with index S: MS100C8VSM32ZXFGUHPCHTLUPZRY9X8GF2TVDW0S3JN54KHCE6MUA7LQPZYGSFJD6AN074RXVCEMLH8WU3TK925ACDEFGHJKLMNPQRSTUVWXY06FHPV80UNDVARHRAK
+* Master secret (hex): dc5423251cb87175ff8110c8531d0952d8d73e1194e95b5f19d6f9df7c01111104c9baecdfea8cccc677fb9ddc8aec5553b86e528bcadfdcc201c17c638c47e9
+* master node xprv: xprv9s21ZrQH143K4UYT4rP3TZVKKbmRVmfRqTx9mG2xCy2JYipZbkLV8rwvBXsUbEv9KQiUD7oED1Wyi9evZzUn2rqK9skRgPkNaAzyw3YrpJN
+
+===Invalid test vectors===
+
+These examples have incorrect checksums.
+
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxve740yyge2ghq
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxve740yyge2ghp
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxlk3yepcstwr
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxx6pgnv7jnpcsp
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxx0cpvr7n4geq
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxm5252y7d3lr
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxrd9sukzl05ej
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxc55srw5jrm0
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxgc7rwhtudwc
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxx4gy22afwghvs
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe8yfm0
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxvm597d
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxme084q0vpht7pe0
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxme084q0vpht7pew
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxqyadsp3nywm8a
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxzvg7ar4hgaejk
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcznau0advgxqe
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxch3jrc6j5040j
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx52gxl6ppv40mcv
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx7g4g2nhhle8fk
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx63m45uj8ss4x8
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy4r708q7kg65x
+
+These examples use the wrong checksum for their given data sizes.
+
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxurfvwmdcmymdufv
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxcsyppjkd8lz4hx3
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxu6hwvl5p0l9xf3c
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxwqey9rfs6smenxa
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxv70wkzrjr4ntqet
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3hmlrmpa4zl0v
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrfggf88znkaup
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxpt7l4aycv9qzj
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxus27z9xtyxyw3
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcwm4re8fs78vn
+
+These examples have improper lengths.
+They are either too short, too long, or would decode to byte sequence with an incomplete group greater than 4 bits.
+
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxw0a4c70rfefn4
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxk4pavy5n46nea
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxx9lrwar5zwng4w
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr335l5tv88js3
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxvu7q9nz8p7dj68v
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxpq6k542scdxndq3
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkmfw6jm270mz6ej
+* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxzhddxw99w7xws
+* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxx42cux6um92rz
+* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxarja5kqukdhy9
+* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxky0ua3ha84qk8
+* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9eheesxadh2n2n9
+* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9llwmgesfulcj2z
+* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx02ev7caq6n9fgkf
+
+This example uses a "0" threshold with a non-"s" index
+
+* ms10fauxxxxxxxxxxxxxxxxxxxxxxxxxxxx0z26tfn0ulw3p
+
+This example has a threshold that is not a digit.
+
+* ms1fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxda3kr3s0s2swg
+
+These examples do not begin with the required "ms" or "MS" prefix and/or are missing the "1" separator.
+
+* 0fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* 10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* ms0fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* m10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* s10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* 0fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxhkd4f70m8lgws
+* 10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxhkd4f70m8lgws
+* m10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxx8t28z74x8hs4l
+* s10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxh9d0fhnvfyx3x
+
+These examples all incorrectly mix upper and lower case characters.
+
+* Ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* mS10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* MS10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* ms10FAUXsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* ms10fauxSxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2
+* ms10fauxsXXXXXXXXXXXXXXXXXXXXXXXXXXuqxkk05lyf3x2
+* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxUQXKK05LYF3X2
+
+==Appendix==
+
+===Mathematical Companion===
+
+Below we use the bech32 character set to denote values in GF[32].
+In bech32, the letter Q denotes zero and the letter P denotes one.
+The digits 0 and 2 through 9 do ''not'' denote their numeric values.
+They are simply elements of GF[32].
+
+The generating polynomial for our BCH code is as follows.
+
+We extend GF[32] to GF[1024] by adjoining a primitive cube root of unity, ζ, satisfying ζ^2 = ζ + P.
+
+We select β := G ζ which has order 93, and construct the product (x - β^i) for i in {17, 20, 46, 49, 52, 77, 78, 79, 80, 81, 82, 83, 84}.
+The resulting polynomial is our generating polynomial for our 13 character checksum:
+
+ x^13 + E x^12 + M x^11 + 3 x^10 + G x^9 + Q x^8 + E x^7 + E x^6 + E x^5 + L x^4 + M x^3 + C x^2 + S x + S
+
+For our long checksum, we select γ := E + X ζ, which has order 1023, and construct the product (x - γ^i) for i in {32, 64, 96, 895, 927, 959, 991, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026}.
+The resulting polynomial is our generating polynomial for our 15 character checksum for long strings:
+
+ x^15 + 0 x^14 + 2 x^13 + E x^12 + 6 x^11 + F x^10 + E x^9 + 4 x^8 + X x^7 + H x^6 + 4 x^5 + X x^4 + 9 x^3 + K x^2 + Y x^1 + H
+
+(Reminder: the character 0 does ''not'' denote the zero of the field.)
diff --git a/bip-0094.mediawiki b/bip-0094.mediawiki
new file mode 100644
index 0000000000..8457b072d1
--- /dev/null
+++ b/bip-0094.mediawiki
@@ -0,0 +1,145 @@
+
+
+== Abstract ==
+
+A new test network with the goal to replace Testnet 3. This network comes with small but important improvements of the consensus rules, that should make it impractical to attack the network using only CPU mining.
+
+== Motivation ==
+
+Quoting the original mailing list post from Jameson Lopphttps://gnusha.org/pi/bitcoindev/CADL_X_eXjbRFROuJU0b336vPVy5Q2RJvhcx64NSNPH-3fDCUfw@mail.gmail.com/:
+
+
+Testnet3 has been running for 13 years. It's on block 2.5 million something and the block reward is down to ~0.014 TBTC, so mining is not doing a great job at distributing testnet coins anymore.
+
+The reason the block height is insanely high is due to a rather amusing edge case bug that causes the difficulty to regularly get reset to 1, which causes a bit of havoc. If you want a deep dive into the quirk: https://blog.lopp.net/the-block-storms-of-bitcoins-testnet/
+
+Testnet3 is being actively used for scammy airdrops; those of us who tend to be generous with our testnet coins are getting hounded by non-developers chasing cheap gains.
+
+As a result, TBTC is being actively bought and sold; one could argue that the fundamental principle of testnet coins having no value has been broken.
+
+
+Since then the issue with block storms has been further demonstrated on Testnet 3 when three years' worth of blocks were mined in a few weeks while rendering the network practically unusable at the same time.
+
+== Specification ==
+
+Testnet 4 follows the same consensus rules as mainnet with the following three exceptions. Additionally, all soft forks that are active on mainnet as of May 2024 are enforced from genesis.
+
+=== 1. 20-minute Exception Rule ===
+
+This rule was implemented in Testnet 3https://github.com/bitcoin/bitcoin/pull/686 and is preserved in Testnet 4.
+
+==== Rule Specification ====
+
+1. For any block except the first block in a difficulty period:
+ a. If the block's timestamp is >20 minutes past the timestamp of the previous block
+ b. Then the block MUST use the minimum difficulty value (nBits = 0x1d00ffff), regardless of the network's actual difficulty
+
+2. The first block of each difficulty period MUST use the actual network difficulty.
+
+This rule enables CPU mining on testnet but has led to block stormshttps://blog.lopp.net/the-block-storms-of-bitcoins-testnet/ which rule #2 below addresses.
+
+=== 2. Block Storm Fix ===
+
+This is a new rule to address block storms caused by the 20-minute exception.
+
+==== Problem Statement ====
+
+In Mainnet and Testnet 3, the difficulty adjustment calculation uses the difficulty value of the last block in the previous period as its base. When the 20-minute exception is applied to this last block, it is mined at difficulty 1, causing the next period's difficulty to be constrained between 1-4, leading to block storms.
+
+==== Rule Specification ====
+
+1. For difficulty adjustment calculations between periods:
+ a. The base difficulty value MUST be taken from the first block of the previous difficulty period
+ b. NOT from the last block as in previous implementations
+
+2. The adjustment factor calculation remains unchanged:
+ a. Multiplication factor based on the duration of the previous difficulty period
+ b. Limited to no less than 1/4 and no more than 4x
+
+This change ensures that the actual network difficulty is used for adjustment calculations rather than potentially manipulated values from the last block in a period.
+
+=== 3. Time Warp Attack Prevention ===
+
+This rule prevents time warp attacks that could otherwise be used to amplify block stormsA perpetual block storm attack with entire difficulty periods being authored in less than 3.5 days that resets the difficulty to the minimum in the last block of every difficulty period would adjust to a new actual difficulty of 4 every period. An attacker that additionally leverages a time warp attack would start their attack by holding back timestamps until the latest block's timestamp is at least two weeks in the past, and then limiting their block rate to six blocks per second, incrementing the timestamp on every sixth block. Only on the last block they would use the current time, which both resets the difficulty to one per the 20-minute exception and would result in a difficulty adjustment keeping the difficulty at the minimum due to the elapsed time exceeding the target. This would allow lower the difficulty for all blocks to difficulty 1 instead of difficulty 4.
+
+==== Rule Specification ====
+
+1. For any block whose height modulo 2016 equals 0 (i.e., the first block of each difficulty period):
+ a. The block's nTime field MUST be greater than or equal to the nTime field of the immediately prior block minus 600 seconds
+
+2. These blocks MUST still comply with existing Median-Time-Past nTime restrictions
+
+This rule is based on The Great Consensus Cleanup proposalhttps://github.com/TheBlueMatt/bips/blob/cleanup-softfork/bip-XXXX.mediawiki and prevents miners from manipulating timestamps to artificially lower difficulty.
+
+== Rationale ==
+
+The applied changes were the result of discussions on the mailing list and the PR. The selected changes try to strike a balance between minimal changes to the network (keeping it as close to mainnet as possible) while making it more robust against attackers that try to disrupt the network. Several alternative designs were considered:
+
+* For the block storm fix an alternative fix could have been to prevent the last block in a difficulty period from applying the existing difficulty exception. Both solutions were deemed acceptable and there was no clear preference among reviewers.
+* Removal of the 20-minute exception was discussed but dismissed since several reviewers insisted that it was a useful feature allowing non-standard transactions to be mined with just a CPU. The 20-minute exception also allows CPU users to move the chain forward (except on the first block that needs to be mined at actual difficulty) in case a large amount of hash power suddenly leaves the network. This would allow the chain to recover to a normal difficulty level faster if left stranded at high difficulty.
+* Increase of minimum difficulty was discussed but dismissed as it would categorically prevent participation in the network using a CPU miner (utilizing the 20-minute exception).
+* Increase of the delay in the 20-minute exception was suggested but did not receive significant support.
+* Re-enabling acceptnonstdtxn in bitcoin core by default was dismissed as it had led to confusion among layer-2s that had used testnet for transaction propagation tests and expected it to behave similarly to mainnet.
+* Motivating miners to re-org min difficulty blocks was suggested, but was considered out of scope for this BIP, since adoption of such a mining policy remains available after Testnet 4 is deployed. As 20-minute exception blocks only contribute work corresponding to difficulty one to the chaintip, and actual difficulty blocks should have a difficulty magnitudes higher, a block mined at actual difficulty could easily replace even multiple 20-minute exception blocks.
+* Persisting the real difficulty in the version field was suggested to robustly prevent exploits of the 20-minute exception while allowing it to be used on any block, but did not receive a sufficient level of support to justify the more invasive change.
+
+One known downside of the chosen approach is that if the difficulty is gradually raised by a miner with significant hash rate, and this miner disappears, then each difficulty adjustment period requires one block at the actual difficulty.
+
+This would cause the network to stall once per difficulty adjustment period until the real difficulty is adjusted downwards enough for the remaining hash rate to find this block in reasonable time.
+
+== Network Parameters ==
+
+=== Consensus Rules ===
+
+All consensus rules active on mainnet at the time of this proposal are enforced from block 1, the newest of these rules being the Taproot softfork.
+
+=== Genesis Block ===
+
+* Message: 03/May/2024 000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00e
+* Pubkey: 000000000000000000000000000000000000000000000000000000000000000000
+* Time stamp: 1714777860
+* Nonce: 393743547
+* Difficulty: 0x1d00ffff
+* Version: 1
+
+The resulting genesis block hash is 00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043, and the block hex is 0100000000000000000000000000000000000000000000000000000000000000000000004e7b2b9128fe0291db0693af2ae418b767e657cd407e80cb1434221eaea7a07a046f3566ffff001dbb0c78170101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5504ffff001d01044c4c30332f4d61792f323032342030303030303030303030303030303030303030303165626435386332343439373062336161396437383362623030313031316662653865613865393865303065ffffffff0100f2052a010000002321000000000000000000000000000000000000000000000000000000000000000000ac00000000.
+
+=== Message Start ===
+
+The message start is defined as 0x1c163f28. These four bytes were randomly generated and have no special meaning.
+
+=== Network Parameters ===
+
+The default p2p port for Testnet 4 is `48333`.
+
+== Backwards Compatibility ==
+
+The rules used by Testnet 4 are backwards compatible to the rules of Testnet 3. Existing software that implements support for Testnet 3 would only require addition of the network parameters (magic number, genesis block, etc.) to be able to follow Testnet 4.
+
+However, implementations that only implement Testnet 3's rules would accept a chain that violates Testnet 4's rules and are therefore susceptible to being forked off. It is recommended that any implementations check blocks in regard to all the new rules of Testnet 4 and reject blocks that fail to comply.
+
+== Reference implementation ==
+
+Pull request at https://github.com/bitcoin/bitcoin/pull/29775
+
+== References ==
+
+
+
+== Copyright ==
+
+This document is licensed under the Creative Commons CC0 1.0 Universal license.
\ No newline at end of file
diff --git a/bip-0098.mediawiki b/bip-0098.mediawiki
index 8540d1ac89..d4711bb423 100644
--- a/bip-0098.mediawiki
+++ b/bip-0098.mediawiki
@@ -32,7 +32,7 @@ This BIP is licensed under a Creative Commons Attribution-ShareAlike license. Al
A Merkle hash-tree is a directed acyclic graph data structure where all non-terminal nodes are labeled with the hash of combined labels or values of the node(s) it is connected to.
Bitcoin uses a unique Merkle hash-tree construct invented by Satoshi for calculating the block header commitment to the list of transactions in a block.
-While it would be convenient for new applications to make use of this same data structure so as to share implementation and maintenance costs, there are three principle drawbacks to reuse.
+While it would be convenient for new applications to make use of this same data structure so as to share implementation and maintenance costs, there are three principal drawbacks to reuse.
First, Satoshi's Merkle hash-tree has a serious vulnerability[1] related to duplicate tree entries that can cause bugs in protocols that use it.
While it is possible to secure protocols and implementations against exploit of this flaw, it requires foresight and it is a bit more tricky to design secure protocols that work around this vulnerability.
@@ -63,7 +63,7 @@ Nodes with single children are not allowed.
The ''double-SHA256'' cryptographic hash function takes an arbitrary-length data as input and produces a 32-byte hash by running the data through the SHA-256 hash function as specified in FIPS 180-4[3], and then running the same hash function again on the 32-byte result, as a protection against length-extension attacks.
-The ''fast-SHA256'' cryptographic hash function takes two 32-byte hash values, concatenates these to produce a 64-byte buffer, and applies a single run of the SHA-256 hash function with a custom 'initialization vector' (IV) and without message paddding.
+The ''fast-SHA256'' cryptographic hash function takes two 32-byte hash values, concatenates these to produce a 64-byte buffer, and applies a single run of the SHA-256 hash function with a custom 'initialization vector' (IV) and without message padding.
The result is a 32-byte 'midstate' which is the combined hash value and the label of the inner node.
The changed IV protects against path-length extension attacks (grinding to interpret a hash as both an inner node and a leaf).
fast-SHA256 is only defined for two 32-byte inputs.
@@ -241,16 +241,16 @@ Disallowing a node with two SKIP branches eliminates what would otherwise be a s
The number of hashing operations required to verify a proof is one less than the number of hashes (SKIP and VERIFY combined),
and is exactly equal to the number of inner nodes serialized as the beginning of the proof as N.
-The variable-length integer encoding has the property that serialized integers, sorted lexigraphically, will also be sorted numerically.
-Since the first serialized item is the number of inner nodes, sorting proofs lexigraphically has the effect of sorting the proofs by the amount of work required to verify.
+The variable-length integer encoding has the property that serialized integers, sorted lexicographically, will also be sorted numerically.
+Since the first serialized item is the number of inner nodes, sorting proofs lexicographically has the effect of sorting the proofs by the amount of work required to verify.
The number of hashes required as input for verification of a proof is N+1 minus the number of SKIP hashes,
and can be quickly calculated without parsing the tree structure.
-The coding and packing rules for the serialized tree structure were also chosen to make lexigraphical comparison useful (or at least not meaningless).
+The coding and packing rules for the serialized tree structure were also chosen to make lexicographical comparison useful (or at least not meaningless).
If we consider a fully-expanded tree (no SKIP hashes, all VERIFY) to be encoding a list of elements in the order traversed depth-first from left-to-right,
then we can extract proofs for subsets of the list by SKIP'ing the hashes of missing values and recursively pruning any resulting SKIP,SKIP nodes.
-Lexigraphically comparing the resulting serialized tree structures is the same as lexigraphically comparing lists of indices from the original list verified by the derived proof.
+Lexicographically comparing the resulting serialized tree structures is the same as lexicographically comparing lists of indices from the original list verified by the derived proof.
Because the number of inner nodes and the number of SKIP hashes is extractible from the tree structure,
both variable-length integers in the proof are redundant and could have been omitted.
diff --git a/bip-0099.mediawiki b/bip-0099.mediawiki
index 8882e0036b..3638cb9165 100644
--- a/bip-0099.mediawiki
+++ b/bip-0099.mediawiki
@@ -23,7 +23,7 @@ not always well-understood, and the best upgrade mechanisms to the
consensus validation rules may vary depending on the type of change being deployed.
Discussing such changes without a uniform view on the deployment
paths often leads to misunderstandings and unnecessarily delays the
-deployment of changes.
+deployment of changes.
==Definitions==
@@ -43,7 +43,7 @@ deployment of changes.
: a theoretical piece of software that contains the specifications that define the validity of a block for a given state and chain parameters (ie it may act differently on, for example, regtest).
;Libbitcoinconsensus
-: the existing implementation is a library that is compiled by default with Bitcoin Core master and exposes a single C function named bitcoinconsensus_verify_script(). Although it has a deterministic build and implements the most complex rules (most of the cryptography, which is itself heavily based on libsecp256k1 after #REPLACE_libsecp256k1_PR), it is still not a complete specification of the consensus rules. Since libconsensus doesn't manage the current state but only the validation of the next block given that state, it is known that this long effort of encapsulation and decoupling will eventually finish, and that the person who moves the last line
+: the existing implementation is a library that is compiled by default with Bitcoin Core master and exposes a single C function named bitcoinconsensus_verify_script(). Although it has a deterministic build and implements the most complex rules (most of the cryptography, which is itself heavily based on libsecp256k1 after #REPLACE_libsecp256k1_PR), it is still not a complete specification of the consensus rules. Since libconsensus doesn't manage the current state but only the validation of the next block given that state, it is known that this long effort of encapsulation and decoupling will eventually finish, and that the person who moves the last line
==Taxonomy of consensus forks==
@@ -56,7 +56,7 @@ development, diversity, etc) to fork the Bitcoin Core software and it's good
that there's many alternative implementations of the protocol (forks
of Bitcoin Core or written from scratch).
-But sometimes a bug in the reimplementaion of the consensus
+But sometimes a bug in the reimplementation of the consensus
validation rules can prevent users of alternative implementation from
following the longest (most work) valid chain. This can result in
those users losing coins or being defrauded, making reimplementations
@@ -76,14 +76,14 @@ without burdening them with specific design choices made by Bitcoin
Core. It is to be noted that sharing the same code for consensus
validation doesn't prevent alternative implementations from
independently changing their consensus rules: they can always fork
-the libbitcoinconsensus project (once it is in a separate repository).
+the libbitcoinconsensus project (once it is in a separate repository).
Hopefully libbitcoinconsensus will remove this type of consensus fork
which - being accidental - obviously doesn't need a deployment plan.
====11/12 March 2013 Chain Fork====
-There is a precedent of an accidental consensus fork at height 225430.
+There is a precedent of an accidental consensus fork at height 225430.
Without entering into much detail (see [2]), the situation was different from
what's being described from the alternative implementation risks (today alternative implementation
still usually rely in different degrees on Bitcoin Core trusted proxies, which
@@ -104,7 +104,7 @@ rapidly by the whole worldwide community and nobody is unhappy about
the solution.
But there's some philosophical disagreements on the terms of what the
-solution was: we can add a pedantic note on that.
+solution was: we can add a pedantic note on that.
If "the implementation is the specification", then those
levelDB-specific limitations were part of the consensus rules.
Then additional rules were necessary and any alternative
@@ -113,7 +113,7 @@ planned consensus fork to migrate all Bitcoin-qt 0.7- users could
remove those additional consensus restrictions.
Had libconsensus being implemented without depending on levelDB,
those additional restrictions wouldn't have been part of "the specification"
- and this would just have been a bug in the
+and this would just have been a bug in the
consensus rules, just a consensus-critical bug in a set of
implementations, concretely all satoshi-bitcoin-0.7-or-less (which
happened to be a huge super majority of the users), but other
@@ -126,7 +126,7 @@ another consensus fork to remove them. Two theoretical consensus forks
instead of one but the first one deployed practically for free. The
practical result would have been identical and only the definitions
change. This means discussing something that went uncontroversially
-well further is "philosophical bike-shed" (TM).
+well further is "philosophical bike-shed" (TM).
===Unilateral softforks===
@@ -145,7 +145,7 @@ Fundamental disagreements and controversies are part of social
systems, like the one defined as the human participants in the Bitcoin
network. Without judging the motivation of the rule discrepancies or
what rules were in place first, we're defining schism[1] hardforks as
-those in which - for whatever reason - users are consiously going to validate 2
+those in which - for whatever reason - users are consciously going to validate 2
different sets of consensus rules. Since they will validate different
rulesets, they will end up following 2 different chains for at least
some time, maybe forever.
@@ -154,20 +154,20 @@ One possible result observed in the past[non_proportional_inflatacoin_fork]
is that one of the chains rapidly disappears, but nothing indicates
that this must always be the case.
-While 2 chains cohexist, they can be considered two different
+While 2 chains coexist, they can be considered two different
currencies.
We could say that bitcoin becomes bitcoinA and bitcoinB. The implications for market
-capitalization are completely unpredictable,
+capitalization are completely unpredictable,
-maybe mc(bitcoinA) = mc(bitcoinB) = mc(old_bitcoin),
+maybe mc(bitcoinA) = mc(bitcoinB) = mc(old_bitcoin),
-maybe mc(bitcoinA) + mc(bitcoinB) = mc(old_bitcoin),
+maybe mc(bitcoinA) + mc(bitcoinB) = mc(old_bitcoin),
maybe mc(bitcoinA) + mc(bitcoinB) = 1000 * mc(old_bitcoin),
maybe mc(bitcoinA) + mc(bitcoinB) = 0,
-...
+...
Schism hardforks have been compared to one type of altcoins called
"spinoffs"[spinoffs] that distribute all or part of its initial seigniorage to
@@ -224,7 +224,7 @@ Let's imagine BIP66 had a crypto backdoor
that nobody noticed and allows an evil developer cabal to steal
everyone's coins. The users and non-evil developers could join, fork
libconsensus and use the forked version in their respective bitcoin
-implementations.
+implementations.
Should miner's "vote" be required to express their consent? What if some miners
are part of the cabal? In the unlikely event that most miners are
part of such an evil cabal, changing the pow function may be
@@ -268,7 +268,7 @@ that's why the voting mechanism and first used for BIP30 and BIP66.
The current voting threshold for softfork enforcement is 95%. There's
also a 75% threshold for miners to activate it as a policy rule, but
it should be safe for miners to activate such a policy from the start
-or later than 75%, as long as they enforce it as consensus rule after 95%.
+or later than 75%, as long as they enforce it as consensus rule after 95%.
The current miners' voting mechanism can be modified to allow for
changes to be deployed in parallel, the rejection of a concrete
@@ -350,17 +350,17 @@ worth of blocks).
[3] https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki
-[4] https://github.com/bitcoin/bitcoin/compare/0.11...jtimon:hardfork-timewarp-0.11
+[4] https://github.com/jtimon/bitcoin/tree/hardfork-timewarp-0.11
[5] Original references:
https://bitcointalk.org/index.php?topic=114751.0
https://bitcointalk.org/index.php?topic=43692.msg521772#msg521772
-Rebased patch:
+Rebased patch:
https://github.com/freicoin/freicoin/commit/beb2fa54745180d755949470466cbffd1cd6ff14
==Attribution==
-Incorporated corrections and suggestions from: Andy Chase, Bryan Bishop,
+Incorporated corrections and suggestions from: Andy Chase, Bryan Bishop,
Btcdrak, Gavin Andresen, Gregory Sanders, Luke Dashjr, Marco Falke.
==Copyright==
diff --git a/bip-0104.mediawiki b/bip-0104.mediawiki
index 1244b3e420..4d81110af7 100644
--- a/bip-0104.mediawiki
+++ b/bip-0104.mediawiki
@@ -65,7 +65,7 @@ A hardcoded increase to max block size (2MB, 8MB, etc.), rejected because:
Allow miners to vote for max block size, rejected because:
* overly complex and political
* human involvement makes this slow to respond to changing transaction volumes
-* focuses power over max block size to a relatively small group of people
+* focuses power over max block size to a relatively small group of people
* unpredictable transaction fees caused by this would create uncertainty in the ecosystem
==Backward Compatibility==
diff --git a/bip-0105.mediawiki b/bip-0105.mediawiki
index 3643562ef8..af416910df 100644
--- a/bip-0105.mediawiki
+++ b/bip-0105.mediawiki
@@ -13,21 +13,21 @@
==Abstract==
-A method of altering the maximum allowed block size of the Bitcoin protocol
+A method of altering the maximum allowed block size of the Bitcoin protocol
using a consensus based approach.
==Motivation==
-There is a belief that Bitcoin cannot easily respond to raising the
-blocksize limit if popularity was to suddenly increase due to a mass adoption
-curve, because co-ordinating a hard fork takes considerable time, and being
-unable to respond in a timely manner would irreparably harm the credibility of
+There is a belief that Bitcoin cannot easily respond to raising the
+blocksize limit if popularity was to suddenly increase due to a mass adoption
+curve, because co-ordinating a hard fork takes considerable time, and being
+unable to respond in a timely manner would irreparably harm the credibility of
bitcoin.
Additionally, predetermined block size increases are problematic because they
-attempt to predict the future, and if too large could have unintended
-consequences like damaging the possibility for a fee market to develop
-as block subsidy decreases substantially over the next 9 years; introducing
+attempt to predict the future, and if too large could have unintended
+consequences like damaging the possibility for a fee market to develop
+as block subsidy decreases substantially over the next 9 years; introducing
or exacerbating mining attack vectors; or somehow affect the network in unknown
or unpredicted ways. Since fixed changes are hard to deploy, the damage could be
extensive.
@@ -36,14 +36,14 @@ Dynamic block size adjustments also suffer from the potential to be gamed by the
larger hash power.
Free voting as suggested by BIP100 allows miners to sell their votes out of band
-at no risk, and enable the sponsor the ability to manipulate the blocksize.
+at no risk, and enable the sponsor the ability to manipulate the blocksize.
It also provides a cost free method or the larger pools to vote in ways to
manipulate the blocksize such to disadvantage or attack smaller pools.
==Rationale==
-By introducing a cost to increase the block size ensures the mining community
+By introducing a cost to increase the block size ensures the mining community
will collude to increase it only when there is a clear necessity, and reduce it
when it is unnecessary. Larger miners cannot force their wishes so easily
because not only will they have to pay extra a difficulty target, then can be
@@ -63,7 +63,7 @@ honest.
The initial block size limit shall be 1MB.
Each time a miner creates a block, they may vote to increase or decrease the
-blocksize by a maximum of 10% of the current block size limit. These votes will
+blocksize by a maximum of 10% of the current block size limit. These votes will
be used to recalculate the new block size limit every 2016 blocks.
Votes are cast using the block's coinbase transaction scriptSig.
@@ -77,7 +77,7 @@ If a miner votes for an increase, the block hash must meet a difficulty target
which is proportionally larger than the standard difficulty target based on the
percentage increase they voted for.
-Votes proposing decreasing the block size limit do not need to meet a higher
+Votes proposing decreasing the block size limit do not need to meet a higher
difficulty target.
Miners can vote for no change by voting for the current block size.
diff --git a/bip-0106.mediawiki b/bip-0106.mediawiki
index 193d4cd8a6..84b04980f2 100644
--- a/bip-0106.mediawiki
+++ b/bip-0106.mediawiki
@@ -36,13 +36,13 @@ https://blockchain.info/charts/avg-block-size?timespan=all&showDataPoints=false&
Keep the same MaxBlockSize
===Proposal 2 : Depending on previous block size calculation and previous Tx fee collected by miners===
-
+
TotalBlockSizeInLastButOneDifficulty = Sum of all Block size of first 2008 blocks in last 2 difficulty period
TotalBlockSizeInLastDifficulty = Sum of all Block size of second 2008 blocks in last 2 difficulty period (This actually includes 8 blocks from last but one difficulty)
-
+
TotalTxFeeInLastButOneDifficulty = Sum of all Tx fees of first 2008 blocks in last 2 difficulty period
TotalTxFeeInLastDifficulty = Sum of all Tx fees of second 2008 blocks in last 2 difficulty period (This actually includes 8 blocks from last but one difficulty)
-
+
If ( ( (Sum of first 4016 block size in last 2 difficulty period)/4016 > 50% MaxBlockSize) AND (TotalTxFeeInLastDifficulty > TotalTxFeeInLastButOneDifficulty) AND (TotalBlockSizeInLastDifficulty > TotalBlockSizeInLastButOneDifficulty) )
MaxBlockSize = TotalBlockSizeInLastDifficulty * MaxBlockSize / TotalBlockSizeInLastButOneDifficulty
Else If ( ( (Sum of first 4016 block size in last 2 difficulty period)/4016 < 50% MaxBlockSize) AND (TotalTxFeeInLastDifficulty < TotalTxFeeInLastButOneDifficulty) AND (TotalBlockSizeInLastDifficulty < TotalBlockSizeInLastButOneDifficulty) )
diff --git a/bip-0107.mediawiki b/bip-0107.mediawiki
index b82db614f7..915657aa70 100644
--- a/bip-0107.mediawiki
+++ b/bip-0107.mediawiki
@@ -24,7 +24,7 @@ Over the next few years, large infrastructure investments will be made into:
# Layer 2 services and networks for off-chain transactions
# General efficiency improvements to transactions and the blockchain
-* While there is a consensus between Bitcoin developers, miners, businesses and users that the block size needs to be increased, there is a lingering concern over the potential unintended consequences that may augment the trend towards network and mining centralization (largely driven by mining hardware such as ASICs) and thereby threaten the security of the network.
+* While there is a consensus between Bitcoin developers, miners, businesses and users that the block size needs to be increased, there is a lingering concern over the potential unintended consequences that may augment the trend towards network and mining centralization (largely driven by mining hardware such as ASICs) and thereby threaten the security of the network.
* In contrast, failing to respond to elevated on-chain transaction volume may lead to a consumer-failure of Bitcoin, where ordinary users - having enjoyed over 6 years of submitting transactions on-chain at relatively low cost - will be priced out of blockchain with the emergence of a prohibitive 'fee market'.
* These two concerns must be delicately balanced so that all users can benefit from a robust, scalable, and neutral network.
@@ -40,7 +40,7 @@ Over the next few years, large infrastructure investments will be made into:
* '''Phase 2'''
** In 2020, the maximum block size will be increased dynamically according to sustained increases in transaction volume
** Every 4032 blocks (~4 weeks), a CHECK will be performed to determine if a raise in the maximum block size should occur
-*** This calculates to a theoretical maximum of 13 increases per year
+*** This calculates to a theoretical maximum of 13 increases per year
** IF of the last >= 3025 blocks were >=60% full, the maximum block size will be increased by 10%
** The maximum block size can only ever be increased, not decreased
* The default limitfreerelay will also be raised in proportion to maximum block size increases
@@ -49,8 +49,8 @@ Over the next few years, large infrastructure investments will be made into:
For example:
* When the dynamic rules for increasing the block size go live on January 1st 2020, the starting maximum block size will be 6 MB
-* IF >=3025 blocks are >= 3.6 MB, the new maximum block size become 6.6 MB.
-* The theoretical maximum block size at the end of 2020 would be ~20.7 MB, assuming all 13 increases are triggered every 4 weeks by the end of the year.
+* IF >=3025 blocks are >= 3.6 MB, the new maximum block size become 6.6 MB.
+* The theoretical maximum block size at the end of 2020 would be ~20.7 MB, assuming all 13 increases are triggered every 4 weeks by the end of the year.
==Rationale==
@@ -63,19 +63,19 @@ For example:
*** Setting the parameter too high may set the trigger sensitivity too low, causing transaction delays that are trying to be avoided in the first place
*** Between September 2013-2015, the standard deviation measured from average block size (n=730 data points from blockchain.info) was ~ 0.13 MB or 13% of the maximum block size
**** If blocks needed to be 90% full before an increase were triggered, normal variance in the average block size would mean some blocks would be full before an increase could be triggered
-*** Therefore, we need a ''safe distance'' away from the maximum block size to avoid normal block size variance hitting the limit. The 60% level represents a 3 standard deviation distance from the limit.
+*** Therefore, we need a ''safe distance'' away from the maximum block size to avoid normal block size variance hitting the limit. The 60% level represents a 3 standard deviation distance from the limit.
** Why 3025 blocks?
*** The assessment period is 4032 blocks or ~ 4 weeks, with the threshold set as 4032 blocks/0.75 + 1
*** Increases in the maximum block size should only occur after a sustained trend can be observed in order to:
***# Demonstrate a market-driven secular elevation in the transaction volume
-***# Increase the cost to trigger an increase by spam attacks or miner collusion with zero fee transactions
+***# Increase the cost to trigger an increase by spam attacks or miner collusion with zero fee transactions
*** In other words, increases to the maximum block size must be conservative but meaningful to relieve transaction volume pressure in response to true market demand
** Why 10% increase in the block size?
*** Increases in the block size are designed to be conservative and in balance with the number of theoretical opportunities to increase the block size per year
-*** Makes any resources spent for spam attacks or miner collusion relatively expensive to achieve a minor increase in the block size. A sustained attack would need to be launched that may be too costly, and ideally detectable by the community
+*** Makes any resources spent for spam attacks or miner collusion relatively expensive to achieve a minor increase in the block size. A sustained attack would need to be launched that may be too costly, and ideally detectable by the community
==Deployment==
-Similar deployment model to BIP101:
+Similar deployment model to BIP101:
Activation is achieved when 750 of 1,000 consecutive blocks in the best chain have a version number with the first, second, third, and thirtieth bits set (0x20000007 in hex). The activation time will be the timestamp of the 750'th block plus a two week (1,209,600 second) grace period to give any remaining miners or services time to upgrade to support larger blocks.
==Acknowledgements==
diff --git a/bip-0109.mediawiki b/bip-0109.mediawiki
index 69b265b1c9..ec1d7e5bc6 100644
--- a/bip-0109.mediawiki
+++ b/bip-0109.mediawiki
@@ -37,7 +37,7 @@ In particular:
* The coinbase scriptSig is not counted
* Signature operations in un-executed branches of a Script are not counted
-* OP_CHECKMULTISIG evaluations are counted accurately; if the signature for a 1-of-20 OP_CHECKMULTISIG is satisified by the public key nearest the top of the execution stack, it is counted as one signature operation. If it is satisfied by the public key nearest the bottom of the execution stack, it is counted as twenty signature operations.
+* OP_CHECKMULTISIG evaluations are counted accurately; if the signature for a 1-of-20 OP_CHECKMULTISIG is satisfied by the public key nearest the top of the execution stack, it is counted as one signature operation. If it is satisfied by the public key nearest the bottom of the execution stack, it is counted as twenty signature operations.
* Signature operations involving invalidly encoded signatures or public keys are not counted towards the limit
=== Add a new limit of 1,300,000,000 bytes hashed to compute transaction signatures per block ===
@@ -65,7 +65,7 @@ SPV (simple payment validation) wallets are compatible with this change.
==Rationale==
-In the short term, an increase is needed to handle increasing transaction volume.
+In the short term, an increase is needed to handle increasing transaction volume.
The limits on signature operations and amount of signature hashing done prevent possible CPU exhaustion attacks by "rogue miners" producing very expensive-to-validate two megabyte blocks. The signature hashing limit is chosen to be impossible to reach with any non-attack transaction or block, to minimize the impact on existing mining or wallet software.
diff --git a/bip-0112.mediawiki b/bip-0112.mediawiki
index f3d370a3f1..d3e4c2e671 100644
--- a/bip-0112.mediawiki
+++ b/bip-0112.mediawiki
@@ -36,7 +36,7 @@ When executed, if any of the following conditions are true, the script interpret
Otherwise, script execution will continue as if a NOP had been executed.
-BIP 68 prevents a non-final transaction from being selected for inclusion in a block until the corresponding input has reached the specified age, as measured in block-height or block-time. By comparing the argument to CHECKSEQUENCEVERIFY against the nSequence field, we indirectly verify a desired minimum age of the
+BIP 68 prevents a non-final transaction from being selected for inclusion in a block until the corresponding input has reached the specified age, as measured in block-height or block-time. By comparing the argument to CHECKSEQUENCEVERIFY against the nSequence field, we indirectly verify a desired minimum age of
the output being spent; until that relative age has been reached any script execution pathway including the CHECKSEQUENCEVERIFY will fail to validate, causing the transaction not to be selected for inclusion in a block.
@@ -69,13 +69,13 @@ address with the following redeemscript.
CHECKSIG
ENDIF
-At any time funds can be spent using signatures from any two of Alice,
+At any time funds can be spent using signatures from any two of Alice,
Bob or the Escrow.
After 30 days Alice can sign alone.
The clock does not start ticking until the payment to the escrow address
-confirms.
+confirms.
===Retroactive Invalidation===
@@ -214,7 +214,7 @@ final branch of above to ensure Bob cannot spend the output until after both
the timeout is complete and Alice has had time to reveal the revocation
secret.
-See the [https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf Deployable Lightning] paper.
+See the [https://github.com/ElementsProject/lightning/blob/master/doc/miscellaneous/deployable-lightning.pdf Deployable Lightning] paper.
====2-Way Pegged Sidechains====
@@ -230,7 +230,7 @@ The 2-way pegged sidechain requires a new REORGPROOFVERIFY opcode, the semantics
==Specification==
-Refer to the reference implementation, reproduced below, for the precise
+Refer to the reference implementation, reproduced below, for the precise
semantics and detailed rationale for those semantics.
@@ -247,7 +247,7 @@ static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
/* If CTxIn::nSequence encodes a relative lock-time, this mask is
* applied to extract that lock-time from the sequence field. */
static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
-
+
case OP_NOP3:
{
if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
@@ -290,7 +290,7 @@ case OP_NOP3:
break;
}
-
+
bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const
{
// Relative lock times are supported by comparing the passed
@@ -382,13 +382,13 @@ Thanks to Eric Lombrozo and Anthony Towns for contributing example use cases.
[http://lightning.network/lightning-network-paper.pdf Lightning Network]
-[https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf Deployable Lightning]
+[https://github.com/ElementsProject/lightning/blob/master/doc/miscellaneous/deployable-lightning.pdf Deployable Lightning]
[http://diyhpl.us/diyhpluswiki/transcripts/sf-bitcoin-meetup/2015-02-23-scaling-bitcoin-to-billions-of-transactions-per-day/ Scaling Bitcoin to Billions of Transactions Per Day]
[http://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-August/010396.html Softfork deployment considerations]
-[https://gist.github.com/sipa/bf69659f43e763540550 Version bits]
+[https://web.archive.org/web/20210925124425/https://gist.github.com/sipa/bf69659f43e763540550 Version bits]
[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2013-April/002433.html Jeremy Spilman Micropayment Channels]
diff --git a/bip-0113.mediawiki b/bip-0113.mediawiki
index 368677715b..d736280931 100644
--- a/bip-0113.mediawiki
+++ b/bip-0113.mediawiki
@@ -45,13 +45,13 @@ BIP68 (sequence numbers) and BIP112 (CHECKSEQUENCEVERIFY).
==Specification==
-The values for transaction locktime remain unchanged. The difference is only in
-the calculation determining whether a transaction can be included. Instead of
-an unreliable timestamp, the following function is used to determine the current
+The values for transaction locktime remain unchanged. The difference is only in
+the calculation determining whether a transaction can be included. Instead of
+an unreliable timestamp, the following function is used to determine the current
block time for the purpose of checking lock-time constraints:
enum { nMedianTimeSpan=11 };
-
+
int64_t GetMedianTimePast(const CBlockIndex* pindex)
{
int64_t pmedian[nMedianTimeSpan];
diff --git a/bip-0114.mediawiki b/bip-0114.mediawiki
index 410e84ccfd..5b0713747e 100644
--- a/bip-0114.mediawiki
+++ b/bip-0114.mediawiki
@@ -111,7 +111,7 @@ The advantages of the current proposal are:
* If different parties in a contract do not want to expose their scripts to each other, they may provide only H(Subscript) and keep the Subscript private until redemption.
* If they are willing to share the actual scripts, they may combine them into one Subscript for each branch, saving some nOpCount and a few bytes of witness space.
-The are some disadvantages, but only when the redemption condition is very complicated:
+There are some disadvantages, but only when the redemption condition is very complicated:
* It may require more branches than a general MAST design (as shown in the previous example) and take more witness space in redemption
* Creation and storage of the MAST structure may take more time and space. However, such additional costs affect only the related parties in the contract but not any other Bitcoin users.
diff --git a/bip-0115.mediawiki b/bip-0115.mediawiki
index 8bc90f6949..042d0570ec 100644
--- a/bip-0115.mediawiki
+++ b/bip-0115.mediawiki
@@ -98,7 +98,7 @@ What if ParamBlockHash has leading zeros? Should this be prevented?
* If leading zeros are included, they should be compared to the actual block hash. (If they were truncated, fewer bytes would be compared.)
* It is unlikely that the leading zeros will ever be necessary for sufficient precision, so the additional space is not a concern.
-* Since all block hashes are in principle shorter than than 29 bytes, ParamBlockHash may not be larger than 28 bytes.
+* Since all block hashes are in principle shorter than 29 bytes, ParamBlockHash may not be larger than 28 bytes.
Why is it safe to allow checking blocks as recently as the immediate previous block?
diff --git a/bip-0116.mediawiki b/bip-0116.mediawiki
index 86b0f9aaae..c6e13465cc 100644
--- a/bip-0116.mediawiki
+++ b/bip-0116.mediawiki
@@ -17,7 +17,7 @@
==Abstract==
A general approach to bitcoin contracts is to fully enumerate the possible spending conditions and then program verification of these conditions into a single script.
-At redemption, the spending condition used is explicitly selected, e.g. by pushing a value on the witness stack which cascades through a series if if/else constructs.
+At redemption, the spending condition used is explicitly selected, e.g. by pushing a value on the witness stack that cascades through a series of if/else constructs.
This approach has significant downsides, such as requiring all program pathways to be visible in the scriptPubKey or redeem script, even those which are not used at validation.
This wastes space on the block chain, restricts the size of possible scripts due to push limits, and impacts both privacy and fungibility as details of the contract can often be specific to the user.
@@ -59,7 +59,7 @@ This includes execution pathways or policy conditions which end up not being nee
Not only is it inefficient to require this unnecessary information to be present on the blockchain, albeit in the witness, it also impacts privacy and fungibility as some unused script policies may be identifying.
Using a Merkle hash tree to commit to the policy options, and then only forcing revelation of the policy used at redemption minimizes this information leakage.
-Using Merkle hash trees to commit to policy allows for considerably more complex contracts than would would otherwise be possible, due to various built-in script size and runtime limitations.
+Using Merkle hash trees to commit to policy allows for considerably more complex contracts than would otherwise be possible, due to various built-in script size and runtime limitations.
With Merkle commitments to policy these size and runtime limitations constrain the complexity of any one policy that can be used rather than the sum of all possible policies.
==Rationale==
@@ -67,7 +67,7 @@ With Merkle commitments to policy these size and runtime limitations constrain t
The MERKLEBRANCHVERIFY opcode uses fast Merkle hash trees as specified by BIP98[1] rather than the construct used by Satoshi for committing transactions to the block header as the later has a known vulnerability relating to duplicate entries that introduces a source of malleability to downstream protocols[4].
A source of malleability in Merkle proofs could potentially lead to spend vulnerabilities in protocols that use MERKLEBRANCHVERIFY.
For example, a compact 2-of-N policy could be written by using MERKLEBRANCHVERIFY to prove that two keys are extracted from the same tree, one at a time, then checking the proofs for bitwise equality to make sure the same entry wasn't used twice.
-With the vulnerable Merkle tree implementation there are privledged positions in unbalanced Merkle trees that allow multiple proofs to be constructed for the same, single entry.
+With the vulnerable Merkle tree implementation there are privileged positions in unbalanced Merkle trees that allow multiple proofs to be constructed for the same, single entry.
BIP141 (Segregated Witness)[3] provides support for a powerful form of script upgrades called script versioning, which is able to achieve the sort of upgrades which would previously have been hard-forks.
If script versioning were used for deployment then MERKLEBRANCHVERIFY could be written to consume its inputs, which would provide a small 2-byte savings for many anticipated use cases.
diff --git a/bip-0118.mediawiki b/bip-0118.mediawiki
index a3a690bb18..09d63a5be9 100644
--- a/bip-0118.mediawiki
+++ b/bip-0118.mediawiki
@@ -73,7 +73,7 @@ To convert a 33-byte BIP 118 public key for use with [[bip-0340.mediawiki|BIP 34
==== Signature message ====
-The function ''SigMsg118(hash_type, ext_flag)'' computes the message being signed as a byte array, analogously to ''SigMsg(hash_type, ext_flag)'' defined in [[bip-0341.mediawiki|BIP 341]], ''SigExt118(hash_type,key_version)'' computes the extension, similarly to [[bip-0342.mediawiki|BIP 342]].
+We define the functions ''Msg118(hash_type)'' and ''Ext118(hash_type)'' which compute the message being signed as a byte array.
The parameter ''hash_type'' is an 8-bit unsigned value, reusing values defined in [[bip-0341.mediawiki|BIP 341]], with the addition that the values 0x41, 0x42, 0x43, 0xc1, 0xc2, and 0xc3 are also valid for BIP 118 public keys.
@@ -82,64 +82,56 @@ We define the following constants using bits 6 and 7 of hash_type:
* SIGHASH_ANYPREVOUT = 0x40
* SIGHASH_ANYPREVOUTANYSCRIPT = 0xc0
-As per [[bip-0341.mediawiki|BIP 341]], the parameter ''ext_flag'' is an integer in the range 0-127, used for indicating that extensions are added at the end of the message. The parameter ''key_version'' is an 8-bit unsigned value (an integer in the range 0-255) used for committing to the public key version.
-
The following restrictions apply and cause validation failure if violated:
* Using any undefined ''hash_type'' (not ''0x00'', ''0x01'', ''0x02'', ''0x03'', ''0x41'', ''0x42'', ''0x43'', ''0x81'', ''0x82'', ''0x83'', ''0xc1'', ''0xc2'', or ''0xc3'').
* Using SIGHASH_SINGLE without a "corresponding output" (an output with the same index as the input being verified).
-If these restrictions aren't violated, ''SigMsg118(hash_type,ext_flag)'' evaluates to the concatenation of the following data, in order (with byte size of each item listed in parentheses). Numerical values in 2, 4, or 8-byte items are encoded in little-endian.
+If these restrictions are not violated, ''Msg118(hash_type)'' evaluates as follows.
+
+If ''hash_type & 0x40 == 0'', then ''Msg118(hash_type) = SigMsg(hash_type, 1)'', where ''SigMsg'' is as defined in [[bip-0341.mediawiki|BIP 341]].
+
+If ''hash_type & 0x40 != 0'', then ''Msg118(hash_type)'' is the concatenation of the following data, in order (with byte size of each item listed in parentheses). Numerical values in 2, 4, or 8-byte items are encoded in little-endian.
* Control:
** ''hash_type'' (1).
* Transaction data:
** ''nVersion'' (4): the ''nVersion'' of the transaction.
** ''nLockTime'' (4): the ''nLockTime'' of the transaction.
-** If ''hash_type & 0xc0'' is zero:
-*** ''sha_prevouts'' (32): the SHA256 of the serialization of all input outpoints.
-*** ''sha_amounts'' (32): the SHA256 of the serialization of all spent output amounts.
-*** ''sha_scriptpubkeys'' (32): the SHA256 of the serialization of all spent output ''scriptPubKey''s.
-*** ''sha_sequences'' (32): the SHA256 of the serialization of all input ''nSequence''.
** If ''hash_type & 3'' does not equal SIGHASH_NONE or SIGHASH_SINGLE:
*** ''sha_outputs'' (32): the SHA256 of the serialization of all outputs in CTxOut format.
* Data about this input:
-** ''spend_type'' (1): equal to ''(ext_flag * 2) + annex_present'', where ''annex_present'' is 0 if no annex is present, or 1 otherwise (the original witness stack has two or more witness elements, and the first byte of the last element is ''0x50'')
-** If ''hash_type & 0xc0'' is non-zero:
-*** If ''hash_type & 0xc0'' is SIGHASH_ANYONECANPAY:
-**** ''outpoint'' (36): the COutPoint of this input (32-byte hash + 4-byte little-endian).
-*** If ''hash_type & 0xc0'' is SIGHASH_ANYONECANPAY or SIGHASH_ANYPREVOUT:
-**** ''amount'' (8): value of the previous output spent by this input.
-**** ''scriptPubKey'' (35): ''scriptPubKey'' of the previous output spent by this input, serialized as script inside CTxOut. Its size is always 35 bytes.
-*** ''nSequence'' (4): ''nSequence'' of this input.
-** If ''hash_type & 0xc0'' is zero:
-*** ''input_index'' (4): index of this input in the transaction input vector. Index of the first input is 0.
+** ''spend_type'' (1): equal to 2 if no annex is present, or 3 otherwise (the original witness stack has two or more witness elements, and the first byte of the last element is ''0x50'')
+** If ''hash_type & 0xc0'' is SIGHASH_ANYPREVOUT:
+*** ''amount'' (8): value of the previous output spent by this input.
+*** ''scriptPubKey'' (35): ''scriptPubKey'' of the previous output spent by this input, serialized as script inside CTxOut. Its size is always 35 bytes.
+** ''nSequence'' (4): ''nSequence'' of this input.
** If an annex is present (the lowest bit of ''spend_type'' is set):
*** ''sha_annex'' (32): the SHA256 of ''(compact_size(size of annex) || annex)'', where ''annex'' includes the mandatory ''0x50'' prefix.
* Data about this output:
** If ''hash_type & 3'' equals SIGHASH_SINGLE:
*** ''sha_single_output'' (32): the SHA256 of the corresponding output in CTxOut format.
-Similarly, ''SigExt118(hash_type,key_version)'' evaluates to the concatenation of:
+Similarly, ''Ext118(hash_type)'' evaluates to the concatenation of the following data, in order:
* Extension:
** If ''hash_type & 0xc0'' is not SIGHASH_ANYPREVOUTANYSCRIPT:
*** ''tapleaf_hash'' (32): the tapleaf hash as defined in [[bip-0341.mediawiki|BIP 341]]
-** ''key_version'' (1).
+** ''key_version'' (1): a constant value ''0x01'' representing that this is a signature for a BIP 118 public key.
** ''codesep_pos'' (4): the opcode position of the last executed OP_CODESEPARATOR before the currently executed signature opcode, with the value in little endian (or ''0xffffffff'' if none executed). The first opcode in a script has a position of 0. A multi-byte push opcode is counted as one opcode, regardless of the size of data being pushed.
-Note that if ''hash_type & 0x40'' is zero, ''SigMsg118(hash_type,ext_flag) == SigMsg(hash_type,ext_flag)'', and ''SigExt118(hash_type,0x00) == ext'' (where ''ext'' is the message extension as defined in [[bip-0342.mediawiki|BIP 342]]).
-
To verify a signature ''sig'' for a BIP 118 public key ''p'':
-* If the ''sig'' is 64 bytes long, return ''Verify(p, hashTapSigHash(0x00 || SigMsg118(0x00, 1) || SigExt118(0x00, 0x01), sig)'', where ''Verify'' is defined in [[bip-0340.mediawiki|BIP 340]].
-* If the ''sig'' is 65 bytes long, return ''sig[64] ≠ 0x00 and Verify(p, hashTapSighash(0x00 || SigMsg118(sig[64], 1) || SigExt118(sig[64], 0x01), sig[0:64])''.
+* If the ''sig'' is 64 bytes long, return ''Verify(p, hashTapSigHash(0x00 || Msg118(0x00) || Ext118(0x00)), sig)''
+* If the ''sig'' is 65 bytes long, return ''sig[64] ≠ 0x00 and Verify(p, hashTapSighash(0x00 || Msg118(sig[64]) || Ext118(sig[64])), sig[0:64])''.
* Otherwise, fail.
+''Verify'' is as defined in [[bip-0340.mediawiki|BIP 340]].
+
The key differences from [[bip-0342.mediawiki|BIP 342]] signature verification are:
* In all cases, key_version is set to the constant value 0x01 instead of 0x00.'''Why change key_version?''' Changing key_version ensures that if the same private key is used to generate both a [[bip-0342.mediawiki|BIP 342]] key and a BIP 118 public key, that a signature for the [[bip-0342.mediawiki|BIP 342]] key is not also valid for the BIP 118 public key (and vice-versa).
* If SIGHASH_ANYPREVOUT is set, the digest is calculated as if SIGHASH_ANYONECANPAY was set, except outpoint is not included in the digest.
-* If SIGHASH_ANYPREVOUTANYSCRIPT is set, the digest is calculated as if SIGHASH_ANYONECANPAY was set, except outpoint, scriptPubKey and tapleaf_hash are not included in the digest.
+* If SIGHASH_ANYPREVOUTANYSCRIPT is set, the digest is calculated as if SIGHASH_ANYONECANPAY was set, except outpoint, amount, scriptPubKey and tapleaf_hash are not included in the digest.
== Security ==
@@ -150,7 +142,7 @@ By design, SIGHASH_ANYPREVOUT and SIGHASH_ANYPREVOUTANYSCRIPT
Both SIGHASH_ALL and SIGHASH_ANYONECANPAY signatures prevent signature replay by committing to one or more inputs, so replay of the signature is only possible if the same input can be spent multiple times, which is not possible on the Bitcoin blockchain (due to enforcement of [[bip-0030.mediawiki|BIP 30]]).
With SIGHASH_ANYPREVOUT signature replay is possible for different UTXOs with the same scriptPubKey and the same value, while with SIGHASH_ANYPREVOUTANYSCRIPT signature replay is possible for any UTXOs that reuse the same BIP 118 public key in one of their potential scripts.
-As a consequence, implementors MUST ensure that BIP 118 public keys are only reused when signature replay cannot cause loss of funds (eg due to other features of the protocol or other constraints on the transaction), or when such a loss of funds is acceptable.
+As a consequence, implementers MUST ensure that BIP 118 public keys are only reused when signature replay cannot cause loss of funds (eg due to other features of the protocol or other constraints on the transaction), or when such a loss of funds is acceptable.
==== Malleability ====
diff --git a/bip-0119.mediawiki b/bip-0119.mediawiki
index 730ffb932d..2908fad4fa 100644
--- a/bip-0119.mediawiki
+++ b/bip-0119.mediawiki
@@ -15,10 +15,6 @@
This BIP proposes a new opcode, OP_CHECKTEMPLATEVERIFY, to be activated
as a change to the semantics of OP_NOP4.
-The new opcode has applications for transaction congestion control and payment
-channel instantiation, among others, which are described in the Motivation
-section of this BIP.
-
==Summary==
OP_CHECKTEMPLATEVERIFY uses opcode OP_NOP4 (0xb3) as a soft fork upgrade.
@@ -27,9 +23,9 @@ OP_CHECKTEMPLATEVERIFY does the following:
* There is at least one element on the stack, fail otherwise
* The element on the stack is 32 bytes long, NOP otherwise
-* The StandardTemplateHash of the transaction at the current input index is equal to the element on the stack, fail otherwise
+* The DefaultCheckTemplateVerifyHash of the transaction at the current input index is equal to the element on the stack, fail otherwise
-The StandardTemplateHash commits to the serialized version, locktime, scriptSigs hash (if any
+The DefaultCheckTemplateVerifyHash commits to the serialized version, locktime, scriptSigs hash (if any
non-null scriptSigs), number of inputs, sequences hash, number of outputs, outputs hash, and
currently executing input index.
@@ -39,216 +35,185 @@ The recommended standardness rules additionally:
==Motivation==
-Covenants are restrictions on how a coin may be spent beyond key ownership. Covenants can be useful
-to construct smart contracts. As covenants are complex to implement and risk of introducing
-fungibility discriminants they have not been seriously considered for inclusion in Bitcoin.
-
-This BIP introduces a simple covenant called a *template* which enables a limited set of highly
-valuable use cases without significant risk.
-
-A few examples are described below, which should be the subject of future non-consensus
-standardization efforts.
-
-===Congestion Controlled Transactions===
-
-When there is a high demand for blockspace it becomes very expensive to make transactions. A large
-volume payment processor may aggregate all their payments into a single O(1) transaction commitment
-for purposes of confirmation using CHECKTEMPLATEVERIFY. Then, some time later, the payments can
-be expanded out of that UTXO when the demand for blockspace is decreased. These payments can be
-structured in a tree-like fashion to reduce individual costs of redemption.
-
-
-The below chart showcases the structure of these transactions in comparison to
-normal transactions and batched transactions.
-
-
-
-A simulation is shown below of what impact this could have on mempool backlog
-given 5% network adoption, and 50% network adoption. The code for the simulation
-is provided in this BIP's subdirectory.
-
-
-
-
-===Payment Channels===
-There are numerous payment channel related uses.
-
-====Channel Factories====
-
-Using CHECKTEMPLATEVERIFY for Channel Factories is similar to the use for Congestion Control,
-except the leaf node transactions are channels instead of plain payments. The channel can be between
-the sender and recipient or a target of recipient's choice. Using an CHECKTEMPLATEVERIFY, the
-recipient may give the sender an address which makes a tree of channels unbeknownst to them.
-These channels are time insensitive for setup, as all punishments are relative timelocked to the
-penultimate transaction node.
-Thus, coins sent using a congestion controlled transaction can still enjoy instant liquidity.
-
-====Non-Interactive Channels====
-When opening a traditional payment channel, both parties to the channel must participate. This is
-because the channel uses pre-signed multi-sig transactions to ensure that a channel can always be
-exited by either party, before entering.
-With CHECKTEMPLATEVERIFY, it’s possible for a single party to construct a channel which either
-party can exit from without requiring signatures from both parties.
-These payment channels can operate in one direction, paying to the channel "listener" without need
-for their private key to be online.
-
-
-====Increased Channel Routes====
-In the Lightning Network protocol, Hashed Time Locked Contracts (HTLCS) are used in the construction
-of channels. A new HTLC is required per route that the channel is serving in.
-In BOLT #2, this maximum number of HTLCs in a channel is hard limited to 483 as the maximum safe
-size to prevent the transaction from being too large to be valid. In common software implementations
-such as LND, this limit is set much lower to 12 HTLCS. This is because accepting a larger number of
-HTLCS makes it more difficult for transactions to confirm during congested periods as they must pay
-higher fees.
-Therefore, similarly to how congestion control is handled for normal transaction, lightning channel
-updates can be done across an CHECKTEMPLATEVERIFY tree, allowing nodes to safely use many more
-HTLCS.
-Because each HTLC can have its own relative time lock in the tree, this also improves the latency
-sensitivity of the lightning protocol on contested channel close.
-
-
-===Wallet Vaults===
-
-When greater security is required for cold storage solutions, there can be
-default script paths that move funds from one target to another target.
-For example, a cold wallet can be set up where one customer support desk can,
-without further authorization, move a portion of the funds (using multiple
-pre-set amounts) into a lukewarm wallet operated by an isolated support desk.
-The support desk can then issue some funds to a hot wallet, and send the
-remainder back to cold storage with a similar withdrawal mechanism in place.
-This is all possible without CHECKTEMPLATEVERIFY, but CHECKTEMPLATEVERIFY
-eliminates the need for coordination and online signers, as well as reducing the
-ability for a support desk to improperly move funds.
-Furthermore, all such designs can be combined with relative time locks to give
-time for compliance and risk desks to intervene.
-
-
-
-===CoinJoin===
-
-CHECKTEMPLATEVERIFY makes it much easier to set up trustless CoinJoins than previously because
-participants agree on a single output which pays all participants, which will be lower fee than
-before. Further Each participant doesn't need to know the totality of the outputs committed to by
-that output, they only have to verify their own sub-tree will pay them.
+This BIP introduces a transaction template, a simple spending restriction that
+pattern matches a transaction against a hashed transaction specification.
+OP_CHECKTEMPLATEVERIFY reduces many of the trust, interactivity, and storage
+requirements inherent with the use of pre-signing in applications.
+For more details on applications, please see the references.
+
==Detailed Specification==
-The below code is the main logic for verifying CHECKTEMPLATEVERIFY, and is the canonical
-specification for the semantics of OP_CHECKTEMPLATEVERIFY.
-
- case OP_CHECKTEMPLATEVERIFY:
- {
- // if flags not enabled; treat as a NOP4
- if (!(flags & SCRIPT_VERIFY_STANDARD_TEMPLATE)) break;
- if (stack.size() < 1)
- return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
- // If the argument was not 32 bytes, treat as OP_NOP4:
- switch (stack.back().size()) {
- case 32:
- if (!checker.CheckStandardTemplateHash(stack.back())) {
- return set_error(serror, SCRIPT_ERR_TEMPLATE_MISMATCH);
- }
- break;
- default:
- // future upgrade can add semantics for this opcode with different length args
- // so discourage use when applicable
- if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
- return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
- }
- }
- }
- break;
-
-The hash is computed as follows:
-
- uint256 GetStandardTemplateHash(const CTransaction& tx, uint32_t input_index) {
- return GetStandardTemplateHash(tx, GetOutputsSHA256(tx), GetSequenceSHA256(tx), input_index);
- }
- uint256 GetStandardTemplateHash(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
- const uint32_t input_index) {
- bool skip_scriptSigs = std::find_if(tx.vin.begin(), tx.vin.end(),
- [](const CTxIn& c) { return c.scriptSig != CScript(); }) == tx.vin.end();
- return skip_scriptSigs ? GetStandardTemplateHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) :
- GetStandardTemplateHashWithScript(tx, outputs_hash, sequences_hash, GetScriptSigsSHA256(tx), input_index);
- }
- uint256 GetStandardTemplateHashWithScript(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
- const uint256& scriptSig_hash, const uint32_t input_index) {
- auto h = CHashWriter(SER_GETHASH, 0)
- << tx.nVersion
- << tx.nLockTime
- << scriptSig_hash
- << uint32_t(tx.vin.size())
- << sequences_hash
- << uint32_t(tx.vout.size())
- << outputs_hash
- << input_index;
- return h.GetSHA256();
- }
- uint256 GetStandardTemplateHashEmptyScript(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
- const uint32_t input_index) {
- auto h = CHashWriter(SER_GETHASH, 0)
- << tx.nVersion
- << tx.nLockTime
- << uint32_t(tx.vin.size())
- << sequences_hash
- << uint32_t(tx.vout.size())
- << outputs_hash
- << input_index;
- return h.GetSHA256();
- }
-
-
-A PayToBasicStandardTemplate output matches the following template:
-
- bool CScript::IsPayToBasicStandardTemplate() const
- {
- // Extra-fast test for pay-to-basic-standard-template CScripts:
- return (this->size() == 34 &&
- (*this)[0] == 0x20 &&
- (*this)[33] == OP_CHECKTEMPLATEVERIFY);
- }
-==Deployment==
+The below code is the main logic for verifying CHECKTEMPLATEVERIFY, described
+in pythonic pseudocode. The canonical specification for the semantics of
+OP_CHECKTEMPLATEVERIFY as implemented in C++ in the context of Bitcoin Core can
+be seen in the reference implementation.
+
+The execution of the opcode is as follows:
+
+def execute_bip_119(self):
+ # Before soft-fork activation / failed activation
+ # continue to treat as NOP4
+ if not self.flags.script_verify_default_check_template_verify_hash:
+ # Potentially set for node-local policy to discourage premature use
+ if self.flags.script_verify_discourage_upgradable_nops:
+ return self.errors_with(errors.script_err_discourage_upgradable_nops)
+ return self.return_as_nop()
+
+ # CTV always requires at least one stack argument
+ if len(self.stack) < 1:
+ return self.errors_with(errors.script_err_invalid_stack_operation)
+
+ # CTV only verifies the hash against a 32 byte argument
+ if len(self.stack[-1]) == 32:
+ # Ensure the precomputed data required for anti-DoS is available,
+ # or cache it on first use
+ if self.context.precomputed_ctv_data == None:
+ self.context.precomputed_ctv_data = self.context.tx.get_default_check_template_precomputed_data()
+
+ # If the hashes do not match, return error
+ if stack[-1] != self.context.tx.get_default_check_template_hash(self.context.nIn, self.context.precomputed_ctv_data):
+ return self.errors_with(errors.script_err_template_mismatch)
+
+ return self.return_as_nop()
+
+ # future upgrade can add semantics for this opcode with different length args
+ # so discourage use when applicable
+ if self.flags.script_verify_discourage_upgradable_nops:
+ return self.errors_with(errors.script_err_discourage_upgradable_nops)
+ else:
+ return self.return_as_nop()
+
+
+The computation of this hash can be implemented as specified below (where self
+is the transaction type). Care must be taken that in any validation context,
+the precomputed data must be initialized to prevent Denial-of-Service attacks.
+Any implementation *must* cache these parts of the hash computation to avoid
+quadratic hashing DoS. All variable length computations must be precomputed
+including hashes of the scriptsigs, sequences, and outputs. See the section
+"Denial of Service and Validation Costs" below. This is not a performance
+optimization.
+
+
+
+def ser_compact_size(l):
+ r = b""
+ if l < 253:
+ # Serialize as unsigned char
+ r = struct.pack("B", l)
+ elif l < 0x10000:
+ # Serialize as unsigned char 253 followed by unsigned 2 byte integer (little endian)
+ r = struct.pack("
+
+
+A PayToBareDefaultCheckTemplateVerifyHash output matches the following template:
+
+
+# Extra-fast test for pay-to-basic-standard-template CScripts:
+def is_pay_to_bare_default_check_template_verify_hash(self):
+ return len(self) == 34 and self[0] == 0x20 and self[-1] == OP_CHECKTEMPLATEVERIFY
+
+
-Deployment should be done via BIP 9 VersionBits.
+==Deployment==
-The start time and bit in the implementation are currently set to bit 5 and
-March 1st, 2020, but this is subject to change while the BIP is a draft.
+Activation logic is elided from this BIP and is more appropriately discussed elsewhere.
-For the avoidance of unclarity, the parameters are:
+Until BIP-119 reaches ACTIVE state and the
+SCRIPT_VERIFY_DEFAULT_CHECK_TEMPLATE_VERIFY_HASH flag is enforced, node implementations should (are recommended to)
+execute a NOP4 as SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS (to deny entry to the mempool) for policy and must evaluate as
+a NOP for consensus (during block validation).
- consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY].bit = 5;
- consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY].nStartTime = 1583020800; // March 1, 2020
- consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY].nTimeout = 1614556800; // March 1, 2021
+In order to facilitate using CHECKTEMPLATEVERIFY, the common case of a
+PayToBareDefaultCheckTemplateVerifyHash
+with no scriptSig data may (is recommended to) be made standard to permit relaying. Future bare scripts may be
+standardized later as policy changes at the preference of the implementer.
-In order to facilitate using CHECKTEMPLATEVERIFY, the common case of a PayToBasicStandardTemplate
-with no scriptSig data shall be made standard to permit relaying. Future template types may be
-standardized later as policy changes.
==Reference Implementation==
-A reference implementation and tests are available here:
-https://github.com/JeremyRubin/bitcoin/tree/checktemplateverify.
+A reference implementation and tests are available here in the PR to Bitcoin Core https://github.com/bitcoin/bitcoin/pull/21702.
+It is not ideal to link to a PR, as it may be rebased and changed, but it is the best place to find
+the current implementation and review comments of others.
+A recent commit hash in that PR including tests and vectors can be found here https://github.com/jeremyrubin/bitcoin/commit/3109df5616796282786706738994a5b97b8a5a38.
+Once the PR is merged, this BIP should be updated to point to the specific code released.
-==Rationale==
+Test vectors are available in [/bip-0119/vectors the bip-0119/vectors
+directory] for checking compatibility with the reference implementation and BIP.
-The goal of CHECKTEMPLATEVERIFY is to be minimal impact on the existing codebase -- in the
-future, as we become aware of more complex but shown to be safe use cases new template types can be added.
+==Rationale==
+OP_CHECKTEMPLATEVERIFY's design is a small code change and simple to analyze. It is
+compatible with future upgrades if new template types are required
+for more complex but demonstrably safe use cases.
Below we'll discuss the rules one-by-one:
-
-
-====The StandardTemplateHash of the transaction at the current input index matches the top of the stack====
+====The DefaultCheckTemplateVerifyHash of the transaction at the current input index matches the top of the stack====
The set of data committed to is a superset of data which can impact the TXID of the transaction,
other than the inputs. This ensures that for a given known input, the TXIDs can also be known ahead
-of time. Otherwise, CHECKTEMPLATEVERIFY would not be usable for Channel Factory type constructions
-as the redemption TXID could be malleated and pre-signed transactions invalidated.
-
-
+of time. Otherwise, CHECKTEMPLATEVERIFY would not be usable for Batched Channel Creation constructions
+as the redemption TXID could be malleated and pre-signed transactions invalidated, unless the channels
+are built using an LN-Symmetry-like protocol. Note that there may be other types of pre-signed contracts that
+may or may not be able to use LN-Symmetry-like constructs, therefore making TXIDs predictable makes CTV more
+composable with arbitrary sub-protocols.
=====Committing to the version and locktime=====
@@ -256,7 +221,7 @@ Were these values not committed, it would be possible to delay the spending of
an output arbitrarily as well as possible to change the TXID.
Committing these values, rather than restricting them to specific values, is
-more flexible as it permits users of CHECKTEMPLATEVERIFY the set the version and
+more flexible as it permits users of CHECKTEMPLATEVERIFY to set the version and
locktime as they please.
=====Committing to the ScriptSigs Hash=====
@@ -264,7 +229,7 @@ locktime as they please.
The scriptsig in a segwit transaction must be exactly empty, unless it is a P2SH
segwit transaction in which case it must be only the exact redeemscript. P2SH is incompatible
(unless the P2SH hash is broken) with CHECKTEMPLATEVERIFY because the template hash must commit
-to the ScriptSig, which must contain the redeemscript, which is a hash cycle.
+to the ScriptSig, which must contain the redeemscript, which is a hash cycle.
To prevent malleability when not using a segwit input, we also commit to the
scriptsig. This makes it possible to use a 2 input CHECKTEMPLATEVERIFY with a legacy pre-signed
@@ -272,16 +237,15 @@ spend, as long as the exact scriptsig for the legacy output is committed. This i
simply disallowing any scriptSig to be set with CHECKTEMPLATEVERIFY.
If no scriptSigs are set in the transaction, there is no purpose in hashing the data or including it
-in the StandardTemplateHash, so we elide it. It is expected to be common that no scriptSigs will be
+in the DefaultCheckTemplateVerifyHash, so we elide it. It is expected to be common that no scriptSigs will be
set as segwit mandates that the scriptSig must be empty (to avoid malleability).
We commit to the hash rather than the values themselves as this is already
precomputed for each transaction to optimize SIGHASH_ALL signatures.
-Committing to the hash additionally makes it simpler to construct StandardTemplateHashes safely and unambiguously from
+Committing to the hash additionally makes it simpler to construct DefaultCheckTemplateVerifyHash safely and unambiguously from
script.
-
=====Committing to the number of inputs=====
If we allow more than one input to be spent in the transaction then it would be
@@ -312,13 +276,15 @@ spent. In general, using CHECKTEMPLATEVERIFY with more than one input is difficu
and exposes subtle issues, so multiple inputs should not be used except in
specific applications.
-In principal, committing to the Sequences Hash (below) implicitly commits to the number of inputs,
+In principle, committing to the Sequences Hash (below) implicitly commits to the number of inputs,
making this field strictly redundant. However, separately committing to this number makes it easier
-to construct StandardTemplateHashes from script.
+to construct DefaultCheckTemplateVerifyHash from script.
-We treat the number of inputs as a `uint32_t` because signature checking code expects nIn to be an
-`unsigned int`, even though in principal a transaction can encode more than a `uint32_t`'s worth of
-inputs.
+We treat the number of inputs as a `uint32_t` because Bitcoin's consensus decoding logic limits vectors
+to `MAX_SIZE=33554432` and that is larger than `uint16_t` and smaller than `uint32_t`. 32 bits is also
+friendly for manipulation using Bitcoin's current math opcodes, should `OP_CAT` be added. Note that
+the max inputs in a block is further restricted by the block size to around 25,000, which would fit
+into a `uint16_t`, but that is an unnecessary abstraction leak.
=====Committing to the Sequences Hash=====
@@ -329,17 +295,19 @@ with OP_CSV because OP_CSV enforces a minimum nSequence value, not a literal val
We commit to the hash rather than the values themselves as this is already
precomputed for each transaction to optimize SIGHASH_ALL signatures.
-Committing to the hash additionally makes it simpler to construct StandardTemplateHashes safely and unambiguously from
+Committing to the hash additionally makes it simpler to construct DefaultCheckTemplateVerifyHash safely and unambiguously from
script.
=====Committing to the Number of Outputs=====
-In principal, committing to the Outputs Hash (below) implicitly commits to the number of outputs,
+In principle, committing to the Outputs Hash (below) implicitly commits to the number of outputs,
making this field strictly redundant. However, separately committing to this number makes it easier
-to construct StandardTemplateHashes from script.
+to construct DefaultCheckTemplateVerifyHash from script.
-We treat the number of outputs as a `uint32_t` because a `COutpoint` index is a `uint32_t`, even
-though in principal a transaction could encode more outputs.
+We treat the number of outputs as a `uint32_t` because a `COutpoint` index is a `uint32_t`.
+Further, Bitcoin's consensus decoding logic limits vectors to `MAX_SIZE=33554432` and that is
+larger than `uint16_t` and smaller than `uint32_t`. 32 bits is also friendly for manipulation using
+Bitcoin's current math opcodes, should `OP_CAT` be added.
=====Committing to the outputs hash=====
@@ -349,7 +317,7 @@ requested.
We commit to the hash rather than the values themselves as this is already
precomputed for each transaction to optimize SIGHASH_ALL signatures.
-Committing to the hash additionally makes it simpler to construct StandardTemplateHashes safely and unambiguously from
+Committing to the hash additionally makes it simpler to construct DefaultCheckTemplateVerifyHash safely and unambiguously from
script.
=====Committing to the current input's index=====
@@ -364,13 +332,14 @@ scripts cannot be spent at the same index, which implies that they cannot be spe
This makes it safer to design wallet vault contracts without half-spend vulnerabilities.
Committing to the current index doesn't prevent one from expressing a CHECKTEMPLATEVERIFY which can
-be spent at multiple indicies. In current script, the CHECKTEMPLATEVERIFY operation can be wrapped
+be spent at multiple indices. In current script, the CHECKTEMPLATEVERIFY operation can be wrapped
in an OP_IF for each index (or Tapscript branches in the future). If OP_CAT or OP_SHA256STREAM are
added to Bitcoin, the index may simply be passed in by the witness before hashing.
=====Committing to Values by Hash=====
-Committing to values by hash makes it easier and more efficient to construct a StandardTemplateHash
+Committing to values by hash makes it easier and more efficient to construct a
+DefaultCheckTemplateVerifyHash
from script. Fields which are not intended to be set may be committed to by hash without incurring
O(n) overhead to re-hash.
@@ -378,12 +347,41 @@ Furthermore, if OP_SHA256STREAM is added in the future, it may be possible to wr
allows adding a single output to a list of outputs without incurring O(n) overhead by committing to
a hash midstate in the script.
+=====Using SHA256=====
+
+SHA256 is a 32 byte hash which meets Bitcoin's security standards and is
+available already inside of Bitcoin Script for programmatic creation of template
+programs.
+
+RIPEMD160, a 20 byte hash, might also be a viable hash in some contexts and has some benefits. For fee efficiency,
+RIPEMD160 saves 12 bytes. However, RIPEMD160 was not chosen for BIP-119 because it introduces
+risks around the verification of programs created by third parties to be subject to a
+[birthday-attack https://bitcoin.stackexchange.com/questions/54841/birthday-attack-on-p2sh] on
+transaction preimages.
+
+=====Using Non-Tagged Hashes=====
+
+The Taproot/Schnorr BIPs use Tagged Hashes
+(`SHA256(SHA256(tag)||SHA256(tag)||msg)`) to prevent taproot leaves, branches,
+tweaks, and signatures from overlapping in a way that might introduce a security
+[vulnerability https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-June/016091.html].
+
+OP_CHECKTEMPLATEVERIFY is not subject to this sort of vulnerability as the
+hashes are effectively tagged externally, that is, by OP_CHECKTEMPLATEVERIFY
+itself and therefore cannot be confused for another hash.
+
+It would be a conservative design decision to make it a tagged hash even if
+there was no obvious benefit and no cost. However, in the future, if OP_CAT were
+to be introduced to Bitcoin, it would make programs which dynamically build
+OP_CHECKTEMPLATEVERIFY hashes less space-efficient. Therefore, bare untagged hashes
+are used in BIP-119.
=====The Ordering of Fields=====
-Strictly speaking, the ordering of fields is insignificant. However, with a carefully selected
-order, the efficiency of future scripts (e.g., those using a OP_CAT or OP_SHA256STREAM) may be
-improved.
+Strictly speaking, the ordering of fields is insignificant. However, with a
+carefully selected order, the efficiency of future scripts (e.g., those using a
+OP_CAT or OP_SHA256STREAM) may be improved (as described in the Future Upgrades
+section).
In particular, the order is selected in order of least likely to change to most.
@@ -414,45 +412,71 @@ does not make sense for input index to be the last field. However, given the des
able to express a "don't care" index easily (e.g., for decentralized kickstarter-type transactions),
this value is placed last.
-As an example, the following code checks an input index argument and concatenates it to the template and
-checks the template matches the transaction.
-
- OP_SIZE 4 OP_EQUALVERIF
-
- OP_SWAP OP_CAT OP_SHA256 OP_CHECKTEMPLATEVERIFY
-
===Design Tradeoffs and Risks===
-Covenants have historically been controversial given their potential for fungibility risks -- coins
-could be minted which have a permanent restriction on how they may or may not be spent or required
-to propagate metadata.
-In the CHECKTEMPLATEVERIFY approach, the covenants are severely restricted to simple templates. The
-structure of CHECKTEMPLATEVERIFY template is such that the outputs must be known exactly at the
-time of construction. Based on a destructuring argument, it is only possible to create templates
-which expand in a finite number of steps. Thus templated transactions are in theory as safe as
-transactions which create all the inputs directly in this regard.
+CHECKTEMPLATEVERIFY's design limits script authors to relatively precise template matching. The
+structure of CHECKTEMPLATEVERIFY template is such that most of the transaction details must be known
+exactly at the time of construction, with the exception of the inputs.
-Furthermore, templates are restricted to be spendable as a known number of inputs only, preventing
-unintentional introduction of the 'half spend' problem.
+CHECKTEMPLATEVERIFY can be nested -- that is, a transaction that is created by spending an output with a
+` OP_CHECKTEMPLATEVERIFY` restriction may create outputs with ` OP_CHECKTEMPLATEVERIFY` restrictions.
+This expansion is inherently finite, as re-creating an output with a script containing the hash `` from a transaction
+spending an output with the hash `` creates a hash cycle. This can also be thought of as each template hash `` having
+a "path height" of the longest chain of possible unbroken `OP_CHECKTEMPLATEVERIFY` verifying transactions, and the path height is
+strictly decreasing.
+Furthermore, templates are restricted to be spendable as a known number of inputs only and
+at a specific input index, preventing unintentional introduction of the 'half spend' problem.
Templates, as restricted as they are, bear some risks.
+====Denial of Service and Validation Costs====
+
+CTV is designed to be able to be validated very cheaply without introducing DoS, either by checking a
+precomputed hash or computing a hash of fixed length arguments (some of which may be cached from more
+expensive computations).
+
+In particular, CTV requires that clients cache the computation of a hash over all the scriptSigs, sequences,
+and outputs. Before CTV, the hash of the scriptSigs was not required. CTV also requires that the presence of
+any non-empty scriptSig be hashed, but this can be handled as a part of the scriptSigs hash.
+
+As such, evaluating a CTV hash during consensus is always O(1) computation when the caches are available.
+These caches usually must be available due to similar issues in CHECKSIG behavior. Computing the caches
+is O(T) (the size of the transaction).
+
+An example of a script that could experience a DoS issue without caching is:
+
+ CTV CTV CTV... CTV
+
+Such a script would cause the interpreter to compute hashes (supposing N CTV's) over O(N*T) data.
+If the scriptSigs non-nullity is not cached, then the O(T) transaction could be scanned over O(N)
+times as well (although cheaper than hashing, still a DoS). As such, CTV caches hashes and computations
+over all variable length fields in a transaction.
+
+For CTV, the Denial-of-Service exposure and validation costs are relatively clear. Implementers must be careful
+to correctly code CTV to make use of existing caches and cache the (new for CTV) computations over scriptSigs.
+Other more flexible proposals may have a more difficult time solving DoS issues as more complex template computations may
+be less cacheable and expose issues around quadratic hashing, it is a tradeoff CTV makes in favor of cheap and secure
+validation at the expense of flexibility. For example, if CTV allowed the hashing only select outputs by a bitmask,
+caching of all combinations of outputs would not be possible and would cause a quadratic hashing DoS vulnerability.
+
====Permanently Unspendable Outputs====
+
The preimage argument passed to CHECKTEMPLATEVERIFY may be unknown or otherwise unsatisfiable.
However, requiring knowledge that an address is spendable from is incompatible with sender's ability
to spend to any address (especially, OP_RETURN). If a sender needs to know the template can be spent
-from before sending, they may request a signature of an provably non-transaction challenge string
-from the leafs of the CHECKTEMPLATEVERIFY tree.
+from before sending, they may request a signature of a provably non-transaction challenge string
+from the leaves of the CHECKTEMPLATEVERIFY tree.
====Forwarding Addresses====
+
Key-reuse with CHECKTEMPLATEVERIFY may be used as a form of "forwarding address contract".
A forwarding address is an address which can automatically execute in a predefined way.
-For example, a exchange's hot wallet might use an address which can automatically be moved to a cold
+For example, an exchange's hot wallet might use an address which can automatically be moved to a cold
storage address after a relative timeout.
The issue is that reusing addresses in this way can lead to loss of funds.
-Suppose one creates an template address which forwards 1 BTC to cold storage.
+Suppose one creates a template address which forwards 1 BTC to cold storage.
Creating an output to this address with less than 1 BTC will be frozen permanently.
Paying more than 1 BTC will lead to the funds in excess of 1BTC to be paid as a large miner fee.
CHECKTEMPLATEVERIFY could commit to the exact amount of bitcoin provided by the inputs/amount of fee
@@ -471,53 +495,130 @@ reuse-unsafe.
Because CHECKTEMPLATEVERIFY commits to the input index currently being spent, reused-keys are
guaranteed to execute in separate transactions which reduces the risk of "half-spend" type issues.
+====NOP-Default and Recommended Standardness Rules====
-====NOP-Default and Standardness Rules====
-
-If the argument length is not exactly 32, CHECKTEMPLATEVERIFY treats it as a NOP.
-Many OP_NOP upgrades prefer to fail in such circumstances. In particular, for
-CHECKTEMPLATEVERIFY, making an invalid argument a NOP permits future soft-forks to upgrade the
-semantics or loosed restrictions around the value being previously pushed only.
+If the argument length is not exactly 32, CHECKTEMPLATEVERIFY treats it as a NOP during
+consensus validation. Implementations are recommended to fail in such circumstances during non-consensus
+relaying and mempool validation. In particular, making an invalid-length argument a failure aids future
+soft-forks upgrades to be able to rely on the tighter standard restrictions to safely loosen
+the restrictions for standardness while tightening them for consensus with the upgrade's rules.
The standardness rules may lead an unscrupulous script developer to accidentally rely on the
stricter standardness rules to be enforced during consensus. Should that developer submit a
-transaction directly to the network relying on standardness rejection, an standardness-invalid but
+transaction directly to the network relying on standardness rejection, a standardness-invalid but
consensus-valid transaction may be caused, leading to a potential loss of funds.
-
====Feature Redundancy====
-CHECKTEMPLATEVERIFY templates are substantially less risky than other covenant systems. If
-implemented, other covenant systems could make the CHECKTEMPLATEVERIFY's functionality redundant.
-However, given CHECKTEMPLATEVERIFY's simple semantics and low on chain cost it's likely that it
-would continue to be favored even if redundant with other capabilities.
-More powerful covenants like those proposed by MES16, would also bring some benefits in terms of
-improving the ability to adjust for things like fees rather than relying on child-pays-for-parent or
-other mechanisms. However, these features come at substantially increased complexity and room for
-unintended behavior.
+There are other opcodes that, if implemented, could make the CHECKTEMPLATEVERIFY's functionality redundant.
+However, given CHECKTEMPLATEVERIFY's simple semantics and low on chain cost it's likely that it
+would continue to be favored even if redundant with other capabilities. Or, in the case of opcodes
+such as OP_VAULT, OP_CHECKCONTRACTVERIFY, and OP_TXHASH, OP_CHECKTEMPLATEVERIFY is a part of their
+currently proposed implementations.
-Alternatively, SIGHASH_ANYPREVOUTANYSCRIPT based covenant designs can implement
-something similar to templates, via a scriptPubKey like:
+More powerful opcodes, like OP_COV proposed in MES16 or OP_TXHASH, would also bring some benefits in terms of
+improving the ability to pay fees endogenously rather than relying on exogenous child-pays-for-parent or
+other fee paying mechanisms such as transaction sponsors. However, these features come at substantially
+increased complexity and room for behaviors unintended by the application developer.
+Alternatively, SIGHASH_ANYPREVOUTANYSCRIPT can be used to implement something similar to templates,
+via a scriptPubKey like:
OP_CHECKSIG
-SIGHASH_ANYPREVOUTANYSCRIPT bears additional technical and implementation risks that may preclude
-its viability for inclusion in Bitcoin, but the capabilities above are similar to what
-CHECKTEMPLATEVERIFY offers. However, CHECKTEMPLATEVERIFY has benefits in terms of verification
-speed, as it requires only hash computation rather than signature operations. This can be
-significant when constructing large payment trees or programmatic compilations. CHECKTEMPLATEVERIFY
-also has a feature-wise benefit in that it provides a robust pathway for future template upgrades.
+SIGHASH_ANYPREVOUTANYSCRIPT capabilities
+above are similar to what CHECKTEMPLATEVERIFY offers. The key functional
+difference between SIGHASH_ANYPREVOUTANYSCRIPT and OP_CHECKTEMPLATEVERIFY is
+that OP_CHECKTEMPLATEVERIFY restricts the number of additional inputs and
+precludes dynamically determined change outputs while
+SIGHASH_ANYPREVOUTANYSCRIPT can be combined with SIGHASH_SINGLE or
+SIGHASH_ANYONECANPAY. For the additional inputs, OP_CHECKTEMPLATEVERIFY also
+commits to the scriptsig and sequence, which allows for specifying specific P2SH
+scripts (or segwit v0 P2SH) which have some use cases. Furthermore,
+CHECKTEMPLATEVERIFY has benefits in terms of script size (depending on choice of
+PK, SIGHASH_ANYPREVOUTANYSCRIPT may use about 2x-3x the bytes) and verification
+speed, as OP_CHECKTEMPLATEVERIFY requires only hash computation rather than
+signature operations. This can be significant when constructing large payment
+trees or programmatic compilations. CHECKTEMPLATEVERIFY also has a feature-wise
+benefit in that it provides a robust pathway for future template upgrades, as proposed
+in OP_TXHASH.
+
+OP_CHECKSIGFROMSTACKVERIFY along with OP_CAT may also be used to emulate
+CHECKTEMPLATEVERIFY. However such constructions are more complicated to implement in application
+scripts than CHECKTEMPLATEVERIFY, and encumber additional verification overhead absent
+from CHECKTEMPLATEVERIFY.
+
+Given the simplicity of this approach to implement and analyze, and the benefits realizable by user
+applications, CHECKTEMPLATEVERIFY's single template based approach is proposed in lieu of a generalized
+system for specifying transactions in script.
-CHECKSIGFROMSTACK along with OP_CAT may also be used to emulate CHECKTEMPLATEVERIFY. However such
-constructions are more complicated to use than CHECKTEMPLATEVERIFY, and encumbers additional
-verification overhead absent from CHECKTEMPLATEVERIFY. These types of covenants also bear similar
-potential recursion issues to OP_COV which make it unlikely for inclusion in Bitcoin.
+====Future Upgrades====
-Given the simplicity of this approach to implement and analyze, and the benefits realizable by user
-applications, CHECKTEMPLATEVERIFY's template based approach is proposed in lieu of more complete
-covenants system.
+This section describes updates to OP_CHECKTEMPLATEVERIFY that are possible in
+the future as well as synergies with other possible upgrades.
+
+=====CHECKTEMPLATEVERIFY Versions=====
+
+OP_CHECKTEMPLATEVERIFY currently only verifies properties of 32 byte arguments.
+In the future, meaning could be ascribed to other length arguments. For
+example, a 33-byte argument could just the last byte as a control program. In
+that case, DefaultCheckTemplateVerifyHash could be computed when the flag byte
+is set to CTVHASH_ALL. Other programs could be added similar to a SIGHASH_TYPE.
+For example, CTVHASH_GROUP could read data from the Taproot Annex for
+compatibility with SIGHASH_GROUP type proposals and allow dynamic malleability
+of which indexes get hashed for bundling.
+
+The work done for the OP_TXHASH pre-BIP details one approach to upgrading the
+OP_CHECKTEMPLATEVERIFY semantics.
+
+=====OP_CHECKSIGFROMSTACKVERIFY=====
+
+Were both OP_CHECKTEMPLATEVERIFY and OP_CHECKSIGFROMSTACKVERIFY to be added to
+Bitcoin, it would be possible to implement a variant of LN-Symmetry's floating
+transactions using the following script:
+
+ witness(S+n):
+ program(S): OP_CHECKTEMPLATEVERIFY OP_CHECKSIGFROMSTACKVERIFY OP_CHECKLOCKTIMEVERIFY
+
+Compared to SIGHASH_ANYPREVOUTANYSCRIPT, because OP_CHECKTEMPLATEVERIFY does not
+allow something similar to SIGHASH_ANYONECANPAY or SIGHASH_SINGLE, protocol
+implementers might sign transactions with Ephemeral Anchors or additional Inputs
+for paying fees or an alternative such as transaction sponsors might be considered.
+
+Note that this use of OP_CHECKSIGFROMSTACKVERIFY and OP_CHECKTEMPLATEVERIFY, without the ` OP_CHECKLOCKTIMEVERIFY` ratchet,
+enables a form of self-reproducing automata address with a one-time-trusted-setup, albeit with limited utility given the specifics
+of OP_CHECKTEMPLATEVERIFY's DefaultCheckTemplateVerifyHash. In comparison, SIGHASH_ANYPREVOUT enables a more
+powerful self-reproducing automata (colloquially called SpookChains), that uses a variety of combinations of SIGHASH flags
+to be able to restrict state transitions based on amount.
+
+=====OP_AMOUNTVERIFY=====
+
+An opcode which verifies the exact amount that is being spent in the
+transaction, the amount paid as fees, or made available in a given output could
+be used to make safer OP_CHECKTEMPLATEVERIFY addresses. For instance, if the
+OP_CHECKTEMPLATEVERIFY program P expects exactly S satoshis, sending S-1
+satoshis would result in a frozen UTXO and sending S+n satoshis would result in
+n satoshis being paid to fee. A range check could restrict the program to only
+apply for expected values and default to a keypath otherwise, e.g.:
+
+ IF OP_AMOUNTVERIFY OP_GREATER CHECKSIG ELSE OP_CHECKTEMPLATEVERIFY
+
+=====OP_CAT/OP_SHA256STREAM=====
+
+OP_CHECKTEMPLATEVERIFY is (as described in the Ordering of Fields section)
+efficient for specifying transactions dynamically from script should Bitcoin get enhanced
+data manipulation opcodes.
+
+As an example, the following code checks an input index argument and
+concatenates it to the template and checks the template matches the transaction.
+
+ OP_SIZE 4 OP_EQUALVERIFY
+
+ OP_SWAP OP_CAT OP_SHA256 OP_CHECKTEMPLATEVERIFY
+
+Note that were OP_CAT to be introduced with a size limit, e.g. 520 bytes, one would be limited
+to use it to introspect transactions with 12 inputs and 12 outputs (depending on script type).
== Backwards Compatibility ==
@@ -527,36 +628,63 @@ for an OP_NOP are a soft fork, so existing software will be fully functional wit
for mining and block validation. Similar soft forks for OP_CHECKSEQUENCEVERIFY and OP_CHECKLOCKTIMEVERIFY
(see BIP-0065 and BIP-0112) have similarly changed OP_NOP semantics without introducing compatibility issues.
+In contrast to previous forks, OP_CHECKTEMPLATEVERIFY's reference implementation does not allow transactions with spending
+scripts using it to be accepted to the mempool or relayed under standard policy until the new rule is active. Other implementations
+are recommended to follow this rule as well, but not required.
+
Older wallet software will be able to accept spends from OP_CHECKTEMPLATEVERIFY outputs, but will
-require an upgrade in order to treat PayToBasicStandardTemplate chains with a confirmed ancestor as
+require an upgrade in order to treat PayToBareDefaultCheckTemplateVerifyHash chains with a confirmed ancestor as
being "trusted" (i.e., eligible for spending before the transaction is confirmed).
Backports of OP_CHECKTEMPLATEVERIFY can be trivially prepared (see the reference implementation)
for older node versions that can be patched but not upgraded to a newer major release.
+== Script Compatibility ==
+
+OP_CHECKTEMPLATEVERIFY is made available in all script versions. Application developers should
+note that P2SH and P2SH Segwit, which reveal the program in the scriptSig, may not use ` CTV`
+like fragments in their program as the scriptSig commitment creates a hash cycle.
== References ==
+
*[https://utxos.org utxos.org informational site]
+*[https://covenants.info covenant informational site]
+*[https://learn.sapio-lang.org Sapio Bitcoin smart contract language]
+*[https://rubin.io/advent21 27 Blog Posts on building smart contracts with Sapio and CTV, including examples described here.]
*[https://www.youtube.com/watch?v=YxsjdIl0034&t=2451 Scaling Bitcoin Presentation]
*[https://bitcoinops.org/en/newsletters/2019/05/29/ Optech Newsletter Covering OP_CHECKOUTPUTSHASHVERIFY]
*[https://cyber.stanford.edu/sites/g/files/sbiybj9936/f/jeremyrubin.pdf Structuring Multi Transaction Contracts in Bitcoin]
*[https://github.com/jeremyrubin/lazuli Lazuli Notes (ECDSA based N-of-N Signatures for Certified Post-Dated UTXOs)]
-*[https://fc16.ifca.ai/bitcoin/papers/MES16.pdf Bitcoin Covenants]
+*[https://web.archive.org/web/20220203124718/https://fc16.ifca.ai/bitcoin/papers/MES16.pdf Bitcoin Covenants]
*[https://bitcointalk.org/index.php?topic=278122.0 CoinCovenants using SCIP signatures, an amusingly bad idea.]
*[https://fc17.ifca.ai/bitcoin/papers/bitcoin17-final28.pdf Enhancing Bitcoin Transactions with Covenants]
+*[https://github.com/jamesob/simple-ctv-vault Simple CTV Vaults]
+*[https://github.com/kanzure/python-vaults Python Vaults]
+*[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019808.html CTV Dramatically Improves DLCs]
+*[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-April/020225.html Calculus of Covenants]
+*[https://rubin.io/bitcoin/2021/12/10/advent-13/ Payment Pools with CTV]
+*[https://rubin.io/bitcoin/2021/12/11/advent-14/ Channels with CTV]
+*[https://rubin.io/bitcoin/2021/12/09/advent-12/ Congestion Control with CTV]
+*[https://rubin.io/bitcoin/2021/12/07/advent-10/ Building Vaults on Bitcoin]
+*[https://arkdev.info/ (Ark Labs) Ark Documentation]
+*[https://docs.second.tech/protocol/intro/ (Second) Ark Documentation]
+*[https://rubin.io/bitcoin/2022/09/14/drivechain-apo/ SpookChains]
+*[https://github.com/bitcoin/bips/pull/1500 OP_TXHASH]
===Note on Similar Alternatives===
+
An earlier version of CHECKTEMPLATEVERIFY, CHECKOUTPUTSHASHVERIFY, is withdrawn
in favor of CHECKTEMPLATEVERIFY. CHECKOUTPUTSHASHVERIFY did not commit to the
version or lock time and was thus insecure.
CHECKTEMPLATEVERIFY could also be implemented as an extension to Taproot, and was
-proposed this way earlier. However, given that CHECKTEMPLATEVERIFY has no dependency
-on Taproot, it is preferable to deploy it independently.
+proposed this way earlier. However, particular applications may want to use OP_CHECKTEMPLATEVERIFY
+in bare legacy scripts to maximize efficiency.
CHECKTEMPLATEVERIFY has also been previously referred to as OP_SECURETHEBAG, which is mentioned here
to aid in searching and referencing discussion on this BIP.
==Copyright==
+
This document is licensed under the 3-clause BSD license.
diff --git a/bip-0119/vaultanim.gif b/bip-0119/vaultanim.gif
new file mode 100644
index 0000000000..a6b3082816
Binary files /dev/null and b/bip-0119/vaultanim.gif differ
diff --git a/bip-0119/vectors/ctvhash.json b/bip-0119/vectors/ctvhash.json
new file mode 100644
index 0000000000..9cbc6b8f08
--- /dev/null
+++ b/bip-0119/vectors/ctvhash.json
@@ -0,0 +1,2204 @@
+[
+ "{\"hex_tx\":string (hex tx), \"spend_index\":[number], \"result\": [string (hex hash)]}",
+ {
+ "desc": {
+ "Inputs": 3,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": -2079506940,
+ "scriptSigs": true
+ },
+ "hex_tx": "043e0d840001034f8f827b00000000000000000000000000000000000000000000000000000000f54c98ade5a10d6c8a3013fd077ed18e1d7eba9119ee318b83220c2521e1d55ff06a494bb210a1c73ef3df958da16481cec61f80281e9ab392ee6701ffc205db6393497681d92282aa2f55ec5f9dba411b5787353b36c1b33afc884249038954c7d6dcc55baf885767d4800c62314f6021cf59d4f88845d960aeebd5fb84cfe393939893a847b13753d9f3ecb8dbc264b24b64020f4897efebfeac68dd6e13b127b132859d792d2b293223fd7b591d03cb9b20735f18c0085542f1a4d769c1c874e9eac2d2e280fa3d9e7b03dc62e64c9fc80f0b09506b19166e84ab7600744cdfa6bf25f5df671725adb23887aa3e8e6d9200000000000000000000000000000000000000000000000000000000119ccb06e028dc54e45a5bb28199c854b8fd1b1797c2d7aefdb5823fc1b316a2a88e9b670ff7f282cb22d26adc79c464a50e3ce287739ec14d011a999dd66553d08d51fc9eba2ab0f8525bc6cf98cc64f09e7d7415ba7dc98701e3b6cd94342d872bea86dcfec4d14ada25febd8d2387ccef203bc6fc202c5b38c09b3525c6e68b1fb9e2284ffa3374777d686ad6c68c6ec25560645b739e8d338a3b6ff314e80698e180b836a315f90a0ed2e30260bea7e540f8a00f4d051e95f27c7cfef998002ba0cba0a725ad33f6d54aff13be272441af523dc5959980ca6c8caaeb518c46d07b0997c33d24827f9af222000000000000000000000000000000000000000000000000000000007263de59fd7c0115337ebfb53cb1dcc1e5ae6f5303ef40c4a9e71e3c819346ad09bf2ab51de119d11f878134d7715b880ec54dd5c7c5cbf2bc3b9db9a980432807aa4de4072064e0b8315010bb61cb85cf2836cd649d86f88170d747ecfc3bfbc4051aeaa453de0f9d90f33932588a03c920d523fbcdea58340733e207817a8a500d642e759a7181a666e8099592548ece7535fb14d11f8a6e4dba55780773387c464502794bbdf1bbaaa79efda2e024002357f2a50ef2a31120c4382be745debf40e0fc0894172a9d51ede424561b88615518c9c9c7b1bc7b8085cd0907e19d6fbcb85e3569c9349d95dca881100d390c321721809e8bbfabcb4c25b29bc4777c4d79c39aa9849c53b318894ad875708d8e6689dd6bc2f2aef433003ab8d0755387f56bf73f1e74980ff2d4eccddd0a00bb9a71b343137b69f7c51cb66d8e33cd70573f65f9157043f5267b60e64370e0cf33ab8d40e6968192cf3da58790dda9824def3b8d56d7385068ac8bfafc76f06e46cccb80852a59439a5f0ed8ffb02aaff01e4556ea01ba56592ae4e4ec33c86d2dbea9c83550cb9357d7b1aa67a1067b4c163e39202438ec52087f4195c1fc90f543fe41c630bf25ec79d6084a954ac70c9558443ded85901746e35226564b22ecde4e23da0905e38dddc4b34186e895fa5b743eef69ecee8513ebd2f821bb89c2f9ee7f0b82bd0d42f40bd9671dc163a5eb53a403831f9df6ca6245cf0ef03708fb889e4362dc5ee3b504a8e01136cfc3d3bbc44eede5e4abd18fca8315d27a746a749f5fec46254cea659c53ea71f99ed1e9744192d1743cdf24d99c59a671006a4474077ad6020db169be53eec1511c5157517253fdc901257a6f391c70dfed3d0a26bf3155ead063468639825752a4f386f43cc94223db499358afa7fb21d27ef72bbd73be1c9eb528962c4697ec9cbffd44ca6d2879dbf84de9dae29261c37a2ce87813ce34a5de387afd740d29727b1cbf0cbdebf4cacec0cc0c73c28d9f120bc31b243629fc850b55cbc704f16d7505c9b83aa079cb644c69cf6ea01b9c92dea2a624315471922626e10c290976a26247c0f733d49225b91e38074075bea6b2cfe14ba60a608c15351701b71c81bca089f2da62c5fb07ebb261682f2be982b2f699aa27df152d8fd260287e9bedd5b848186e38c3fd1895cc1e53d907bb75ab3fda26202fab8c7a8d0fb3d4445fc3b6f90b2a80010cd3c2ae18e55736e460278b9ed477e209939b096a2cb3225535666616c773e07293c100afb5ce982e933fd2d95a607968e1dec26a4b2e5e8e3e2b40cbec9b15c16da81f72d6bd4569e8e223a4351ec112d52cfe0a6e51e8ab660552195b507a648a42ce70e635437d52c8bda21d914d7fc0f2875f08af1f8803fa0a9a48484ae311361d2fa5bda2b3f689559bc2fb1c577f5acbfa7effed855ae0bf908a7e9269dff51070aa8a97e4954505abcdcebfc6ae1c1bc68dd593021777e9ea573fd79334e85c582ea900e1570337f091bdbb555c19b89262aba2b7429e24ca04c177059ba8dd468375f2a12e99937a22cb131ebb508e81ede4b807789c4318b8229b90a01a4443d74e6fc4ae30d04f7ea1c2bdbb98c2a83b316d56a093c790af9ff25ee6be833448dd05e96ed38e7b3fbfc7c2409c99f36d81e40196180e2360ad3a0ef439a0a6bed0b92e93cca398ca4f95906ba6d30b33e81faeb3c405a3247f488dbc86eca14e25ddcc4367f4170044fbc5e329f49a91410185475164afb2bc537500970cf1041b09d590f12613630bba8efacde59e3c8aaecd5bc5626a7bf0b5abf4b507b3659b6df2bad43d7a2ecdc2500b375c155aae9c62a8d8af503a927d859a6dc2ffdca19cbe8872c63b1083cf5b11fb957da72f631694d0dccf21820247943a90b18eb2258af5c6aed6d19bf82542f524c8066501698f5709473824d07f61",
+ "spend_index": [
+ 0,
+ 1,
+ 3116999548,
+ 4294967295
+ ],
+ "result": [
+ "2d28d0672f1d46cb3e86abd7e682d2d3e9961e6c9237157f47d39f0a694bb694",
+ "12f7ab0a282fb9e29c9fd2ada21f950f492bfd5778a94202398c13ae6e97f0b4",
+ "0ee9cc212182845d4c32ba6b3ba8859800d5cf423c58fb1444feaf21aa9cf81c",
+ "da78ece7c0888725532355018961f58ad471f242e29a60adf84c55007fad608f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": -1368569235,
+ "scriptSigs": false
+ },
+ "hex_tx": "6d4a6dae00010a916a4b8200000000000000000000000000000000000000000000000000000000678ccb660063c1aa74901ac96e00000000000000000000000000000000000000000000000000000000333575f100deed4cd21c61531e000000000000000000000000000000000000000000000000000000002ca78054001064ed3dec34dfc70000000000000000000000000000000000000000000000000000000069eb33a500b63bd6b3a8649f6e00000000000000000000000000000000000000000000000000000000bdef058800d2e45813892f854400000000000000000000000000000000000000000000000000000000dfa70a4b0090fdb4507528cb0a00000000000000000000000000000000000000000000000000000000265a129d009caebc792f12408d00000000000000000000000000000000000000000000000000000000a163d9dd0096eb42406cc5468600000000000000000000000000000000000000000000000000000000980b4ad1008b6e087dfd46e3e60000000000000000000000000000000000000000000000000000000008d612a30061f404f0047d5a85efcd513431c8fdc3e16e04bbda3ed597cba1417cd04394a876b5d008a88e54f7b6aa91ff086ba4ba2fc76e3cb8ff373f737bba9581678944d574c399a6627e2cb10a01bb88baeb4cafb52ca8f14c1c5355497520916ff57f78e173271ed1d731e5ae17e4776481955881d03c183e0737dba812521364159af700d062aa092436e38f6e6994a8b50535a2c1c0513b690c0f1bfa14612aedb1b7b4d90f1b4d4f2909633a36e4a245f6cfba0e64fbf262a96d2721e1d4417b4028b06c200887bba784d6f410880e64c1819432f44256d93e4198b7d62b6cc80fda87347ebba272e3d2267f39efa7268ac3e4f0cd8b077bf9d4831072b9cf1fd6191e6c430422c3225ce247ec07f94fb58d365ff4e59ac353c5cc9ca9be7c01475c6e6509298134e3fcded875ec17bc35c40c6e8b5c6f1ebda9bad1d752b655d9f9238312e5c01f59cf14f45bdfed18c3ae2254635a91405cc42d68f1d7ca68b97ec93d96ed1277baff57951af33a79edd01ac23f47400fa49ea85507bec9a45bf6022e3873d90890eecd1582e17fdf5160ce30eb87baafd169dd4d0f6ea2f9e1b45406620f9c0430a2a513a6011e7cc88557ebc7b2057b4b1dcc55b6edd7a203bb9d8cd9f8019f79b2df2c64410ceefd1a819668d915c1fcc46679dffb772dc3eb55205524f495b6642d311f1bf58024df8400567f61f1debeaeb6b95b612f7e6687e7ae4dc0c3e0df045bd018434ffa4a179bc23c95562daf3e293cdf682381f920d333e61143392021beacb2935789b8d4e86ab2b16d46e0c79c05166ddf0461614204fb01265a5e9cc552812085c68129f7e0663e511f1112588886b30d5b736d3414ea8b7280e5a017473ffa0e6ff88c36902de8672353a8cd464a1b2d67c8d0691d4368b6f5c78a23b8acd08e338a8e73e7f9bfc0f7418f5efcd8bdd924fae94f9f4ef68612144ac53ad0759e0f0d366fb6994d0a8f237236eba419c3afe1176e569bfac7384c03ff056b17702d440a1b0965a753193df5b28f550244e4652bd8f6d9209a3ff027f54c493302dee347e70d3eec95621a223823b5d33f9d59f6fdf66c15ae2ebeb26d26fa265ef3485dc6db2ae40d41da19de962a154baf84962547099ff17ca2e32fd831f65be2c59136394d33d64e75ef4828c7059c0f670769a46a9dfa38bb03f27b15eea1567e1241ac5bfacb5c7737109e1b7dd6f6409b982d2da48a7883ed01601869ae39528755419487c8035b54e66ec9078fa8d655effbd5afbfc067dcab5270ef42a049d32d9af1ef63abde30321a5b56a4e38676ae9a7d02ba11487545ad6829ac5fee5a4c15db77faf50ca1731e85399d4edf189343fec7f0b7549ff6cd94c2df1f048ea84237a5febe51908922d8d5ed87605236e88097fb3e6f5b61735a7a1d899fdff4e4bba1301b0c8008fc550123262c28064e8974ee9ce18f20591c0b5cc9f82481c9e558f44b2b1707ce53ced8cf132686b50bfbe0f3a501f06b37b21c9cd210da0515d73f0d569b610db7fd2e016b6fa063c83c771b81414585f112106d1cbff1c15bbf4f5d01468b9f152a7b04948881699ccfe8b71df6c8841848462f2ba63574b4b82233adb84101a027071d337b73f408f21c333cf80619d033adb11f67c81b4c8364e03072b9cdd06f20fd14e38dc0d5f73ac880ba5f06f0215f67f23c2253dc5d461a438383eee398996d97f1916b0ef6d8ecf027e1aa21827fa0bd8fb04eb0010c98bf673bfacb8a2619b55899f0c86e363e1ed26e43a38ac0941934cd79a0b5521b1338269083b951025b92562b057e738d0c57e6b47cbb120d482bc3b34f1ee93c3de86ea4bf6a01f24f47b7ebac399d4bf3228606dc23695f55a3d99d78e032ee4854e5c3a7d1574c5b56a476ba88a6bbc8263418b5ee790c88da6de6400225763b02f3164c3655ca0c33d5ec1ade6dea61c64a1e40e38d219e870f064c993d806747642572ad2bc5f37ab58edceac35460c7bf50afa9ca8e62c9e8c506635c3301aa9ab70d8c73a955768a56af4e36862d2e908d18057440ea4e9fa7edb1b662a2ccc10b737e59ed3f1f4b8d9445243a685f167ba068153e1d6b865ab827fc01b28cc9b08090dc0f413ad1071760e7740d2251986eccf29c12246dd98171e67b27902a3d02fd58010b63aac9d24630fec45752a1adf2e280c4f7a0697192f128e1ef02f0c546db67f8c45cf55a39a7d103ebdac927574b043a7bb95942267e1a488d60b22f08b32102a7aab4dede478d19cd95a4b5ce911aee03728cbbd9c7666967a86c500ac7c6ff63ff4849e5432bf8de5a695e7ca4d5f1ab2ac09d1cd7c26227194287e0f8f3673cdb852b6d03005c85afcb181fc83a8ec0ed95499be06415c79d69429888a90187e7789f5a860b873abb0f7fef8c47b99e362891451e02eb31a4048ed4aeeebf49603ea7fac87d8134ae718dca06460536a011715ed4b83ae9724aebef0c46bbfdf02ca85ebe1bbdf5f45e58a2e96d514d98ce425726904607e613b16aa3025e1f671f1dd913e60995523035718e7f898bcbb46ee3e90e76b03ad99b61737f1ee2d4c3cf23d5614f767d8a03e4921839f59eabb29ea260684783a2842e6b0d6056429d2b390a697aef776fe8021492db57fcc045e68997524407d6e9b963f8970b5c80cd43a1d0ffc4514da60b26a750639778c902d10e00d8a569c4a8c7008d1388e8b8714c7f827a951dbd9c5a466174f9838651e86cdaa19402c8dc6427d84e73fe41596d6a1d2bba03fd4801e784079ec830a58842a8cb33d32cc56cce22b89ea5dcae7b2e659cdc6c87f6567ebae46e81a5f75ec4495110482b84ce0bdf824dc625c5cf32cc6b28075600d03d48982d75c4755ca3b7fcf9a90f7d8832197e8b96c64158eb3b568bbd48995c7820940e4488f882a8ee842024e91221072dc32917c6da4c03b86bed15fdf2889697ed349649be9b287a1b1e6d5655e7110fb3c98bc417f89eca4c3ca9f3a8891162873298e85ac83ff64adcb9622bbaeddba3bce44855b84c5acd7f72d6be9bc58bd7e9e273385a555019be50dcca5d555170fa041b472af4e9bf7b322178a3e4166b1dd6d81c7cea97788af5615323c128ca9d15dc267dcc41f6db00c8c04c6cfff3f3e8cec109ce77151b206910df0d393671685ea4dd66ca4e20e1b06ae442dc4d4c4c80dd34c3ce214bd4a3e138c82287311366cff1113b9b87f653e00b7757f57dfc011669d691591c3f04c90c9e9757ff568449b89bcce976aeb19b7d0ec42e0c0ff7414910f63f150aaad4de779604069eb6be22287e2dc2161f540608fa3b31728a1220211d253496c399bf61df8691c36728c486e5e867f6cd43262044bdbebababdb8caf50afa7f595ff07b83595de7afeba51fd2a475a419d154e312e5233d5941b45f46fc2dd3df5bc2212cc33c51e2468f5e17d17dfaff014b60024983705b5f9f263055b5ad52fb27b818ec1fbbc1de9d06636eccba8614fd2860250561d19a406b9d3a67ef125cfb6a22c9fb0e61ed3e65a93fefa8edd2fd5801586591b2f2ab61e013400acf71f0e023d17300cc90c1f9259bc8524b2319e77bbba8c4d286a0ffe799c57061f3a36f831e2cd4c5480a5dafa9c209c93d7cb54a56f1b3670ec1eef3de8494c496061c14853566c11e9fa4e77dc3aa029be7a120644ef0394f6cbd581a323b56187769669cb1a5d99bbe08781c95d6eab57a3c6e1d1ca3484b20bf3f67f2b6ef9c6bdba800e3275a469f8e39630366581f2b275b65a2a3643e02142c7a58bc00e60e350f930fe441f443454c5b7da4159195ecc9ea9d90929a74186312877f3b3f8a0eb61037c73f24d7f13fbe2304affcebedc366318b6c1a53f470efdb7cb16c833abf27ba330290ff43209af9eee39081bc576e1715d953ad728297c3c939dab1848763e6df0c72198c8571541b81e4dfea8196bb8f8cd319f80e10e64b61d1541bcd89ca33a6e67517052512906159506f3b012b76d5b4280faa87e5605a175c1b05ab70f91d98eea78f01fdd401e032ea5ebfebe20e81bfd4a6fc2e8f99017f50b310f1310b3b71c70c2537d132a2f6c588db5af8d24ba648ee89fc0553b305f1664f9e480ac4c103665ab51d13f94bcea38d9faebbbd6fa6298a8374448f1e99802499fe7b64d5a0e607ebec52ce1339d073130bc7d68cc0f74c29a8d313ee17d38c467fdb225a1287f9e2c328c8da19a8834809db2ec5438d30df24ba3c3b264858998ba973f016016f117db6982ef3d43d31236ae3bce49a938d43d8cc46e4de548c85cb2bfb33669fd7a9492e62e761861693a7a3aa14cfa3243521f8ca7ae6add2d20be4bef6ce40bb25795b7f53009135a992ebf8563654463e35585fc9c380940f324f9b07f638c54d6d5da77ced9814456adca7fd15665797381580f2aed4bd800942faa64a2a086ea01aca5cc4a139b234ef3837f789d406481f17798521571d5cbf83336d03a4fb054c2556bb423602364006f6f8d59eea0689fd280e29429b7052b4614aaf785e22c70596cdd11403d9a9e9a60f45395c7e4085a515689e37ca942d5a65f872fd3223adf2f7bfd47fce21f280ef44ea71c755dda9f41e730b306b90a1432ead90f9f788177cbdf41db86135171d2b6d8baf8e0a3f019900e19dc9d9668111e3300e1a73aed0a68a25e6d670cba7e1fc6c18e8da346402b732446a381a75c65a0959b1b4fe2d116b801688880a9cc014e0e7b5851610bc49fddca01aea179977b87863ab3ba9004a05a08609278c5bfbfdbe9f6844b439343d46a0cd38b40b4ded6fee8b563a20c25637f7068810e379bd65b704f6e74480d129482f88ce63d9eec54d1f19dd113afd36357ff3d1d989a4992ee5d8c4a25946e8f79b1a80ab76685c568280eed7b6902f66d3e29116ad75c547e8ffe4c5ad03622befb7ead7bf02b5c0f44765d577148fcce0354f60c939aaf4552f352a2981026208ee74c730ea5e03b78756b09aa68e02f60931a2ae5176a0e6eb02726be51b3f286192c11a98617138710d27ce6923bd49e099f18feffc0bed3f1d38474baa4c69bd92561aa4827cfe9796a1f3aad098b4eb8006b02db2ed8fa6dc84eb78a4857cc9f027908d90578eaf1ebda3989c9501c7c098b9ded18ab12fced3473205cc5d1c2b8608bab400423402dd10eacb71e6ce96a0990b34d94a0e035b3fa84b62fc21323a3ff4bbdd6602b694ef45572d4650fd80771eb1bf8621654fc43403fd3a018f67c2e675cf14d60e6276425b877f4c0bb9c057d6004f07431a0e641cbc41b2d77a5304c06ddc39cc995248b366cb79f3c38322b4074ec9bf147d6d1663deb54acf30d9568085f910ac91575901834fb234cb0d8b1579eab248cc5b1172dd8b1872dc8665b07c17f88c37df4f8f67bfe1e4e3c5a0a7259a7a2687319e458de79b8bc377a573b760fdea26b82b1a7ff7e2e89c756d9c7fb29a75367c4c44b8e6444a6ce2f81902a1bf7e2485039d1b2b3810e680e22770953abec970c1ea3eb8244f8b5cf19d23d637b8749c61dd653b34e7e8c7064b5c2d67793c867adf8691543df88c2e96ea08e06fb29a40575ac4b18c8506b08c9608e9e9512e132f093fd12df8910ebced42aae6e768977d7195dc4728b533f35852926671d08b1a68bc6c8abea8b4dd82811bb3d4959363dfa923a5a40c656b0b557afefde201ddfeb04901dd91fa610e4be576555cd592998b4d2e16e64c48acd3ac6db3473ac77625de377c2e1bfb8dcbf8b7b111c13287a84b6b7bf35e2c54b37064fa8c4e03a19beeea55ea95caec8e02a4c73c0344c83664deda81e64b20fb00a602a174031cdd5248db1abbd543ea2240f4e4a4df8c7648cbe45c639ecefbe7c4bb2df223577e63922a7a6bdbd3a6d3908f5cdc412fb455516341d66dca4b4523f82e7f9d3be73ae24b97985e482d6d4e6cb82dcbb362ce064c0dd54a26c42e843625f155f9152f94aa6ba04839323ee78828dbf5e0dfa4d628656c736634f9122c4fad047d0513f7118ce77c959f9eba47b57ccbf2671c6250665f83e915d74ccb7cb6faa028eaecebc21b6bcda7193695592b98abb6ee95e47547da6dca4b9b740d0f4a6a6c95ec7ff2ba481133efd7e2b9b93376f08ec97f40a4045a167695ae1114150cdbff9d3081a08d03f2f0ca0b25435ca28b53266cf94faaf656b4e7fb7db882185c973186743c45064ccda60163e73a8c19aab9ae7d2f9e563ac8fffca64ed9c6277f342a99bdda91efe01c2cb24e6149428b56d322f2f7b31e1c61e581b57afb7acb216627ce137fc8fcd14ec5c8d4be39beeb9dcdcc5087422e0255c29f10870ad9bc8931922a21e5b57e085d3d7f20bed100cdaa22a6af6196892702a6eefcfdd601649dcbca53afb0665b25658b57f988e3fd743ce52ee421f4973ee95becda180c7bf41f7f1b3a0c7a5cfd184478575f7aabb059cbb94a42fbdd5b1b11061b8a442a2f29d1096ea85439d89fc031e3b22d85ed29423632ae4f2b6fa98ac4e4f601d91c487f6c84ca2d660aa157dab73ff31f441e6653e9be98e6c08fd6009a5c7e82f4de916ef3650b7a9456dbb77889763448205f42a7d776c871123b1db50bd73f3d60291b1ef225372e5ef434e256e97b4caf64eef889af73818c30d3b24d5ae5aa15353b4e22de089ea4b560891bc329e12e0aac9e7e2f8fa83971eced1115f4b664f5e80700193c60ed15c07f6267f61e1a07b37ec3072e2282133ced8ddf25e8f865580b9cffa49089014a601bf000adebb5ceb5bcd539f3ad20f9c7ce5b3b1d863d4bd60a5fda1f566c9da7c2196abae8b806d62a01ae6840cfb864487c9f3e58b2c22d21ed292a56fcad7a2c53487fff3faa84ad7d58ffc6b00c60aa50e637d4ea74501aa568b1b2a349eda1d04bff81bb052e1d927bccc3daab9ad18fa77740e936c6575fdf6babdaf7a241114ed4f3d65bfb4fdea7a4f57553963df5a5e066b06e82663e54b58a2e5c8f0ce57e2ba4832139ebfbc70671646332a86e971aa9a9d25dfc89243f41cbdec196b279e1bd669be402c94134a56bece2d3d5e733cbb693ce523ee2ab7207feaee1023c4a11758a2c9a1f901623002b9ffa27b642dc9b6c7ac02c2bda113112e597bef8082c3cf95ea4689d29f1f9e666d75aeadd181f92b6e68119c31bf71310ab8628c5f5cecc32e1f2d760231e1e99660a6ad7b3a8ce6d677ef61161fb9979c3897a21871cb431a7aae519cac807259780068e48917d8f2d2b70b3737311db2333d32ace68822d2bd852cfc81eb5dc356fe2e749fa6635228fd6813997372dfc4cce81c9b847615bf132c3f5d1fcf341128dfd4501c98fa3cbc2537cd4185b53bdf095a83bc17acd63119b6195490014a772c4b1787873696ca6087052284db67c5ec38b9243f7a476acd2f10374724c57c15f193a6cc0ce635d59989ac56172b7bb8efc2d6aa17dca85b2a5690a9f409294b33579ae8ffb506152f3f2f3e7c00955005e4fbfbea1827b6678306cffd56cf3f43ceb0afdeaffc891e5bb7ec6eafe24e2aa5066185820d20cab677bc9b83c5a8f2307d4fbd3ff3a282e457d1c3d6ff041763044318b7721dabd51e43337d37fa3064ac7f564d7ebd23930ad11b38d0d7312a62862f7fc9e0664eaf0f0ab5cea30e55ed52078edb0c722ee7f6d5ec4f3c17503f2a97a498660bb7ea1a0e305fe25492944af4b7d4f7bcef715e714b840b440209650e24ae1302c4a658fa7dea6ca6153ad886444ff54eea7672e9b32a1196e593f0532def46e64f04ba46cacdffb7aa1f27f22a4f30001cbc6c09ac7c4450194df9fa302996d8af546361730744ec2264b884d8b92c8ce254289a2082e182f5199f9e22fc37a23459cf97802ff48448c3c66eda84d4d4583db8946f1d2dca19a5e3177769190174e056a0bef4a3695d4c5a47defcdddf1ba513966b59824d9cc996d123422ffb527eea355cd8be64d0400838229f29f263ed5f31d158b3000e0ea1a41d9d0bb1c83fb36fb3aa3087f3320bda1e78620bc4cd4e7bbadb5a1a79ceed8458b97067be123a9a3545ab4593c9f8a341b0c2cae3c3ce7cf2e451185c45c576203eb157f6f0942a6d18343e0cdf7e99305720026ca36a9f2a4b29246cfc7917bcaf41981b2e6cadf1401c062ef1b4f1f98a9e480a6ce1224cf49181eaeb876726315c2c0cdba03bfc11d091042d47dc2ef5e2fb49c4ab4597ccb65cbf0caaaa6015428f7c223733f2cb7cd7aa8b4c7807341f74e83d796b08a5ba9f2c7e56b51665c452a96f1ba0f7490cdcb248b5e5c85c687b6c5710be23019a8bbbdbb9f451e42b79423657f7669e1e55fcac0ca6ef554d7df76e9ff5429b20dae46ed08b9597daeb049c16b03f095c036b7eae7af530281132a2a3ec12c262ff2f66a261b61cf6400d97bfb413de51aa7bc650840ff0853fef3bbb3fa0aa2481275b7d23e369b3e17263f97d49f7a33caf484ab9629345ddee07c9da56a542ada207d98bd7e7da0f38e9327554ecb0d97fe8eb2d2e6e03047e6a05a5bf9f2ef5fe92a9e086e921f117d2bcc37cd3b3e6e4951f19137d96efd9401a1b86a4c70d612a6e96f2516c5da067c58d0431657cf86213766a7ff003cc932ab129772382f6f6ef8d7191a25ebacbb167a31d229618484276f63069f9f837e910829153d31412bb74be44a246f67cd9054e2725baa93cd362a180da0170b726f7698dcba636acaa61817675444aecedda4bac9cc814cc160ab382768d1a4907c41f632178086bcd42da9f7b59d66aca71fd27ec3badf64355c971cef6f9266d200b054ab5e6c8442d158050a0445562d66d9bade327d990428d3be4098a8a1532113ccb8b973aa3f87c07ac87bd8085dbc19fe2fddfcc626c476a7b39cb83e95f62ff1500af385d97e9abd08e6096e64f1569ba5559f0ca9a7c368938cccd5ebec3fa36843ce3fd4bf8a09310a6fe96dd320ca684ce4839b938fde5b11e7b81aad3d2053c698e8ff1bcc5b90833358eaa7b60b006bdf825a062fe01cd4818cf83c1330906298f7acca65188b51fce45a5a9fd64a94bc180267e1f33c8f052ffe457016bd061572f92c784e245581dfbf378f108880202b1089656514daecc405f5ed23a231f72524c81112662997f371474c3b5dbac649",
+ "spend_index": [
+ 0,
+ 1,
+ 1311624179,
+ 4294967295
+ ],
+ "result": [
+ "e01a5d102bb5f8ba7986e7e4ab0fe8c4922bddd005adf740122684a91afad1a4",
+ "0980b070c9b5fea0a87b3b4a148876079cb54dc3db9ca560411c1c8cc3a7f5d9",
+ "3871f92f02152b4846c1f00e3100be52b8ec53cff9f496061dcd3ad3f2f48a2a",
+ "10b88c130695168a2fc2548e4a6f4fed11388a25f3da39a478ebbce6ac2c8299"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 1,
+ "Outputs": 2,
+ "Witness": true,
+ "Version": -1051347441,
+ "scriptSigs": true
+ },
+ "hex_tx": "0fb655c1000101e3bfa656000000000000000000000000000000000000000000000000000000005296f6a3fdad01023648cde2159aabc319afec69ddaa111fde9d94585b4610fb3586e295e25fe73989f10e0991620403eb13fc9861f45021df9966228eb44d474d174823ff8ee86a2ecc631b1267fdb545612f78b4b1d300863e675d47dda8c600d68015b7688d4446625ce245ffc43445d0e95ccfb3275948ef8c21eb59887ab32de1e540d20b62182d442f5c82e41e74b1faaaf84075d88f883fc2e5ae237f3e6ba115b0b2d803fba0d28472c1d0db5e4128b2bce7fa1c1bcaa8823b66151940bc37b9e81cfb2b31f1928a6d1d8716925e91f02de1bfc8b54de0f606b950747063444149f406b003e3e954f89769626083128540ceefd85546537fa7d6541b605cac7c76feb9eba6db727892bccc686f5003758c1c36e7e5f56a49e3736dd9e4e85d12d242315fb52cbcfa19fdb6f794e99bc9a4c7504b76e4288bbce908e1147e1ffa2b25147229b464e03c9a196e5e660fcf43c0a824497e5c246cdd3c79585c43069e54206c06c60a00123f4a3f4927166f290354c512ef7e42b5930c8af1e224a052a0ea1005ea96f19e368509611b183415810e1f399dc3afda846235ceba7224fb53bc8434a2ee37e4d494dbd0742ca294cc04910281d342e9ff46eb40c8747ca18aeaff3d1c00fec1600b4642a520fefaec35d3df74aa13c1d9e37e6405e748512e67399ffa9f7fba8d3244e2e1d6a9efb716a78e4cd947a577a193282d407ba748f3311e7f8880852074a47bbc74994e75fac4aba473c99b97e7ea245e8c56dca37ba1bd4d64522f9eb474cc29018d35da3a1a8abb02032bf0577c681703c4e88ac2c5a57ae0f678dc5834639833fbe1f0e1b9fa817582c30fb07b51641cc4d75e3be4989c25f4b339e3194ff91a0e08916c0410a407fad131b0d15958ed8439f6dcd806554121260a62c36b32c82e0a153e93983ea7152eac373761dba154518e7da0a6d90cb60e306a110886b01353f1dc76ec082130f8176ed80444d9bba60cdff3ccdf31b370e837d94055ba6cc5d5bb8fe396c6d1bbe92c6a19cbd371db892203e7f17e91aa33f093e886601473319154b8fb4db0b0e68e7872e7002fdbab5d6f93dcb61500e4447e4c819fdb590bc7803f8068a008e3f9f1e250a6730a76881fed07d6895690f0444f49019b6e11939cc836fd5b8e4a01f1007c029250412d8e7fd8ac89476849b2c020aac27da1ff8618166303eec688936e28f0a31adb1263dcb48d0d060172ab1d0f0e15102d2815dca08a19d9c2d872224623dabed1880912485e54d3331ec9052a778786498ee0a57271b243e3c854701b2284cfc5d9e5997107cb389df6e58691180bc4ecd0ebfa266a2379d23c561c7fc3b29c393820be0534237fecf93fd33e5cd775e3e17a5db3b35e1d3dff99ccc3263796227526b62c1836704cd13bb50aced16eb449e5511dab9544d1ef4eddd839ac1f73de9bb6a5ca714fd0362301489ffada6154f9aa55fa3bae31eae4f7a9fc02d9aa6dc431cac4f657a47d75defe00ed7ace6e2aa0bfbf06a6f95ab872fc7fc084668b35991e18eecc9a5eb8eede635a619ff7bb40cd1e9f36da0c1fbb9ba88667b8a33d28ef266c270a8e258a933903e8658f71b4c104b34a90a685465490b82483a231d1f5193b58a356b8aa509783964c6aec4f480e6d37a82882449e9f0cad78df21cc73ab71f8253bf236fb67e3807e1f7511da8d4ecf17df6794595d2ce4981e6e7639cbd7dbbab6b18a4ccfff9f404449d82f8c9dd5ea718deb2c5cf373788d8dfd02d375b6d52c8c12d6bfbb5b2ee6a7fe45d705a28df3a0097e90bc4b19ed940530d3244da84a86a9c241bbb2e2048ce0510fdff6c9474f0ac33423b93fe6c07d9c24712761f57ed7c19cd311b1af416544443a6f7f61385ed927d13921bc9ea8a44cc065e6b17db35451b439e1954a040305b2b355160426868746819ccdab1023e30f326926c850ff52a06e8c7852dafa114863f65b25ab7495",
+ "spend_index": [
+ 0,
+ 1,
+ 2574543262,
+ 4294967295
+ ],
+ "result": [
+ "f995d871d35aeeef5d42fbe5c6e8428616d2888db157697579c17add7d2408a1",
+ "029adfd50489e1921d57b997e609451fc71b9eebd5ab79a068d96beb221bf3eb",
+ "e1a58a099f934e0ec776d858c811fe485ebace34a67d0ca3ca23f5b00021a262",
+ "73591132765c175ff83226808b2efd2f13be8e3acf422ef43f728bee7a112444"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 3,
+ "Witness": true,
+ "Version": 814707723,
+ "scriptSigs": false
+ },
+ "hex_tx": "0b748f300001053c73ddd9000000000000000000000000000000000000000000000000000000006d37f59d00ee34fd4b498f005700000000000000000000000000000000000000000000000000000000f66f9bc300059000915d417d6c000000000000000000000000000000000000000000000000000000005fda9bba002da98aa5f81966170000000000000000000000000000000000000000000000000000000049bf1a56004d5d2468ac523d8f00000000000000000000000000000000000000000000000000000000276b4b5500fe26001d03fbecd947d802ea49c8a61d48f577a041311daa647870c8166b0accbf1b2d5e050ffddaa2b08d3e1b2f5392bfcdda9e4a1c19c2b1d9f6185d8d3112d09a983c02db4ce36d9eddbe2daabdccd2dab45985eb37b6349bc81c871bb26ab409211a4513ac4666324e7f44c608fdf5bf073fb64499471f81e6f7950c50f952ec14506ab7985656e5a78446b10a59439d98522177037401faf445734aafce951ba24f0cc68bc0b59a75614d7717265797a683485ac416b4f0be3f9230747f5b6c63ca3e3b8650a68e2fe9346b8fd17c9f29d8c6c4012bb9ab0f970578c8e10acd035ab33642af34daac3882805910b8312bb512d9126d4b465a8260f27ab99c2cdc0936c43fbd2bdbdeb2c35308ab9ead119b767ef01afb943dd9e2b5e053ea99d639fa3b897afeb812d315a80396bc60d59b61fa3e6f461dd718b76c057fc998d3344da47b9da5d024dc4557f05d2a270a9dfc48f297b15c0c37ce68da274afda61593aeec9143b85c060e90ff86650e4fa4e9fee59d4a0c3a3d18351eca4e7cb94fe3f3b156e07217638cdcfb6bf8d512f86bb38bd610832cc7c75c4a94e9a90153ecfdc8b85429d2968cdb48c8296777133ff16197f773b3536a0a1a2d598e6776257685c969d43044173724d8cbeece0e7053234712880a031d12e84ceea423a95efbecc0a5abaabd5a5647fbc6b606116e10532fd7a31d8738d37cfc201b726bf6030f25c3961125dc510417601ffa52cbddddf2c185f4cc17bc7b0d510247b575562306e64cb4e5359d7d70d09e3cd89dac10d82fff19c2255a3ca6a992fbac4b414f23fa1971e838de2e393b2c20c444c238b78e0678cca3901cf29417ab0aeeca9626fcb7be5e777da3648ed088ff4d4154b701f38dbf127fee38897a5ee7d7d357a672031a3085600ae3ad2384696bbdedaaec8a86e008f064c6ad5950eae848772bfb597cdb9b9af7baefff97e52965fd8cb2c8e3561617582942eeb827bce577ffae69ac948a6409c69691c61e0cc55cc11320df3ac90ad2917913e701d69402016a4d88b84915eb546ccf34a37a8b33135dd10306ab10e73bb2ab3fef965423557ab11dcf6c8135660b07a90881b876e06047827fa3e1ae98798604a0dc1d11d9e715102edb2ccaaae863d10ea8c2147b8ca3e8b3f10f082140222d914e15599706465da455f6d5f5b9f14829b4a2611476b5d5ddeaa32037e69098658ccf4790671e2bc206020e9e06c13bc00ce2d4ba17cc6689bcfdd4018fc919d232d5f5021c3d689a4625593fc68aeaacdec4e408bade148365996b6da85c4e9fa11220dfe94615e2ff5356b97874059aafbcac2b0dc90792c3ec08ef4a2bd135ed059c52a42b1d1c168558cd4a758a54752b433d624ab4e7971e51cd39a18aa1229acce968579641aba00662976e6732994b8c3f1683bacfbd510b345391cd438f171898612236705e51c6d603f4c95f5739f80d50abf2133c168af58450f26cdd571ec8d0c6ce4dadb2cef510cb424e75e984f9176e448683c08b3e11419f34f8eb11e1ce4914ae35188fccfece3372e502951df6715ebc5ddad5c13dbf70835c1141cdf2ecf81ed0ecd8d5cf5ca8c57203440f2beaf3f91ef4bd5ad27f53de363c5116de666c5ae832cf9216cc8817091355e22e9dc7ce4f652783b2b523032b7b346c25621b65f4a505b220fde444c57a9a80088bddb5726362ba8a8207834b566c2f9bf9272883aaa62b4553d82010d4081f3bc8a2f7c4878ad4adf0c8c11adc04c41c39ba49dd764bdcb7531b23837ede7d615ce76dd8b68323df8835479ee40688172c881b81cec1074456b53ddd50ba6d96b113ea8a04d5f0466f8ca98b6246d8c84c54d8e9362a6b93481fc2b2c5109c7a6649078c8b38ebffb1adeb396aea039c0b6354d17d5077bcfa3b1103de56a85d7f7fe6d244e4689e03b33515e1674724291c138027e4f0eb953286f4f9e5d790351b538ad17a6a2b0dd3758d06d84413c0bb851daec68775eaf4281010ad67dcfb377b834b3adaf308368fc9b105c16e62e76a629b8af41c7de29a54a974115541e037d5f0f94029dd551d72a3b43e5c39c111a8ce30ab87a0e2e21770e924be91b8e9644c8bb37568bef66a355530e2ccc596bc553ed10fb9973c1c83b6d6f088baf33312637a3d7b47aba022d6e74eecb728f18c22e94fd022e73e7f3e573c8306926459669e80b64eb755ff25df4d2ce78a44c6072729834ef9fdac017c197d8b0e8f91205b0f689ecbe2ea97aa26b6d60d3f72923185f561d7ecc627b96ad0744f69d0cdcac6c30bbf45e9d208f69c6ab1ebc3d83e39da96863525050a37d1d2002733a6fc1581e8e9d16f4a64f2455d7541646d5026ee34cbae5f559d822a99086c75408e376e8d932f87a773b7177f54675a77fc34b935aba64a6fc836b7be488764f4644e68c09cdad418b438a15f02a6cc148bb5e716af5cbacacd4a2be4a5c34e7c0a9f534c19442bb1c4c19fc18567685ec0a6cc79f997061ba073169873b538814d6204b0f0677e9904575bd8d4dafd93410e89065d32ba5fb2a912605368bda85f0e507b68b504baf5003b6308b0bcb094d822ebe2369f0a1caef770051c5a658ed4bc909405c7d30fcf6fe5f52a560e3189e308ea401beb3ab31c1c9a274f4daaef6fa6ddffe0d0accb622d782ccc2d8a581db691c011ec745f8a1c1c4bcb2f52efe1c2856e9a77295e8ef14b935820641d952aa895b1c6bc46a821a85d024b39e734838d007c62ede95bb4c14c6e35d1abf959dae66148b358575f52d9f79fcd81a3d6a4bc7bc62f2499d85ff5833bb2a61a12e28b2b70e8433105ac084998ef7982179ed17df120050b9408a074b8c88beb21ca3ea9359a0bd842c8124e1b3e12bb2f6f68f3887f76ea02824bee5f60ef7d6a438f538ecf4cbbd71c0bc5a41acb03c8c46e6b4ecdd47d16a00e4dcebbbb36e88c82e94c5046081dfdf34fa334eff1d2582e72e39da5a3a0966fce036748b2fa55adf9c96e7b995cc10e3ef11b34a9f6f4eb2556553e6572d11013ef39c033c40232aecba0e36b34daa35f6d9df38b01fd6101cba60d0c4fea9019e3333c4dea24bba24bd906ec319da74809533cebce37ded637c6a21c5fb63096809715971f23ca63b613fe45722cff3c8536d2d2ac71a16476d78dd29bfc013157f0c74da2d05a4bae9bf8145b2c2e5d5b98a1ce1bce0da674490d607e67cfac4fa2832088d237482e3184722b67747658e6c2c94c65e3217bb4e5e9d6c02d74dd45829aca17d9aafa2987b05ac2d6aceb51c824f3d9164a38166d85ed09069399a5d76169bab088258ff89a49451999eed3a2de860e81c6a69e2fb6c77921a018cd29ff1f368f5c5ecf1f831b175fd2f40548adff6425596a10e4d857f3eecf29e00c0e401ed85400d0f22cca0cdc3f8bd566409a5f50ca75adca2de1659698608fe19f5d7ce08ce7d8dd5df9d46146364b4487288290a6d88f52a9c8f525512a6fadde91329d86198bd49642a6f75523e0d0fa10ba996429652c173b04c94f182d6f24d0bde2db590da98c9370d25a6f08978e5183cee41201fd2201d9c1cc04c01b43d94b86a20f89e498560be4361aa120763798da9a303337116095fd5e8d368f0f492c79f120d532020a9f5b8066ab8f7f97f02f0165ab1eb352aa651fff9d70afbf497fb82d2bfa7b95c8b7913d9c63756892e3d8a4defd7c63e366e5e051de0657777d06b6d047a065d34129e6c61406bf004884bfe21d27e840fdce1446a47b0bc55bc6565aaa599262e66102b42e7d410ced19a14e9032c0b52cb73bea41cd6ce76b7430eb2f7442f9fd2236b2c37d9f6a01e522c28b5ccd27d7a0b728cf99f86c06460d67c9521cc5cb95e4116fec8b4fa42dab258c3bd4ade03cc6690e5ae0622be12ce57fbe86411c8c42e77ed684bb719655ff5b47b6b111868e1768b36a31fc09f43017e413f9439969f492fa4ed622e8a6751fb94c3f9908e91981",
+ "spend_index": [
+ 0,
+ 1,
+ 2609405748,
+ 4294967295
+ ],
+ "result": [
+ "5f3bc9fd7fc449341f79d74af750943ba58ed43366d610bf9c85832e15b8f4f0",
+ "564800f51e04ca3288dd040816b60cc9fe4647833a750a98afc943ea22807d8e",
+ "408c08e764904e02780f3e79cc5e12c06cf7acd222e71bc22ba05735d98f2d4a",
+ "aded80f68468d06eda4dca4c1b0685c8cd5563e81b900cf29c82f28d3ad77bee"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": 21403141,
+ "scriptSigs": true
+ },
+ "hex_tx": "0596460100010601d21b5000000000000000000000000000000000000000000000000000000000cc926fb500674bbca5336071b70000000000000000000000000000000000000000000000000000000087fe629e00cae822a64fe86aca000000000000000000000000000000000000000000000000000000003ab379d5db80aa6ac750bff88788ab62704b6d28b5d41262af3c738792a963e95fb02fd0169a194a7accdec7ead5fd40d86f6d043f58d81217ed028c8af11ce797fd503aae366f79cfdc5e77f8c77fbdf3b59629e5262f6a88d8abac1ec5a9e3be9c9742e18083573bc5a90f812a63dcdede3e3d444a964533b6ec75ccde595c389e7c8de759530a578b7af5c6bd6de3c88444ff202514f5e22599ef86bf96b2331e7db56f85eb538358598fed5cc77eadee5055f22969d408d32515a674702788e830a3eea9a7c4d35ed430d475263052ab5f774fc0e6425bb466b123ed43254eeaff351b74ed8c000000000000000000000000000000000000000000000000000000002360f547fdb401292a6b1ce12bea1b921383a0da232c9999f28d1a6cb8c3e48a3c8bb493daffa7359575055c7c327d3fd5d620847a9bcf92ca4dad7632727c8f62623029daecba1f94cf734c843c1d52003510c56b9a01d3bc8a56b9371ec83b3f1b89b3e7f9a8d87182d13a9b5b829c29805a4f09859cf5f67bb8eb9c6c620569b2d2e91dc103de7d69ded829cf2c193892dfbab165aab1643e80b9d48d64e971e40d39cc9442a3c498f77953c6ee5e361b47a849fff0648fd9b608533951bdab1568e0e8f1c2590c4019623034afa5ab96d93bb9aec122bcc329e756205e63fab1349f1765c680660910d7303029091fc2fc3539e7a6996db24734297c97e766073d89d27c67e5a2064fc312760099dd2c60674d4332b620573dda5bd72b444eda33174c18c05f721b860f4eb2819a9384d57df40a598f2aad3909041295d59f0a8d30aad1a8c100f779607f4aae77feeaae5d8f597d8f270e115b66883ea05e9c9d3b273ea0f013bab65059bab42f6b2e154b54666f20bac42bd482481e1a084c06c700726efca97927fe005727c2ee470bd97bea94a717f18dd56d52a5fc26c98f06e32b1173d3b1dca7406ee3dd554e8e3280fec79939986e71c8bfcdff78bb9c000000000000000000000000000000000000000000000000000000007fc3fbfffd01016f8315760178a4ae021929732cbfe8fb92ca4e495562d3d38d7e747e070fe5918c42937d71be004c8f3987fb5507a23cc15a92fd5c864eae227e41798af6c61f6e3314b931a10aae0d4f6da2d4c519417ee5302f3f844a32ac914429c25cf553d8fda38bf1b3a107ab3891b66195999701021e07c0dbf0ecb04df0389ba8ee241da0fcc470886d086fa47861c165dbbdc5a46dbaa5c731d8838bee0e00d9d041d8c073ec35d0bb684cdc2890caf837356d45133eb62c103d33450a531d3da116d8265017597b58e61d9e81f64015c97c6689315f1b3bcae6543ef8b14995497b4565c4afb9e9adfd7ee1555306da7d854ea094fffc926fa6d9db0913c9d3030138af91cf26b6dfd6330000000000000000000000000000000000000000000000000000000000fc550a00d67beead01b3eb058f1e5d1b6bc89326504bd91cdeb1d12524c41f4bad8737a0742c673bac363e3c1159cdebcb11b8a7825f24012ba87c660db47a6736d0b92a8515f8ad66a5c926da385e17d0bdfd26b546f9b86e4229a673269c0500ab7aa65f316c2abd00e4d3b5e68303a7c3e233c286d47e81664a421e556a6531998c232ec00e093ed1f3773a4287377c203026efbb1a04a54212b8234ca8556f0b5e6a6111e161326c9c626eb78e9042b5d197abc092ef7574a11bbedee547d0f576805e7dc8ca1b1330bde8ac2f427b239c8a81c902a0bdba04fd39014abab272ab3ea33bb5946fe9a18786ca2ab5d0bdb07a3a9f38130c8b3be1dd13a7c4881b1720791cbdebf2116ba09412cc9d4b4ef081c702c88cc3cb84e22fd7b48d21ffdb250fcf9a27a51b0a4e5ea4d5c0c2b3aba3dc55d37db1f0f88c54ee1dddcb7e38962cce4b4db92bd036079d1fc62ebf6ed94482ff5fa1c567a5c938c130dbc58ffbdcbdea5bae09c0600717af56042976d15d8a38fe5ffc144cf4b8391c4950e3199ab2a5f2c5fed16d8d137be7ce5c0f3aca1ea8cdba22aa4bfb24a08f47d1059b7836364b52d0d4c4c3e0220087a76b7a6eb5680f407f3018d5b0fe017732f5373be87f713b4cbfc5cfdc4bf4fcea60d08ba50c0f71a4f1c01acb685131b12cd5a745ccd09a4ee694bf6ae2e16d5c456bab6c476cca8f3e9e6b2302a578a7acc6a5daec6ffa7153c622b08df87f79a0a25457650a3d6099a243b7b754d1bffdde01a755b0cfa2547b687e47612cd8808970be6da73699a66936a65dc05ec720e21d757ec8e5c578893f42cdf84c91c6bb89eecac05c29aa67f78b2320f20c52bbba11d18a70e6e32187766780d0c1455805de1c921be4bb952da6f67e9016c0de75e96880f22aa24930c27f61f2cfb42f0fda45dea3f8dd77510d2422172db478415c069541d055e210c16614de7c40001b2be4456b77eaccccd6689457793a29c6a3fc8430f447661088fdf3da0a931a68cd4d9a9264006c218fc11fe41c19312479fec30795b9bf1606b2d8278cebf6243fb15834c2f47460ae1137580fd39f52c6740d9e7a9b0b72c91673333101d1ec4deed2dea4cade9779c9caf41f044ccc3db08c270a5ad8fbf16413d3b657595b8148a3ddcdecd142efb3ad3be784026e9ff3ba15bb3e9902d19dd1db39e8cbc9a9e49d679122c3784bade4640cc7ba9a396c61890311dc587129d6e65331a5a041688f8bf377c7534e2b04a93b42c5315d43696dbf7d26fb1c4f16e31a0411aa90f3cdf93badd0a30d92b3aca8ab0c0b2d1b07e3c99f85396c5f2377646180e8880b22a3ccea23acdc1819f6f6f4637e4f16eec41fe53dc7d8391ee9b60f88853e06b6268b4e3376bc564d9400c0f3e9b30d1a268391dd6c69a6ab5110b4545284aca27b56cd2cb7ba24f37b9022fd7d018a529a69011930c421fa1c8298e8a2ea0f853819c1de239c0e04d8fbb55fe0a36fcff19927e1c8ee08b0051aa9e4241b52c35505527c7cb49b5ba85f6742235a0efb6699b59c18ee90b88d014aa7439cb6da9dfe7b8069658df473d86f77de8e3abe9702c7cb57755b2a07029a67346e4f0155e33793e9ea17e230c7f6679bd870d936ff4813220662753b7567549a65d259d3b0d4f76f8a2dfc9dce0589bc8976818fd7b7bbc1b138c4fd913b1c05346505052b691c2781b89eaf7014d86146a928e2deb36e162f1b5111a9140e030a3e3e02fab012320cffc361155e3d54780bc31d9886e742a9eaecfee7226d9090a61cd9887ac47c2b5ead34f254e8956a77250eb620da3d7b35511591e42cf2e9208fcd075eba22472d7552d16d4f6f3d95dd98d22fa5df590ab33129f8404f1cbb37da8a154f3823354ae0831d545ac5807e64113c93052f2ea6e8b42d6cb23a8164d7f5ea186a03ce09d2b27fba5c1ab1306443d899c09192faa6d3583f411f62eef8a9f20f05d16d9166526502a002bea82178876bec3f29b4d6b14ab55c554a82006fdf29fdc41b52f8f5290e0677ade64afddfe9c91e0a70c18cb77df26a15d1fb9b00a2728fe1ac5b64963e8b1a7cf4f41a2b0e359f81d9dabd1c03d78c963d6e9b30796a1233ed4f78979818bff3209d348502db99e877c2837c19f56ac5c30c9d9fe3b111536015603d7af43acd4a5a09789ffe18ddf91c5cbd5bf934ca7774d046e87cd5fe5180d683d2b0fce914ad495295cefa281c10c1fa286130add4909e664c9cd82b318cb8f88576f7d1c1e968ba054257fc04251fdb19d179d425f261f259ca49a700b648c52fd2b82dfcc746074ca87f899382a76fc980e5d0d53ef1382d77b308fd56fcb64a91585c240b7203d31de0dd534421e5f6705ac224679582751664dacb38161331e8e7b03080a6fe6327d2bb80d867f8efd92f35b8391903551078fd8facde46693bc4d05dc7dd08353a3d14c4eecdda0c509f8a225a8bee815916c9e6b782c4cb2a0f9d724c593e849869c8fffc84ce768b19bf5fdaa9a88ca4e9ab3e2aa7c1a8b41063460e5c649172c80a65352c8b50cb3b8da5c092d3d29786ef536b9004a045fda1edef145f7f81cf947f8a582c1b09f8cd4ac04a531912c8ba673af7f4479844797041b2677d312dfff9922bf974d2843e907977185be663522df8da46ca5b860f49820ea46388044a366a90727886af05e4419a9471ed6fff9dd5e6baa2f5c40f9db17ab70d207d359d573eb435195cd1e69bc63e6fa5b3110d57b47e8e1a472fd76b40756bd2093d49215eee347f2e2fd98d017ff1fc8b3d5df71344f8dae329b49bc9fa1769378b2697f6f0aea609848f5f40446ab77ceaae87d37088cf5b4ce90b58896a91d9bde4a2703e0edde875bc768836eae0e26097a3ec206a2b0a44e874424ab70ae596318e2e3e1ff9d0ac5f749c6854909e8a7cb58359377f6981000a31ee769d18fe9ebff7f291ff0d525c264abf29b3d52611fa85f9600173ced565fd2ce8651a9745f967b883c234335d3222484ab5f4592427863242805337424517b1b391193e462419c78f7e457eec1ba9f6571e9b939b2fae357f3bc73ce8f80a205e10d48b7bc11e1bc77cc10b5c0473773a0c023a4967e63e41159059b18e51d972f878a9f3dcc2aaa355aa94c0358631bac7ac90e279dd8577b025bb396c260bbff4c5e3bfb3b512b34f6c6283bdddd1fec44b0a60fe3368cef33841d604fdda017a6d1cc3191ca5b81377b679801e62f4d0890cbb8223802df810a9d1354438049b3d7a0e9c8ab61a4656d6dc2629a9fb4e25fa54a9139d6646a6a147f9577dc1a7f32f8da8d56fc06b4379aa064380cc8802ef69aae0a2e962ebb8308fdc13468aa5935cb388f9d8efd3998dfd05423540194c4e53c7a0066161e8c285e79a4649f0e66c3646607a915e1c88f59e81b8affce0fc807adeb916889f48b94e5ca31cec3b2528ea318e7b0d424d6c5ecaba319d388641235cfa3514010fd4c0c54e7172ce0505526a885de8f353532af79159562979839a5a90f08ccda684a8867be69036f0d6598a4c992f3a43c3ad1fc1d7c09fbca86e3782a49c3df7e05bb5a17d50632b577903fc5c9c3ccfdb2c7f9c94bbbdad2513eac76696b29ae2e53abb1bc2f4b6f8fdcaf239380a51c7ca7958c6b31b7422551e9fda7e6eef57bcb35e331fc1e5a375b29b481b4f400f880f9c786a11f002d97972cc1c5a626bf86b8303b6603eb343b69c1fe3f063e9e5c6b7f1ff2fb393535dae2409100ec0903a76922c978ef7420c6145c5f4782691ead4734deb53acc9eba6de9e9cee2294c9767ec2f9a17cb8f32b3ea0bae12faf5ea9c1041528fe5d81d620aba24b199b6eec08f630e216c830f53c3264ed031d66c8f8a560d5594fc7dba25a01f8614036ca1c29b5453b4b7ebb1d524d561fae087d71e71d4028f2a6f60a55385b47d7e6d16c50a59b877c5f95bd473a02134697df794991bf42b51504c269345f0621009d4ecb25c61260b9af0576ed74ba0acfb87ca7d0d2afa0c3f4755eb93494f22b76611518fcc01c69302a816d90e0b443f89623e4b97917c78966c2e5285a71945e332609d793615693a9d8f4a351ebf2eb036bf2a7946ba702d55efb77dd61584faafa55f842066b11d250bc53905dae083fd1de527f9180171f486a6044a96eecdda76a42e975f7e7689285b9e5af32b9049beb95341541e915345a38909b8c5c9927c932af502e0726d84864c3f2a8866728fb5b04bd3f73cfcef203134b06f08301158bc85b49fbc4d915712e0f031da2533825548c87f3a0d213e204effa84bf31567a358d01826246e224a3e67d374307fe3eb66990c4052678f415c938f20a502779808ac8d37c7137dc2563e3bc05470a16b573abf62a8a58464bc83688e5466fac402bde107e940feece935197f0c2b8b3c0f9314be42a3c1165cd9fdd3074b76aa0ec8455bc366e4b1bea4de34c2b278d854299428d1e59f76c169c747387c04f2f6defa126cd32abd2a83edcec1198fdc301671e12f96e0fb407c506fea811286696d25f6363fdbd40481070b4998ae9e05fbf5399eeeb086d5453e487278d20934d5bb48a3c549082e4026e81832925c92aa7f50f94ac0df136ea6102ddc25209769ded90c67eea3a4622141167b9836689f11aee4c81471d00e379c025f9c0cdd61c3ecc293e54fc78486d8b5f053c88534dcd1dad1f33eba8bb3f242d84c4ed4676c4a595aaa1ff6fb5d3d9d49c1cb4a606d628c8a6d6fba32614b3c75c59476cd8a854e07a5a73e30cbad512302291f090bc97e739f5993c4ce65cc16966f6832c18513900b6de7059e205b333de39dba7548ce5ceef1244e43701ebf5a1ef73e134d5efdca291a95cba7d4718a03e49ec1b48ff1b2529dc17616e788e1b4a5bb94c4fcbc3b0d63d4814dce04806f2a2fa33e29ae146d03516cb9d567b8f0e52739ef42685e4559f54aa914f1d685e0ccffe8d971d84f3e3dc78b55ef3825fe1d4f93b5dde4d7483f272d08d5e69c090172f75b1b570cd1d2f15419de9580433df9358395ef41b42a87814c8b5597afd92dfba262ad1784c4a56b43b3960db6bc391f576285093a9a59e681b46ebc8f7bfa4c668592a8759c81dd5400dc5dfd4c54c292c7b1e715367be922e592cc7a851d7ecfd0401ac846196be62de8be7ab31884d3a40ed6fb97d2dc08e3fab6cc056b35516929a09dbc81ed0adaa8694e46a6973566974524149d085532d5ee08e77963f2bbfcd59d4dd97d7b20c099bbc71c3cf9a2d9381114a3bc402e558cd9f20b68b89fec071ddda09fc29a9f61bb7b339b26c146e3071406092b1204d570a4f2f046a1ccfa9ad2780356fddf70f549e3aec3190c764d771dc69c1c0edd6a01cafb695f248655a2929e2c153bf92bbb97c75ed8a677bec3a487bd8fec11586ad1659eed9a99aac10705d979a57a3abf42d17db324a6ac56d52f33edcd523d906587792dd3f4537db5b11ff1190b218d15db8827f2c04961ec9190e72a8f9e8838db13bb4b74a264d7f597dd596d169875cdf219c6360ac9d436713e0b38a361659eaa57941ba50449e765e00bce31185741feacb5f258c0cc8f574502beb1220b39f0341bc22fcaf8c1f4603fa96d310f8bb1720d08fe5f88d08c021fad3f6c4b8a65c04cb34bdb23d8ed3ab86d48f2cfa9355d334562adcbf470bc2dbc7baa9d7a9ba48ea72433d08c2ed9aae3a4e8ff3ccf19e9a09799497653481bf686ec1aba8add6f67b2f8f59a2ad1753133baebf551f489aa9deec98a2dd9fffb57d0e4fb145344d95b459287b9a21101a9a8abd022962468a7c5c79a9b1b391502d1e5be56330f6199fe691be0ef34f3446fa1cee5af1bfdd10cdaede2fb367d36922bbdd925462f0f532f25d295d2380e947e252650a861ad08f0d395f2255964ab2c089daf5bdbe7ba1bfa42d03524f9b4ffdce01ac8d4e394e74da1ea643ac7294d4482a24f9e5def87c8bc44b2d8ea7039580e6b88f1840f77ff4dad00c862bfe937ac8c5f2ebe7325c13338b286bbf066f2dc113a1f8d34948c29119814e09a57f6e2b22e6d3fc68faab24444ac83fa627cb5e251940735dff350debde2ae483f363e3483c5569cae870cd8969c3bd942c4c00a29142a8c97e427064779e080cce75a46f19dc4a0bd89dcab0fd7fe9bf211cbc0a945b1e8fe80a26f9486bdaf92682a027577f76915183184f5491c5497955c0de539a4374bf4aedb27afe226ac37114f5aa4c2793bf60baf4eb44a04e4f4bde01a2d5260a62ad7a99c9bc3b1e15b3c422dfd1b1292efb1a4729b6d030d67892882272a1ab255c83acedbb3bc2ce789a5cdb74586787a4deb1d726b5c3fbc45ca712e84e71dfe84e321566ff45504659aee25d65ebe46b8961036329267d08ff62b7188f88eb633699bc0b8cf8ed36f1977df3e46f8d965a65964d0e27f35cab715210207da86781ec5a78a06d290b66fce6bdb95fed09e5b18ce6dc38d50bf1baac4c7136bc9421dfea53ba199782b50dc93d0fa94b04dd9b19f7c26b3f1ca5176930334ae449b1ee7498ed54ecbb57162da15b4a4464d4aec222062ec8a025ae87fcee521e54a7980e76f79a53bea72f94d0d05dbaf56fdb26360412eac08d782ec2e004d3b4825ba736e4314b15dfeefa6a688c6a2fbad552420f9e34260c353de6bd8cdbe20f25d9b925be17416ca6f40a120a9b51335f8253c85a996eb814381059942df7f2fd2b2ad6a3dc72701d26dcc70b9b9272c98ff35b506f362137826ff1c01cb6e94fc45be8d4566e564280a4d459de12e7a4bb7e40c01162d9e0bf26005ab49620f3e9ec6edb2971892b01892fd6198a3f281fbd32eb2fa6286ee81ca124b5723a5a87669763fcd76e635150248cb644d6ba9cb39a764164980efc751ff4f0025206aa0c1f065d2f3d6f2507ba39e28e5fe4cb2619e397792954514fd7d774ecb89c3e93813fcbc5abd4a451c7a29063fcc42e2264cbc24b3ba4b1a7e89475cb57f618fb0850a346b62a8e2537146b67df20fee9189fbab7854bca3afca89847295875db93e7922f12bdcb1d179a1a160e0acad1111a6a8d297d03b3864c0d97e35c7d35eb7d429fb1abeb7a5967a99f2faa60a3333507de04cf9d061363e0602b149652018726ec6db2c25705491df598580ff52eb9f728b8a0c6c5602b7bd76a94af25d32ccc066ccaa6c414a74d475f323303c2d208a7aeb7555afd42c14686590bd12a9396",
+ "spend_index": [
+ 0,
+ 1,
+ 2796535865,
+ 4294967295
+ ],
+ "result": [
+ "b20bf0f7bf874016ad63ca4df0d99831c1ce767b3ac3b0f50f2d11771895003c",
+ "802dacd41f97a3865ae0825950723ac06924c7caa13598f67c9232efa8843a04",
+ "5e67f8c61e39c1ba23abfea2d0f280ce65cf2302cf385b0828226b8fc36e6d20",
+ "87b4a556c0b5dc3ea7d0853ac2357422344833b3a5cb16e4d347a0f6b74ffdfb"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 3,
+ "Outputs": 2,
+ "Witness": true,
+ "Version": 1925178759,
+ "scriptSigs": false
+ },
+ "hex_tx": "87e5bf720001032856388700000000000000000000000000000000000000000000000000000000cab6031d0095a13d21ad1caa5900000000000000000000000000000000000000000000000000000000727f13190053d917c59770137d00000000000000000000000000000000000000000000000000000000f537c10a005138206e027518707259bb2b34c86902e1031e3e2e4546542ea8862d73bee5c7534fedd0f90755ad7738a760f8bd3519dd0d71adf1bfbff642028e875c015485e8d7676338930d51dcfebe9e0fa355b0a45f4d86e4bc409cf5e8be215f99afff42dfd27229b55d5be188ea90f202eedd5ee9ef2c2a35b5f89945457d667ecc08fc841f34f79b25743cd13e83eae08a3ca9dbca956741ae05a1944fe1bda496eccbb7d95a4a089f04a5fac5dd3ae06694ba3189a3fe31feec2cb97598fb180b7a4e73c2c926e2f72af22bc46d74b37c5a97867486ec036d4078dee0b36a56c86bad746e8a509c812709e292528925ccec70058ed188b7b327ad59676f0ee7ae0a1b6784635865e097a6c05af564ad7fdb308dcaeadb293849c899c7237b0321c35098f37214ae4628e8aab2c1760d9a3b87712f69c4363705a1e7bdfe1209a58a24b774f38c940b5b235c031decd9b96cb8d795529a86c579d5b448691b6e9347b2eda029bd0dc7d0305dee4253ba8f964d2f9642274d86ff3694c73bdb27cd40125e3e57c2eaa86ef0b3df137a4723c36386fe15924654d155feedf70a2f56c0f25fa1841601c804fdce01c01e108a0ed78ef7e93645c39383c3472d5698f9ecef72defdbd00ac5def148ee21055d8e87262adbb72e3b9f5ba174c61a3c03cd75bd197b0b3174fd274494f30ce300ae8ac4fd3a6133f89096ba19fbe237d6ee3a0f5019ce6a652c60b0de903d53de6a8d058dd0a74a96f301f7580bceeb58e20cb2e4f4d66b109205edfd81cd1f5374c8f7a2bfdbe71224f950495f22e685c24d5ec231d4deba4d2af7d350b4eb0f7216cd692553c62e212c5f42805478138b4c49fd35847337472cdfb0a95ed19014da13dfc715eee6c91e6af4c6d13d090bbec13071ef2e99b634b1b96c6e3fc0c2e4d3d2828abb021f6721a2b7630d08d627b4f8d1584171be8e0b920ec1456cde295a7f12fe89a97b2511aa4e54b1c44748b184d4de656b06612b619b2099ae1892729f6e11a6803fccbfdf636e26a7f13d9321bd56dd733c1944f3b47a698725695c7166299c965b7e564ebc02ed3eca057e2643a105bb4007831ddc860b99342fdc938735c8e166a7d41ae9d30db4eeeaeb1bb38a09a451e1258927df33493deba07fa0e326fc2af03d733a365fd4bb6662cdf3bf7acef9369b340357d911b028e8a89a904901c9bafce874ce0974f042ccaef53a0b22e66a97990fec4a010df02820ae11beea66947fde80120122771f5b022287fc3b0cde2f62bf2780722a35c7b9fffabb4483f25a4d9c9d6f1e486e5da2857d825a6f06a91a4b020376ada786fd91fb14ad0b15b8ac2034b04c2e61f1b5259a80d491762d1745e13649d12c6bd6a21c7673fa21cf4a55ccda0ecb7a6d7cf57bc0b2879bda4c2adf62bd7b787915f5a0418f59618957685ab5ddc2618362ce51ec0eaca7650ba1d7f25be051304b3b6cba5a2b11f82c8cbc9612533d5611f0d0e1bcf64a60bb200950f62bbc5949c10b6a0b8957a1bfe2891d1eb413762b0ac9a2700df912689edc3a2a94535119fe0346ef2ff0da3fd404449395463d3eef18dc29eb6eb539c0a667ebd364eccb8a9666d932c990d13fb663398ab8e964598c3cbd298e954a3f5ccb640c932ba0105cb4553895f7b4cd58ef0252a363b28f4315cd3b93967e3c061508367cf814db05f24c15b0587f5adba5b3895a83a47c2944d47e52a1c9a39b84a954af50a3cd49c455d914c9ab25195c5355c24045b5b79a134d244f6ebfdf3b5c2267704513b51fd085bf1cb40106dd34c217200303fb2537cdbbda8fd8c7db1d4ad5aa8eee58696bfb6a5e58a979f6e95bfa86f8db432f1500dda08aba408f7210517eb5c805aefee3b1096bdeb29b30a1b10613bbc2b7c17a91d03b963af7d4863e3a5391ef9aa447ab435c69a4a1f77f502a2faaffd8701363bca086a732aa3b76a68b9632d71eb8c4d3688f4081e5f40ef72d2207963a2ce18bcf121ea94c80fb07579462a43024ca3a7e2c5e3d53b66beb4817fecf398e142846b16d786ccb034cb2d455b88ead1bc0123d0a97cce3128bc8ec1fbdddb0a41b063395b139ffc93023ae8bf25afa05be76527264e364e7f67f2367191ce8066f2242eebd90225c73fec97f6fe3a37011769d7f9eef3d7de5b62d3a4b0f6df4c528a326f5c998444bc1fa5b92e3ea258fc98f0b32e45ca4d3dbc29c796e3708da6ca0fd78345b3b5ebcf3e7658eb263b185f4048f22835c71b3976c226c420d558618daa4b43051e45852eff7f81f0192b70e88307dc99e30bd57483f26f655402269cbdaa9d5c0e0b2e4f09d5a20b6161bc1b3176e19578d0c47079bb789ca26e218ebe235626cfef665a317e02b271c47dce6199248daf06373434fc0db7c9d9f763da2b66c330d113f75dbac87d44e1a1b3a4af8fc15fa5138a0aeb023b1b357cc54da141b0f72edbfd4f53d7ead2ea105e17cd3fa348f28ad0e8d9629e66da1bc1cc557c93cc6240026a713160f8c961c7d90737180e7437c7b18155559fa9ae4b342acd42573d90228a2853c856da1d6241e033cd5a4af667cdc3678b76d67a55b8dffea7a398a0c3abfb9aff7ba8dd69fce4b40872156ef691b2391f88a07811b54b4f176023fe7b3f565b1afbe25e02a7c720b0e35983b82749358bbef2760390dc028fb92faec6ebab2a72b4298f560af575ca56d714bcdd678374b31b477c71817edc83ab772ce48ae2df2bd4df788eb46c12890bfbf11b160b085f64461528a79d0e8085ef5af43cd0072e7339dbb833d51d4c30d43c336ec5b7065e3ac88bfc04ebb76cb0196157223303758dbcff789e9716716ef8b434dc827aa1e3865f4874f4219f9b4f9d69bd38f1d89e177b835f3589ad22859873d25927bb53c2f105219a486508e7a8c941bfc372b51e8d037076f916965be6cb7ab9814185c5d6c38b8b955309d467d8b49d97372d802654b9a4c2b47ca5c980c75bdaf3487154b0fc585e548c22a03fca488d2b9d2f71b482099edbf9f91ff962ebd7f8adaffbdf68d45df9a9d9a25b2423131be2627c4b0915cdfdea0143b4c9942e37c67fa4f1d684dd8258362f0889faa91efc843c05b8bdfa6a0f30ebe12055ff1e88a4531a35b0d8e24ec5c5a1d49678b7017dbd08018197645a17872c50f39fa027f17aad11b3a5383768e4e9ab472f16fec17fa6093f2c4f7e7495141e4acd4b046dfafb6f725fae55f683b6f94092c589b0757789d8dcb2b00b8cd2b96c9a77b333f9118d9b1f0bde08e6a6667d81d76bd622cf0b225b3da4e36a67d0aac083f6604e89c992031091039a4d508b504b9caf437876cffa89efe3544bcfff3e723090476c013f65e3267f49a4194ef85fa0a5fa5c229dfede0c70af901edea230f8e5c65da6071bf55f7604aeb7c812fdd71912e1047e0a06af0627e2a8cc48b575e8c17bb4a7d59f4e349e4dcc6fd3498ebc98a003908ee066602ac6ccdd2327b7ee8d67074acfab3b845f9e7edd4e9866819de8021226c321f3a489a4bcf7da93b2817c6aaad6d7f03743ea3f65831ecdfbd13396aac82cf68ba3ac3a01c9a0980063d895029d573c298b2ae61703357535a672048b946a8fb33c3e0a6a3cca25cfe80a288f4c83c8afa026a35e9e0b4936879fd9a054bead2d7a443bc62029c2b76a05126e27fb04edfcb07acd36dad78cdaf13480b440ff69fcf792929aa8e9114b426c58e279dd80b47a3b53c1a075849bdc8f4251ac25624f2c9d69188be10e32b702fd7201dd1a38c74f28d7ed192299ccc97de5fee37d86cf677b4a93cdd4d57b2345901a0cbb76a3fef8981c3856064099d2f754186892fcc30b9ebee3208b8a6207bae8cb9d8d894cf3301640e9442689d2e8ac45a761d000a3d1f4259726e6b4494f8d4cba43f4ce68dc9cfd01aad9c2ef23b61138223a99f687562fa17e2a33025f17dcfe9e8d7608eedaba9562b82096e5e08461c263a5d579a7f104a445122d718c2e9a1e72d7157a37c1067f2ea00a5f80e6badfc25b82ce089deabd156ace425b4ab8eabd96e60da6565ac2fd225b95f2b25350ee6b06a2b1c0b88db0eaa2a33d6ac7dc594f3a2aca32c000bc539ae9cfaee05d6dcd38f7aef23180e9d6716387c0784864399eb9cbdaae5c0805f36875e290179c5e7b9b7dd054390c0449989e9c4d30bdfdc31d24c60127beb883b171e9b4dfdfc5faa0503d7b9d78284f7763b490afe2b41a2d8d115287107240758b0c5cad97c93f656bbe14a0a3ca92be59ee858eb48c9d0ab4350cbfe1bcb077253958fd9401811f8f4b6068477201aebfedd962ec4a3af8505bc567e9025f89296cf404f7511ec08588c7140c0200fc66abf09fffefc9e21e18cf64c405e68aef2923c014ec6cf65aaff5092f91a11f6fe67ae8e5defc323128882e412562455c1afd385d618f93e72e3787ef9f4a11a258ca57162004d7c6ce3c86fbdb8559566ff33293d904d1151554dca7ca46b53e7a59bc9338beffbcf504104b15e18d4c307fb1ae3fca5b1777809974351d7f4672ef191193b66e56e490106377ca181df08039f6312060fad9cda564be2b61dcb8d24b34592dd74940d1dbf5a01686d05d545a1fdff3f1fc6a7f086bebb6b289c54256f4fff10b51fff6395c768fc23836aa47a1113393e18c6fe07efa218b8dac25cb170c2d40fca0d908520a314935730f554e233518f7b9eb90a8f6149a02f9b028815b144cb6c8f81ff77c3d9c546ba12e6e605a4eecf8e8807f66c8ede1caf68f3afcd021102bdee3515b483e62bdd007e4446e78f4b9ce50b2bd0e8d2eb35e90031df6945adec76996f46f2bb20a0fdb982a9356e67739bfdc785f88c04784e830dd2c0d731b844f1fcf",
+ "spend_index": [
+ 0,
+ 1,
+ 2531309487,
+ 4294967295
+ ],
+ "result": [
+ "6aa5030e6eb67581aa7c7b2708db784358e09d8c9b0ffc64310ad8ce17e9a642",
+ "c6b316553f883ed41ae93c6d5e78560e625f38c6785cbcadbaf742787d2592ef",
+ "b7df572832f590a304798ad0fa135e99042164719e03afbc3dce925f3d6527b6",
+ "fae5e2dc16eba4a334d843e889ffd168bea0f1984071b275d2b002e6fce8be7e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": 388868779,
+ "scriptSigs": true
+ },
+ "hex_tx": "abaa2d1700010519f5c040000000000000000000000000000000000000000000000000000000006ea557d8b117df5e3bc8e37495a9d11545c33b2c595415f8b2a04c107082cea0b6880f1bc1c56ef6b5173e2411b8b009b6cd645542795ba41692ef896e5b3cdfda28174479ca46a39a9a7a2b6deead05881f812d4490c7638d7622ea64973a516f30968b5bde9e00c5e185f5c7b74f5144d18a8785a77f41d5b0369910521e3cfd1060889a73cdaea0553bdd73b9a74a4723c879d798500c1ab8b4f3348be682f420cdac352ca865bd3cff954121fa02ecfaf1893683eddd1e29a32b7d1a00000000000000000000000000000000000000000000000000000000d8d22db820b6f2070dcb6ed7fde96cd0daf36baf689815cf7434fe76cd17b40d55caa040f6fde5a2bf5c21379200000000000000000000000000000000000000000000000000000000f283d7d3fdd7012e9a3be8258305b795f179d2eaa2b257f33a61ed25ef99b46e720d64af6ad1e163e78d722ca24f4d1fcef74ea1b43aff2a2490021ebc5f4207a832e8129afd787494df1ed827969ab9b1a8ed85e425abf8312b32a6c37a5e2570a33cb36a422053d6ce242296e136e163ec84331e6b005f5ccc2cbf8302d67e5669f66166b390fc5f14464031e142b99c387aee115bd785cd9a254eac28d2e08c602d45f24c49e15d86798eecf8492a5e01c8f38262b2a78949406a6271ce95b4d403dad1b63e4a92a9ae8070ccc7911e3f6e7755e03f524aa5b4e62f6e8b726d712b775bbf6dd11580512df826ace61c2cec6b71105055f48befe2c7aca4a7fa1e7910892e279281bf073bd16b3d8c728c3b8654823c76ca4750e195bd1155e9972b02ea16a06fc65d8637fc37d589a22279dd0534d5564af0d10ec8143bcf6d20dcc769ce0e85dd2eba3ff9292464e703e4188c188fd5d30bf07a0a9f45bbbf8f7134380668b13f45c4a4dc50ecf6a338c745cb21ac3f8e7554f058c0cf57553c54ed698bed87c659ede75346332b9f75358133804df22ad1cbf2a3ee4a20f9baab0e3ec1e179528ffcc3f50812d6a8d5f0e3123e913682e42eb1d6d62ff7fe438024d8fd03a8cc8e25721a03139957c9a987eeba99260ad4369c6027b1f9acf037f81547000000000000000000000000000000000000000000000000000000008281c66768798eee90d89d4bff1de684f992a43812d0f27b9093151e22b188d3cae8c141b08c3d8f386da82dd2b16a8bdb5dde5c9e77ea90d753bb3eccb7dd82dc1eb29a62ace3a46c4cad25e3c2356f722f5de3933e952dac1fd33d50ac33dd7b4a488fa3be375af9832b25a46696913bf550b3890000000000000000000000000000000000000000000000000000000031c3c9f0adfa37aceb6b344e0a96379c576bab04ffd61edb0e05fafde6b6a063aaf7320c1a3f2eadedb450efd98e32615c1b7ec0ca2ffb5281d05cce41cf81b52ae0f4025e624d64ef7a811aec917d6ed31d8769a8ac482128780b2be995dbc308935e970fcc8c0c9d15d08503ff9f8d1cafde70dc21e8a056e056d366a9451df9124a2987eb5e438bab5a12a05b87731467e36423fe1c7d9b045f5d77468567b6a604f9ce35b2d01ad020139e1bcfc99fcc26fbcd3f01e4c968239235b20ac84f59e357bdfdeb4b732437828a6b24e066b5984db7a9d67cbc6f7f2c68124c0e3df45f2bd76f8d1ea27d38c583dfda2f2805d11e914807ab4ce855e29189dc29c762a467acfa2a736f2b648f9be1d08fb6a71c56c4dc549c0426e9d32b1ef4db61c0b8cf0dddc4a93a72691a737d85a73ea106aac065304286b9c09443bd053de8bb39078ec9b8fea69b39b8e2aef850828c643b6e5d510cf0ef8429e5488003b0afd2ecdc2dd1afd4335849879acc3c0de1669c9e2f6fdaebebbaaf83fa711e9fe34f834a90043b0456c0e1e45c305ad273ed86c10c522eb8a3f4c8d0c51d236a307ab7ada9872c6826d7f67883777581c94fd8610114b863acecb440d638332d5ff8b59cd7d4d9065d143e2f3aa26687a13e36319b3eee0df12fe9cf3101c2124ce5641be61fabb9351727a09a5b609e4df14fe2c38162ec1afd1dba431891599ca340697144c8c8dcbf53a45f9a9a947498e3e3e3c5a5a13a568587275c0f3f2255be3267675fb73c5c00572c53c4ecd49f2df83c47fc36ac9373b54808e25c2ce64b3dd1949476aaec7f6a25671d322b3a9b7d29d2dbb965c18825de47afc6916852cb09b88d8258e89116fff7230e0448600b2f65fb6fe28a72cccf44da378ad4a7dca0152f2973bb9fdc82ac01988d5509c42aa640940a8a67a5f18166b9ed42c08391ac6a5fe6e0505512f8f103bbbb6721a527d9b17c9b80dcd7858c20cbf3ad1255614a6d062c4716875d682f415f2e443e1732d432ca7bda8958fe7c881853176924b313cdaaf20bcdef7601ac4d35216aa0b2e511d611a07ff675dd2921064be23f6d401515e739d88e8db72120e0f96a0b05c4367309749d01a165fa4366812c78f90c015f39612ef3adaf24cc67e464a0033de296b6d8d8e7b7f50e99d5446e533dc5d59de124e9ed4fa42a1f69842cf28bad4e7e1d966b11c64100d9d2e2df66357d478db99d35aea74f633d415d97e9a451f97355d51970355826add27ddc71676cc700029fb1af45dd03ebb01533b3e59888fc144249722045a444db4b752bed28c49bac7f4f266e12d6889daffd0398eec625695644c9106d2f493a18d2a67f3bba004431b42159459a7efbb34313e5a46dfa65ad062051dcb737c52788d4198734c9c55b7f4339924815bd1c9ece0984b092529543f67dcd8eaf092e4f4f879e527d0554820030692616a8d773d114b902f1f0bbe1bf0eadc45985fcd5301fd155794014ad3b971756856d80f5b10e756092b133aacb680a6cb9e710",
+ "spend_index": [
+ 0,
+ 1,
+ 2898176934,
+ 4294967295
+ ],
+ "result": [
+ "881e1c24059c25a2f9d1a00857b12ead0f18b45567ac8d897ca6e850312cbb57",
+ "c60857fd242e2c0bdc0e2713799212c734c324db3f60fb0421fc8bebc0f85f00",
+ "f5fcc4667fe355e529975a89847ca44f444c560ea86a17ffa27261821bad405c",
+ "294e2970a8980538352f58c1756958ec21b7f5d1aa0f649dce8a90844c4a71f9"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 3,
+ "Witness": true,
+ "Version": -690026209,
+ "scriptSigs": false
+ },
+ "hex_tx": "1f09dfd6000106f4d2bf110000000000000000000000000000000000000000000000000000000059ff91d000d80f276e34f125ff0000000000000000000000000000000000000000000000000000000079474ac1006f953bd096e48aeb0000000000000000000000000000000000000000000000000000000017751cf70094245fda2fa003ae00000000000000000000000000000000000000000000000000000000738ccb5200d2e1794cd5eff28a000000000000000000000000000000000000000000000000000000009babf79f0002fa68d546faeecb00000000000000000000000000000000000000000000000000000000309a198600b4bececf030cc7a4427f98762ec86324677caf5e88a73f1d065463b9840abd4c40e262d892c03b8165a07abd15fbc1709cbc97dfe1192bf523d0b1f2a88c5d3d7610588296c6b5f6f8fb0acf213e38d35d5a34e5eea826cf4f82b3dde023f49d42aa306158b41ea7cb698535a52ddb25ee4dafd3a669cc7416d593a34161842e7204fd2575bffcf7d1eac9632236e781f1eb98d66d089ccda65a355248180f88304a086ab3a4350e18b837ae2b1dcf924c19524755d6bc168be991a5b917e0a7a49eddeb73eef59f1a1f833774c4e1f55fbbd942bd23dc1236090f1d064dc8da8df713f7813d467fff506e667cb98535cb0d4a6fdd7a1c83e3cd66550eebac702519f6fb205a60e977a03c90bcb13c5f74467db98814ad9bb7ab2048eaba8f0d568951f2302c1a39233a4a57dbdf4df82d5aba2a9d1c3835f07fe6836bf52da50205a6bbb14e9e81aafd784a87b522ccb385cddb7b9fbae48df6807c6ecec5cd65f47948abe0d51d1c64d1259b592008ba28fe7507fa9261b357ea21987e63b1e4eea4e0ad9c170718d5f128d0fb5ef6a6346a06836657d18d1da5189b1cf8ca816f620d04756843a96f877d875d4dc881bb6098d0e9667905ee31ec964887fae8685dc96458c6ebee1882943fbbf856bd37cd3d30eb7168839d768312153e9f55d7c017c7a5e367a95d0d4a74fb927587faedae6052b635356436120a6e45dd67dd10c9512ef091d3813577e1d5ef1adb031f70559d70405616706f3d3ddbc4450c867437513581b825c7fe4066fd672b4c7ee2e39041f473aff0ee6b9ff342a16c5870336d3ab8c2e11c9867ba47f16d33665fe060b8c6606d7ab7ef5db50d18d4ebe46e6c858ff3ba081d867a3fadad20357c3bd6772204fd7901a51c74c194dfe328d02423cf6a663f69fec9551d59e5ffb32c3645df20062cdfadd3e73f768d49eba33c97d20797ccd80a64510d72224d50cf3511748842e7944c3214a4803c81793f1716e2b997c3bb6ce6eb43636a49d9b520870cb6a63cdad143d841a3e072d61e52889e71ed7a775e5409d1f119ab84a5519976a52d81b392e32cafb10e75ee97138fc9478dee3e27fadf32494ddd7c589fb9074434e13ea90dd3d4aea619897522b7041504992621e76144a813e3ae7bbe28fdbbc5bc2e706a2af7a5b4bba1dd851d6050f97ec6f24f60c05085f366d07d1f66215f05f053606948f87edf84097b0141c834bd736898ecbc4eb1c90e4b2521a75e42a245fc45f13a0405e3efdc3a357f87a3fc27fbe463291a3c83122a302923aeb8f9ed6b17deca8d833a9463d1b9593d5687972c7988ccafac4d816e85ebd61cb2fd34e42e43d36e3ccbfbe11015c39bf4813ca26fbb28d8ff3920add8564836017eb2569ec6564693d8c067a441892beb3444f4bd54ff00c58b6056bba0f38923e844cfe0008cc5fd889fbdb461f738ed15b687c6d2f8f0a4cbb1609b532c645929f77c1d0575ddc49035e3eb15896ba5225831b15e7d8b5fe1eebc6021a8a8d2cb0e6be7b7b5dc2025d85587ffa4d0b77b07e3e7ee38a99f88d0e5a4baf94af8ae908023e35f8234c548b842d4ad8aea5f4646f5f166576b55eff9821b873b8d367db99ac446c7ee40b81f4c7632d514425dcce6af9c78c7b7dfa89346f8508b72ec7d9f05b5ecfe110f8e7130ba7e0beb25a57b619ad20e7013a3d394d2f65caa8325b19877fd52012c5455dccfad0089dd69642626c889cb328c5f567ec4ab433686ffabd87426ce440df053c2dd69b7d1d5b162f6690bbda276454494780bf2fe7691f90eaafee1cfb52e14db9ae3b0980cd44b21c056c8f4b0cd5b9886bdafc59820a735d5478c48a2fcac7bbfb3515011f5c6ed16228315a8fdc90fef8d8d41f9c27eb2e991f5ae1f6b83a8f1070954bd47341fa301d19534c8a11f572bf7c899d581d8457732482ecd72c857c22f5ddd56488de0b43ea4e8bdc1bb32d5677c1fa352d1d02cf1ed853fe37adcb20c8593ee9cdacdc151f8fd0d82322d48787f66935bc980e03495142e1fcb3fc00b3e3985fc335a5c0ad81c397d9f892d0a485e64c74fb93411c3c5f35f6b87ebaf67f54541687590579c0722f2e98cb075a7508fbddec43f1c0473121ff5e4521bb61327d898ef69f5ef42a9157ba1c8d93e145c35c2dac263b74ab8bdb7bee6d4ec23ae8d1ebd5b3b36140456ddcc8881497022a55696bc6db40be3a0c9f57ab97d8141fdf7fe90dcf0df8f5901c4ff25930f73b3a87d55b06b80fd748b01729997f5fca4e1cb8c9be6725451e2d31beb587740441ecd6b64fb757b3ee18d8c822bd4fd81012d7b13446c4dc4b14f76ff2f7b9f336f9d9a7ba464f455b4f615e206347e40dee0b2a99b1f47f819628c8c6b4ab3b8698c1fb3f437a7d5085d61a54e7c1d549c3aa7669adae4fd761ffd0b0e84928ddeb49d7297dd699f7b8a18c58b651f55f5e62c6a29806d8e44b1b328f67dd090a3d0e2964e7968b2fcbbf5d62a51ef6226034bb0cef7f5d57a0a20fd018959d78cd23ca851a6ffe8e911c4b27be42a29cc71f75f99a60c82b4506f1480c4bc85d24eec9605ab4a9fffe104d6df5350a897fc71039fd5a6df6f1b19d0081572caa0ded13b4c7c5028124c3c428e804388c59fdd38148cd17d8fdf8df4c2a4f1734e0286e6bff59b712cd0a5193b822f77043cad8dc3a8f40f4b5249cb8f9e9821dc7073386507a007ac24969ee7090c96192231aa4a7daf525ba3dfab3d11934f736d10e8b7fa5d8adb800a5986ca8ff9adfa7fc2818b32d020e84edb4fad653a3a495a8d875d51d070efa96f961c1f64d23449f4e520a33cded54a518c2f3a691198660d32d3a2d0cfcfe16b7bd4be7a88d9fd5201f60356e1076a25de008376d86b96b0adead85603296be4b4df6b0a61be6c71e9d777d22842ae13ec6f0630254fa68b61c9acf53c6ba8b6ee7d2504e6ce5d4d3dc92f18e647fda4bb72001a4134659d7c16253eb5c50bea0b848bdce5a7bcad890ec279265c74a3b95ef03e77313e12328ed4030f2e44d85c02d76e2b481b04ca4f03ab8f2abea06327ab0e121e49a5f07b105b99c5cfa47e5c54d5ae70c495964dd276b1af264ba04b95f2df45f799c71031554fcff39c741180b9c2f7432c22b779591080ef524dc72de01855d60db3766800b8a99e8267108dfecd8178928d704988049cbe78cdb2dde1516185bc69e46638ba436311f57f7489381e92040657c314ee86a63a93887c81c362a6f7b7d7637d2c88d70b6ed2ab80a97fa548f7443ac64a4241cdfc4b19e50b1261da72a21a7c2a7229acfe8b6796b728aefdf1f866edf007b6fd0e6db52ed1d2e66ac8af20ce41adceb40115faf56eb264b4ad8be82407cd8b580709cfb58a027b92777f7efec9c2fa66ac505399eb17e7d48f0a6659a5b99ebc2dd36e0b920456114b957a3a194951509a668dd42915edca3fbf59bef1e592495a51332fd4e895b3762c24ffadb594f5b4bcb196d7a7717e403911d599afcc1bc26ce664d905ad01290a9570da5c778a709e88fb4c307c407a9e61f4c53a69bc8b68668da5b5d0c32bcfef38e8b0af68e8b98c19c9f339fc454676be0656f1e5154019bf5e7047b7771fa6fe43d39d79643df3dc877f05cc3fda0001bbab3f2f1f6c9fa3295beea8b21c35bd32842e6e8533250547000134f38ed4f8ebf51f296ec746b90dc7fd301869f4d33d1ae655766fe07b548cacb36872396017a420623cfd8c147df07a8fc5161ea0f8f721fec60ba030d35d7fd99becddf43cf3cf064b167d740227cc4ec7a1b5860a174b8a23f6f9d3c754cfe46f069bc69f44a91bc4b3e1d9544f5571449152cf9b5c92bea1b234e7cc870ed476b9b39c002e432b501d18b09f43d120c1c531a5354f5b5d394472d3c2913712012390fda2e78eb4cf26495a17f02c18db6315cb984977c493350fd892a6f551a848c6bf4e002e5c92f9",
+ "spend_index": [
+ 0,
+ 1,
+ 3965014848,
+ 4294967295
+ ],
+ "result": [
+ "f28f0129882d7fbc863ee68a080b6385c32ba80c9807d2c3faa0499c9a8fc3aa",
+ "2bfe4ee98648516da59d4ddaa7f3852467839f09c6119663aacb7c8415031274",
+ "98f7eadda8776f807ee6d2988b94d26dc6b28bdf3bd8d4f15f4874e3d74c7ade",
+ "0de00fe6be6ed7fe240fe437cabecd03a3a6b14cf66b0b4cdc3863e9d81b2436"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 10,
+ "Witness": true,
+ "Version": -330535473,
+ "scriptSigs": true
+ },
+ "hex_tx": "cf6d4cec0001097627afcb00000000000000000000000000000000000000000000000000000000dd3b4ff0fd8601acc66aadfdbbd1a947a172eff604b62e8c3e8090a0e616ebb1e6ef6d3125f59da24b00eb8680498041eab005eac7cac1d0f8180db579f55ca565c48a2f01b682441db916655c4bf3e941d79d9e028b37034954fd18f5e4eda9c407bc7d92f30e630bd12a59f244b247ba3eb5f415101c1ff3ccb933fa49726f692c7ffaee11dbcbf4173d5fdaeb6859094670f15d249a1d0b521fd3aade0bdf895b3380f950a83f2cffaa114ef0a2bd51670b0b9bc455e3fcfc1f838e784af5cdcee25b367c711b3a00e362757b467b124c6693aa473270d84f7a36dd49e3c285b2fc3e688d4b9fa4edb2d46871117bf6c57d7b510934f2ef03a224419fa78a30ff82e9da00396ceb4584fdec173e22412eb221ff8b9ab3184de295fa5a49a5b3eaab279adde8ffb6702f0cc72e702463fa566e2d27644727dcb1fd796271c494e35b916a62b96a9af7bdfa5f9713f8ccd0523568efffd2a4086b992473b63ad567769c4c76724eaea2044f45cf3ea94fd0e90e7f5e85521601c1442140f84307b86bbef737bf5f3331ea638619a7685ff484179a000000000000000000000000000000000000000000000000000000000873ea8a00b07efc1db4359fef00000000000000000000000000000000000000000000000000000000ebe60da8a8e2db5d53c50b23150975f807b126660c5a1e52ba0916681c0586b6de121953ac1bec5cec423ee5495fac135a1a16ad24f42f62d37b1baa274c078d166c0cb96da40c94ada121292b2ecdcbe61d2cd8bb38f68d86c6ba389d3b2624c56d29211829e2fb435a605cea04b58aacb5525640e7dd9710a78880e6d147745b74a4dd7e6fd333ad05aa65672e9ccc3776c30df7111fd23af7a4dcd4e525785427c2d3b48b95403085e065292536781915c66b2200000000000000000000000000000000000000000000000000000000a1b109d494bf80046c183e6fddfd30f45e9c56116a82655b51ef881e2a6993ef310820cfea7ad3ca3d4b03a0437e586dbf0285ade22228c9bfd0b4a6e09e88a1165801fcaa3bace6d47806d617019005645541af87f84f768ba51374c46b84c118e9b138ae51d3aad4b9bd2b554c438b246e3b4b25e831e1718fc82960e116278b2bac8294aa3adbff8cf6d012777671c8852a2efa06dd2de4829b4fabddca2d8c000000000000000000000000000000000000000000000000000000007a4ae42000ccc9335f2bc7ad3200000000000000000000000000000000000000000000000000000000f67aecc1fd1301f2dff220ee90be9a059583b33badbe3678cc01cbc436ad3fb515e3b052171fa463e036f1c6e31eef7d777c182a501211acc92f6ed87bc7f1f049ea062cef28c443709f5c3db6dd35b0a6d9e19bc7e2d5e4dfa5ba5653ac6b3acffcad4c83e0c02cb5cbe31def8cbc1c47c833862edb7fc5236510d537ebd2ca239a2646026400a6a66b6b9f2666f1f431591873b4cf8bada2897dc589655b38402c358d6df8ee17a0375f78a5372b52c7d06705240628ee488149f1972f8fdd8fc58a15fd1929199eb032915cd464f6b29b51bda2696f3149fa46defc89f148383b21887b299d713f0bf1cac85126eaa2ae61d4cac70644564768b6c42ed3762d7b9f1f286e3e9bf41e5fb0d14d99e0bf0b18cf8b6869975d32eb90f137c28db4240000000000000000000000000000000000000000000000000000000027556429ea5e83f8e8fdab01afd8f10ee8fa20fcb75eb2fa1c813f915bcc68d2e167ffc2ecd7cddc2de40a3ded68e6c617ec37efed4cbe046488f1f80ef7891c6de643f80f74b2fa33e686c0a7989225076796a2a281c2ed87919f43608678235c10d7da626f4e4868b7699eb15f4c8e82f9563cb93f3682b1074ab2e1ffb357cb7b10f8d90baaf786acd8c7694e07f54765ecc537e1b8f5d69f089a944c16d019932d1c151b3892b18f8508d3defe64c9d570e48fb2ab39fcd5f8ee8f10dc1698da04d3529e92f4f50a459be8831db847f6db2bdfbd930224f369a764c1d7b9fd3bad5286520def02649194a80555dfb0ae56b5027eee0000000000000000000000000000000000000000000000000000000057b75a7500126ed03c1729c2dc000000000000000000000000000000000000000000000000000000001790f11893056b98dd75c8abeeb70077e143802fac1050777c07b01165d762cebe0642f8eb8e80ac983d09ecfec1c1194e58edb173a72bd76b42d5f94473c1e3ed2cd0bd6b8fb18ded173e2098834a4906a4c4495db06d27606ac5632882dfe2474424bafd0d9b2a869f881ddae605129ccd745648ee5864a987eadd2d172a4ddb550c47d5d077dee35b30f8a0391927f4d6180de7ca447db20c4e7f0ae9d6df64dc741700c8d2bdacf6fb47879544b5577409d0872419d429ce9e101f900ac52bdfdf80f5c4a479232936e8135a78f61ed539d1235899b982b550e3ae1cec8e23f68e99ec2e8f3daab0c872b1e3e5eaaa153b653e833ef145549f2edcda348908b69d50e19b2486fa33c4b8bcaad350242b52083f0c065925c81dfe718dae232504c0a23a3d38d71ac9b909985c612779f67db6b4b53846c925ddb151b72ce4574fbb516f5d82710118a7d8898b9ccf8f7c955e05310b2d92dca1f9793f7c8ff51e7612d37651bd8ccbfb143030c6874e13c96fcf49c8ebdab66f39ac73b51fd99a996653e9d0042aad8089141704787077869cedce34aedd537e2824a081d616e8f2cf4cc9d367fee8297313d1cb986015f1ec7b66b3b7660ac2e530edc1b1434f08a444984e2dcffa20fcca5b92f7c06b094efdf00e77605e73430079d770b4eddb5a826213de714844edb92336bd07c040ad40c09144415d3e36aa7365888d98f4751771cc5adc3e51de8f595e72389c5d0a16e75a932f217642c2f3373a799643f6bc7aa9ffd533d422806d8d9d88dfae56d8c719ec936456080aed951e9535984d3df654c815d7691c3c00131fc40a8c31f1a0df09a5785a2fbbdb33938a77d0a55a97f237a0b97b92842816a4e3c508619195fd0fd5b5f4b698980e06efaf728ab6c9390b523d5299c3c82c9319f8a09e8da63776a1be938946e00258514b8ea81de4c8adfea509f96554ddba9bbe9ab4d1053a72c32e37ddaa3441b826b3d23fd2c7a1a0a2640ae0a63b4e42d64128bcb441eba69ed308b34ca675e6f11efbda407d06056852f51a393a20e2eedb4775d3b311e893e6fe2995c8e600bd7df3306ed84f4ad943a6c633bb04fdb1ea059a00b1066ac8ce2105c4a05ece4edcb02101d5e2c59dd3d834cafa28554c9f2073d5e345f979dc5cb5e2c17021a654af09d50083d4989ca24609e6f84f44f056a3f2ce6af7674b7614c116aea78fa761b67067c60f612e9da7e671c1ca045eb45211da68052f2c95b020d30f19d1b59223f193f0c3f2e415fcffc7babae3bb34d66b0a281a86e2369f1e86f428d20f7edf2ebbc2c72372df6955c06c8e1e4aa52913c35dd934e82b031a9c081b6567091d82aeba56092478a9a87edc367d0dc3901db866df374605ecfd925885df426d66891df6c36ec8c3c946f69ba08811c4437f200861e0d26a8bc8608812faaf86d520840e0eaca173bf78b2a3e457de9dbab31e50dec191f8c55f8e3cb71369114dcd306b5593da5ea7527756e15ceef076aca4d0268fddaecdc7903a13e53755ae2e069f5d3b17424ce58c52e9fa155a0c5cb88201cc9263237730c9148cd826f3b7e0ccc3346b58a3bcd5528f9990b9bbb2279d45b4f33ebcf8784c5b17461aeb16be121f9a1f23786744c15d5cb1101dc0984f6b3df7db65c8d2543816117f91d8f3aeb5d47f9d060ce097d00fe6487232e33a021e6fc8759bad93e2a4d2370cad829dfbfdf53052776414e69e142ca6ca23848d4bdac7d7d73ebee9ab375bf4042869db5ff36537cb8c559ddfccd127d82a5051b45293374ca749234b4bf2ffd3a33d13a0c0e18f19400943cde7aaecb18def3cb269b7e000fe32c4119cf18e2d6963d9e8989b315d9423f0ab169516eb0e4d63a2e5b872ca14b7fbc39a8b9b4735e30fea05b17c145f99a52e1d5fbb4aaeb862cebeafa33cfce235cf8157fefebf00b7f0220456a909523da21f0e331eafaf24c9819267409754ebbd927bc933efbdc728d142c802fcf847df3780db979875378c83385d7c4e881976ccf2dd9eeda3338296fb28cb8213d716b6a440823dc689a42d8ad8ced64b4287c1fc4042e9459f77a4ff1c44a5b353557eda5ef422ec32b1106f1588a2cfcb936e55616525570930c0f9e308ecd4159bae020cdbe2c53d5520fc62242211971dd5a43788189db3110ab48c5f98a7aa51f5ad6cf8c842f67e1fcf8583b71f31af56387625784a50a38a1b248a3aa57f4cae0c0c8d2c0c93e0ee4c72926e96f4b6141b055aba8895671fe981f6c96f102f0a67390cfb0d303e83da47c87de11e7102d6eb52bd710f59b258dff8d79a7ec187ba70ca8d1af7a3a127350ccdddec6d42d6bb8bba9b5ac65049277edc126c02f928be0637353be04c1f8154b4cf6985092e9d511f205e43be2bbf0141460f389e65d7a2fdcb3b335bcfdc72142b8f4d695ff83be7a50f8c66830a93072db4cc4006313509d6db394cac45f131ddd3e8e1b810f7a86e90ed25156dc653445d5e698517754e4b9dff7954f09461401c20090bfdd08698a067e959eaa8270589ba8243b999f1788de6465d6a85a542aa8b24f950fdbc8e972503074f3ec82798d6bda5a61ee0e3d512d0cf06fd7a8c9cfba818df97bf2fdfdd0c13616e2d04fde64f0d599921baa5113bef041cad95f4b6211548b9ad834dbdf91e258bea7a64484b7cf3a38358cf30b75e5f19fd17aa2b08cf200f249357f2e8874b39edd0800f67d68387e8b39926785a40a74f8133ea42e8577b0acc1171136e56c7be0bd147be8c236c3541cef4b32a5073485b5844adf7ad41472a1712009bd295d4da656af34b59f31099b22964e9014e6971752f74e652b795b1875a9e2ee0f7ab3f4276d4a3e1b183fbaad482ecf6103ac874248862cde6960fb8a11f7e69454e74ab8de6a1f11cde5e65326067fc3011ed9da1232df5e0fab0d5a542b696b20ef364500ad79f6b554a77dacd738355554bbb9f39a9ab1c2e7aae26b1109350db947f6194a0515578869a4294f3e57fca14e3e1446ee2b120cd0c3d2e58a8df857fac16de57c17ef040f19e1e1b5064d10b0ada94940e8f607a15636b58e9b3e1c102e8975ec0d9df8c0ecfdb53f96956e21d78dbd507eaecde047ad065b3f24a7b91e64b9f175d5aa5ab3d5a6dbd192610982e377872af8a1302fd9701b6fe5fcd0fd80ba1dbfba614381ad6fe46851470ca688db52a9bec295848dc823d3ae6669809bf642f1e9718bed5d338f358ea556bc39f3fb3f2c13e175f883d30a77b6b3070b4dcf2a90b3c7748c594c820ead607a4028bda4e75fb9aa1000097492bcdf5d895908a90f7b86168ada4ea94668a5ffd72728d81a11badd5f2db96c06fa042d7cbdbabeaa83d1a95cd0d29b8c39918afc939a7f90f924d36d0ee823d31fd7541f82071a20115b8dae1918b5ac923f3205e97e35f01419d152c8ed004d48d638f602248d1c2b36acde460386173ed9aa7b6eb6a123f5ad362a10b82433724699302041add3997ace66d9df208880bef12ff706782f3b0308327a8fa29fd373c141b84b4c35290ac4397170186cd95882b717fca60b68b8c678d31f59b0002c9b57932fde5dce6e97b9967753bc0fe7534b4c0ee79ebd44003bb9a332c9854b4f1e041a30693111d74ecd62a3dcd311a1e972fcdda7e8591ea626aff739e0b681e813dbcf5891dd1e2a72feda409f71c1e151297618a3ed8cfc51f615e2807de037aef841c6bfc46a1b91a933ffe85a59e44912334d8ea6f4c569b6be0641de5edfbad3a64b355f3b92f060e2c340f74f2de00f6bfc08c1a92fc51a1bc999a6cdb867e7f04fb848607e6d95dc5a02353ba856321b413b6d1eac3e808f19fa52552eb6d481d54e3d14edca29c506591ea82347cdb9956abb01db8c033dd38d23ae7b9bf48fd38488682868bb47dbf34fbd9de7457bd15b61caa0fc55d88e49f5c542df58b01fd92016cf5afcf22685e402d27347a809b3230ccfaa73b2388911034537f18fda34c8b42f931e00ccb6867af0891cb34c3d4dc894ce66781f35f7fcdad63e9d62a6c0db6a6ed37c96c09e7319bd128842a559d70d51bb7b277d0ba2636bde0a9542151511054a59e844b275d25e3cb3fa49d78e5251d8ba9bd8041cf7f726f0be3c54aec311a7c34a94e29a3c8c7b87b0b4ef6807c423a8cf70825ab3f098084239fc44ce457d3c67ccde24861e46d22754819371106cd1a9ccdf84d6641e96f3ac400209bb61302d479f055e42c384f7a6be8468e04ecd1a785fa1dd2eb250a9d7a47af39cac8e685b40a46564bfb5454190bb6d5ab6e9cf6e1317b7dd4288618f1635994a47091956cb7e1894bc3a3cd7addcd8e524ed8dbd1deb9f6c78e1f3bc1988fb7cedcfe3e25554a4ece943bd54279dc5647ca3448b57c1ec729b5f620ac557a48042e3ef811947b210377b6e0cf5d55db80458886c627d3a078e954f0797d48d58ec07515f617f8514a2ce87a5fa25826227889bb27e854011c4dcd2affe59c03971c33b95006d27dca609070ccfd630b04fd2301bba78e360591b8e6e27c9ae167697212c1166160664b20b0799708d1b93c02af323f46852e72158e205587367c103a861ba5c9ffc4eee63cb43def8c3e38cd70ea759a5e67c7ead31a412b2cd5e50e49621228acb4b88cf46ceda11df8b90ca79f5fe2a373f884a8d742be4c0cf0e125499a252ceb6279cffa84c4c184a7097f548fe094a5268aa8bfb7b625dc41e9d2dc2f0b7bdb27712e6e7cebeb2a5e1686f512c807a14bedd253610bd520a38b38837752c3acf9f39e5e1671b099f2170bdc38dec2aa556b701be61b7945b783b44c3c355a87b5ae3dd9ef1f07e077335a7acc7dbf0f03f9dd664c881db172fc237e8c603ca6b5650be236dd3371f866abefde781dcfcd87ed58178ecbfda0ebb37ee015b01e7635152222f23fbe961401a1b6a2fd6501aacd7037576a0d88fb19a9a0265a19ed9c5e1d4e4e722f393b5c1a0c326ea7e3c41e0b4070c59ad1bac3086b83ee661b16ace313348493e09c6d36d6e056b74c37492893b0b0783dca75292596644b0351d95fd870c89cdd6f7c6df57f82f149e321517664354974be9fbe8a7f4a6752eb8f68ba846b6956b8acac038e69cab8a65a015911c1a216bf00d41b75505942c76b4ab03863237054bd0d57ea90ef2f3d1525f2487101677af9093831e0d1bb239cd73ebf835c37bcb19cc39e20b6fc93fc03f2ed1621b41fb36af3fbf071fab21124fe86f1be673548220ce0691f322dbf27125867f7d424e878a427c15898800d18976214059fe37638192cb3deaab52a2514027cab2c0e9ec2a08b92f00418a2640d8ff7d9681d68aef4051a58b2539b4641a0464316651231b5549595372cb0323e81e180368a1506e0cc9ccb901091f27c8aacb3c05a9eac8bc767db41b68431ce1e357238b40a62a68fc9652cc13a56688cfdda0198b1900d19f27d8604cdaa8e0197e9fb9faa949557d9bdca35e97412acd25d13c23a6ab4d5d2e98e1381e499d0f429d8eb53abf92fb94bf7a057c1d4c55c10370098b20ba6b2197078d3919c2e1c638f6ce98ea9b9e7bf55e5ff5e36cb6148eab6575e11f0ef0ea9014fed6db4c47f9e67f203a3c404d3b24d4ff7f08468734b58ee663016bbe7bc2bb97ccc5f664fae40051b68b459998ff4541dadda2d18051dae13ab498e8f807ba2448b2683c653a7876f5c17ce65c91e0062ff6c316c8ac0b22f48d884b1d8d89f43be0fcb394c01139fdc5d6784fa05d7a382d053aa1bfd0ab451de16d3f3c01e1a555047a7629ec4529879a6002385e48157b1f315d4718c7f557067ff4912b1a1b6846833211377caead54180ebd1feb05e00845fca50ed10c50d18637c4997eb205c11f9352d74322ffbb0ab34d00d664e7e2d5eba513c93ecfc9a17adff0093a0c7aa1555ee5b4a6fedbeea988b7e109a2ebeaa5726600f3d3679f0786ca9752490dd94081eb9172a8a4d6f54928e4137e02976565e4f57c4c137e117c8b19d1d7f9482630d676227f9403d1a1fdd525f3a3a4bb41271bf0bc8400061ec7ea3a9be19c8da28298a460f44d2139976606324b743e7cb21ac25cb9cf4fac8d9ad8240a96b8a04e542fc6b188c2954e96fddba1a03422eb8c1c9ead858eaffe47354441d14be919146472aeb160236054a9b1874f7bdcbc2f5f3c9142de5d2ce0af9a90226f481a3147c787179ec1c8e45c283bfdfab4ade49817c04d28233bd2b657fbd63d35acbf9233d91c316dbbc3fec2a86417d5002b96479aa7be6a93c02f088f1f2ac9e10b21bf117f69a342dbe7b1d81e70900cdaaeb1e98998b793cfd08a6e68d9cb7d94b777d6465df704bd95e88569a50a036f593368ad3110840ea30e9da9fcae0be665aea09ff5f996e8dd009f3137808240b533183148c042b1b975ab143177759be8401edf4df446311be64aa933a974f80563a768e3fa7b9ca25dcfd9236b21e623634fda73ad79ee0d9daff1e0da58e844296df730b368bb1953d9567fdbcefa743bf5af9a840760224f22b174c34bfa8fd7566d362d7cb41ab19ec6db5514a647d35059402cdcdc2aec31cf4cfa82f494ddb2c82bd26a0059b7e8e0749f9e56165189fee8516e2c45e74c2c234d1098bde49cadd80abfb69ffeb46e7760c3f3d8294c45cb2939d435457e39aad3335f1277e640d4e594c70e4aa1419cf9dbf1ad818e900d9620ad79116a52740e9b3c150509f797e59008279a28e92ee9068009a70d93c108d19969fc8493fe461fc636f0a6294e671a6bd7792d4a3f31304fd2e015b6a8ac5f9b350ba66c110d09793f5586d8c14fc3988ad744b0a7d7a11378d26b03b14a5125685cf754c3046a4f8bd5801fc397f8865a2f075898c2d8d7b5261a17b1f2612ab315cf04d3e70ae45611eb90f54d30fd4e5df77d6a23bbe173c01d832d248de4e435181c1303b6deaf7cb7edb84ba1fc5d8e12bf204827559ddf22c63d4d345344725aa1c9d1f58c4e39efbc2c21f7fbff8d25b15f1e415e72b2ead357c79bb27ffd99a0803945285b58dba10c428162ec0a6fa8d39f77bafcf212a2fe3a4e117f87d670d6a1c9665aab94dc91bdc6d5450a7997dd968bd3783e8d290392aa9c64a66ba1fcbdd9031b8bcb80b2c815aeb8706fcf05e6aafa49142e8fe584e7ea14621318fe341d5523c4f5eb96453a7d0d390e2eb7879cbca73316443f1fe3c75ce92108b230794e30f42388e0b35a41fa064dc655ecc5fd0f1becddc109345e0f8e923fa1b57763dcf79c89047e326ada66ed63a94d4e24bb8a8f0040561e80740f608656e75c15d06facf6e348bfb3a16c618a8dbdbe09e46209e4921d2f17d6adffbe04601f387744dbce24bbdd4fc997e750fad11c16fec7aec3d8f22d4e2249bd0d2a1ccf0eda0dba7e3f1e1504d76ff4d661aee8b7b1062f9872f2616427385a49fc06168284900fa1c00b21e76d6d14571d8ef85bec6f417893c4fb135a38cf1d6d57f22d61486afd92af96b68bec690230b995aa18977a11cce699fad3ac29a0b1794e73a8066d71cf7fd7218ee9cc9f9e3727517523ea5a1e07c295600408ea190bc4bb45da9d50bcc55c4512f3990ab9ee975485207ec54885f28eec2566e28af790cbdc375cbd105de246305ff0ed36277f928d9e421add9d1b8b897729fc0c2adcfe592d16aed21d99659b67fd17540f3b28e3b83cfea71a8a4d5acbf25b369a8f709d51ee1af3978907879b478b54cf37533bb43c77283ec4572baeabcba5a27fac46764786dc1d2b87d9d9e6904e6f82074dfcd1e0ca8a12762506172a90c2372c816252b1f9e5e6a2d7230b02d940083da713a33b179b0225f928e34e57100c77cb8b0d1f0fb4aa3ae19110e25c8c5d714c90202323b4fa950036fdbb6f35ebca5cce4a546e2864a37537fcd5523d8dbf8e3d35ffae12391f71fef2f5833d20e6fb7e313d4c782d7112221a875231cd54b163c6fe8f191aaf2cc7af4aa2d4c9d233ef9115c23f56e6ad7599bd827fb2d879326eddc235505f90a18cd3b6ef684fd3989f7340a56535b56fdd4013ff579f6cc1d568b4d52de4164d7ada29b0cef596e02b3186988580cd936e2d18242022c825e195b81c25958b2de0880d897572d864fa17feaa1545ec0c125fa472d2b118d1591f480a8bf82a653734188427d03cb86143d18ce6305e0476a2d8748aba80c48d9b9b0cd9242ab58c53d702dfc447c6b17346d9035479ef70a10f8f5e0089a9d4bd687c8a74f0bb71499f0637d44913f461b18f7560c2888ecfde3899b47920c428f81c788ddcd0fe2b029dc2e31565c92c21c2ff254a7fe9969ebf66a97981dcd2f91694278f298520e8ad070a45d845b34148f9140d72246ef0f9a88ac4ae501d6a713ac6a600f1585823b2bf389b3fb63788ae8fae1ad486c530cdf32714c8d24cffb019bbcbe055c95fdeb2488e35552dd66ad14d0dfd7f2aef2c0e4893f0508b6b3d23f828bb4592bbe99ce12f23cc00a025064f361c7272eb2ea5c38a8036c34f22b6cca443aef1bdcfc829906dba7acdbbe3b2b7ed996f1bb33c845239052fe8c8a13527dbe53f47b9f6c330629c33a217952bea341195b91d6dc54e5af843c735defce0371b7c51692c5c23d180336a9f4fa025a3280707d1b0517a2cc46fe91f87ff18ce80529d24bce9cc8360933772a4f58a7a50c0206874ee44484ed37002ddb8aec3a9c1ada3171fd410132493ba7b1afef487bebf0919aea3f563936532938a239649d0e6b804de475a150678ec2894970b8cdb0816a4b2e159e4ef0badfc7f7f3a632cbd040f5da4b541b0f2cb29cc481ed7275cf5f4b779c85a9f4bde812bfd00359c4432612824d7b6712196764d3f563de3849dec3c8db0c5c2a4a233a1191b0eb4d3b60ecf51d3d4640aab4ac83a25ae7a3785530d7c6b81d1e61fab8edb47f6afd9ec80e6d76a5fcbbc17e01cbc000f2f36eb2e3f74f2bdf06980f0c64e27fe73b42416de02c60bb81ee40a7bce033f75c7b7a7cedb35869075bfefd60eaba4e5447d69e4800dab388989cc027e4380c7ea2fd50d7fb4039a495ee1d40e94ff76402972b0c57a8f848e7ef42943998da34e682b1037a5d4f5ceec82c3226c1d0538cce2b9bb73cfb78ab7f8499d7540a63f9b07e0df3a253fd55d5f4306e1f81ba697abcc76cd95603fd3401319dbde87be7fe0f760cc92c08f155ae0a068f04193c1e7f98846a2e256f087c8ba5a9c8189908d10bd30606e5f685e92a8eee8eafd622f1e146d93044eef53395b1d3368a87b4a6b27b11f21cdfaf75cdeeda684f0ec7bb91e04472b19bec99174e6f996435293631ed0770dc9cec222f089811da05e4948dec445eeb508596caec3f3ce738083a2041cb976ff6b5100286587994ccbe31edb0fba5acd1b2a69d4eb96062a2f4a4b668d5f3b5a71a7586ea8296facee1b5b4a1d9f592f0f161f1588a05057e35467bc2628e18fcd927e152ed89d84b33e9ef68bf9270f4f593ae646ae660806c27d00beb048e5dcab3e999dcc5dd314069089a26a5dfe5416c588970433b10771b114f27d6e1b7cb57a00cb67f2ea96540bc68067b9038e4ecb1e5052e2b5903b6a88506960526c71684640ac3d64a0df67e9154d4161dd90eff4a55e95aab70809566b1d9e9905e80d96414ff7413b72a0eb202ea5c1879eb7642919ac939cbaa254847f4d281109acb220fd2e88a52dc76f6b6fa5cf3efd719a47b5195c1be675f38da77bde91340994588259591aa20554c83ca7e37e54c38bba16ded6b31172c160a49e2a6a26ba7b5ff677259b0e96b68c6bde24c1abdcda73a1b816175d6c95e818862fa95fed7dd29f84bb08e97a4649fbfd3764f37344c7ea8bc2a2567feb3cac0751ee3e6a1453fcf97705db7461a5494d244c8d52d295026371910fff45969fd430156f589ac8bb42be8ae75382bc6077b40a5fdc5eb527be66a2acadc29af6694f94d2abfc7bd6105d1ba4134eaa69a98e27b4969c5d6606d1aa4829d7994f6fc3d2f036bdd39bcf1c6089f2748b4420cde9529369d760a86ddeb26163b5e6ce06bf33fa7b82e18a80086d0ef8b54fb352628609b60906bafb2ce0a6be053ffcbda67a546733d99b441c61f21f81291021890e62c89b10e005e58dba73a05b7a78df4978513fe601d89a9ee643f01fb89bafec91e5ad17bcfe72acc3b7bd859cd147d0a8e33ec7ffb00e27c64a4d274feb9a4ba79c17f7543b6a216f1e1b5ca009af538aeaa019ba81a1fbe311afcff9f4f9f182cab2dd18eb7deb27fa08caa9b0b23e4a7d8ca66bfb422eb8846269c6dcc57ec8e6ad32a273f2befa0e91b635d1c66e9b1e00aaf33a16122d4ad0fa1514980f6ec1ec0b7858d389d6c67a15789eac530bf01826d18e0ab706b453da60fe055c9ba5c1df31f3b9e857f3b29613ad75a67c9cc34086b6d7cd58034534940e91026a8cf93d47ce82163feaff45674768f7e755b8743baf4019612c1958328fe9bc0915cc64138668b302b5d118c865ab48ae12a58be525c9d49a4612c376118d7f27e215df8dbd4ee6181182904d6e92330b61aae1ef10045ad689a",
+ "spend_index": [
+ 0,
+ 1,
+ 2540305684,
+ 4294967295
+ ],
+ "result": [
+ "1bdf87717a32269847b30dca87757d9125ae7a4a7ba54bdb5094bcd3ae8c1942",
+ "8fa39fbc122b1e2d03f52b209358ccba778a27d2466ab4b7ded97e042c2d718e",
+ "a985ae74fc1d0b42b8f04c1d1a49e2af5cb2dce04e1a9dd1063110874de5f091",
+ "60c6438d4af02c56e3767618189fd4996076ad5951120197639c72d34f5e7684"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": 715592854,
+ "scriptSigs": false
+ },
+ "hex_tx": "9614a72a00010244487a8400000000000000000000000000000000000000000000000000000000cd90855900c27120ff4dc0679500000000000000000000000000000000000000000000000000000000addd625c0073cb3bbb047a8578e8670b050dc8e81238df3cbc31c53a872208d5e486c4c6f0c8e42c6bb480593f9fa346500640a95a38ee4ec7038b016778eb46a445eba8fc434859693bd099612e91d72d0a8da21ece89d9a0956491083f2daac8945aac13618c531f63acf3f423ace99b996e936bb91f6f532ce34aef686ed4561a101829d37a318f399e8927b3ddd93835f1b2f4509ad45c07aa2618d0bd4918d77f9d84da4df681ecbb96419fc27ea8dafd1f2657f039d6bce777bb7027679fa6897fd8a3d0410d7a71ac5e914b8dbae0246db86c6a03d9b3d0eb8dce9c3f3e7831c8bcd08cbe5e3fd00991116e8f98776590e257dca41919059ae37ac66e3d84d9cd38cb8f0e9b4f76dd01d3d18f0b8a8515163edd7f2ddb6a8dd67dec94f2cbe24c430fba044f7f938f9a3c6c8ff3f80692ab19cef56cdfaa5ad05637b3125d23177ca41495fd82c673ef78c0930fe7d349f513a4a21a3f2f0d9379a9df0e87bf7e9f1e1d0f04f18a735da44baaff3f46e798fbfc107393be22a7fa6f4115fb22d861ab986391c9fd2a9afa441c8db8a0fdb5bc6192cf2c0ba30e3a3f0ce9aa8df89b9afba0d8671363690a93f4927ff73ac81fc0c754a05e6cc5aefd1e9a6bf163d5359460e4ef58ce9168a65576d42e71b677b44da0c72c5eb6ca33a0e363200bda6935fa89e898b9fbe26308cb5227409afe818c3c17403834fca308fb4375db0bed101aab9344203a01629f7deabbf91d91dc6be20e23bf9c09a8a9996935f76ff3322675f7b8cca0bdb46801f8a9dac35718b91ba7338b78cb25f696dd0b61316f8141c94b5a4c78e2ecad292de849c8b9fed939bf509536d01245079fa9516e18189b213343a8f671ed293f2f68bbad654baeb1847215aabe8b0148dfb58905c8d8a0ebb5d60cf68a86e9e3c0c10f4b793d0cf0b2d572fc6b6e07b5561da1c08f42dd827119ed706efc184c781d5938c810c479960213111190b658e78cb2488bc6daf83c3d344ea9aa34d2aadc0729b133869a1ea92de26275993ca80eec33227fa56c19b0fefc7813c0abb06611fd75038d890b41337ff607cccfe5211006eb8e8a218270ae41b46891b46489e58aad8ce43fc7e0b1d99aefbb618c678e74a547d85f461db91b3c3a9dd35627cc247099d7bcb26c0604ca8a6a893dae31171c026e8287f96938fc03fd240130046afdac26ea6e14b194ec5d55c92aca669ad09a3140e600351a34bc8cb92e8267e4f416ac60181f1c3f718d225cc9034d2bddd624823fd5a320772f7201009c0f2f9c545284a9acc22edb78e932e61d4aa09ce09ddd582cbefad60ea3e9e20953549c6ae564df1b6ad4cd2c367f4783dcf7da99d47c895dcaf7a6b77f2b3452f03ac054108c38f9e4cd4c6acd9751029fef96c1592c04016a0a58a9f5d9c2490a1ba9286ef3273c61bda674eab31d6a974e7e7ba02dc3ca62e524e4a89a96f08fa5708461a36c7674588de9dee7c1540a2c287bd5a566cd20b5ff6ff7e3581a5cb326479260c2297d5f8247d0222be1f7c09a58cbc1437e0f91ea3a180b1948ccb0f1de29ad2874f56aaaaab4906166b741494dcda49b16171ba4ff99fb84c41dfdbebaddc69ac0f231f31080af8f04887e59734ec191eac3f1c1a25916b354b9a75ac31d0a63e58c5910f47510821dae0f70e1c1c2dbdb67a14ae08d6efc6a5711c0c6c86355b4ef4048bae9c9f6c3cd5a79d4517ef7ab8c48cee838c6f360628d49d52b9cceb8cd7f0f557f899df6cea8b66cae6856c4fff1e49c50ff9fddad83b3b681c674959cb4959141a3877ff02903aa497ef25cbc936b36c8b3786ac05d71a391b03c8636f82c0d5931b612b75ccc140ec056a3f6028d439db9fd0301ace9b8223e7ca7e00ca9ea447d88a8d6500f302c40e4b13b803d1708271d78adac2b162a30a26f4f0df593f3ea03995efecabd345989970d2defb0a21092a6697d32057e0efd8de0d8599cde438524067b6aaca75e1afdbb1ac04511ced0bbfd4d93847175232ff965bcffc5a07f31457ca97c042c28b7334b7c4033c7a84d0edc792e7cce129c38cdfa0eb9cddafc42a4efbfb16d5f85f2cf3b1244aebf1d89bdf9c018563ab75ed1af53d6260297890daf6c6b7a64190aba1e4ad79819cd241bf5abd87cc989cebb359b41fcf0ce3edf10e2f314aba31565635fc329a8864acaa63be50e7eb76fac299ffed9984dda7b4e55687871d964cc3d311eea262decd1e98e01beca3d7733f03a90e6b04ed560536dc3cb9291b0217597b031510bbc65e5bb3f0eeb12bf7760d7630d75cf8a39dbc7134be2bdb44f2b204576a03d91ee5904a4e548e39345deb04a13859fdf1f3c09b978a4dc2d58e9f461949d16c601b9b8103a5a0b0683dc95d42257e74d28a73de246a7a5cee4103022be8f08141a775672065b73a8403d809d82d9da4d89f67b38e5ab1f692b251b72c5cc19db96ec651183aa5d55fd763119b74a1cebd2c2e698ff797655c176c382c9b3c3c235ced06b696a6e",
+ "spend_index": [
+ 0,
+ 1,
+ 1848110724,
+ 4294967295
+ ],
+ "result": [
+ "12bf734b91f86f14dd3cc42faee9f9f95327d56c5976989d46144b56d6bbfbee",
+ "68621c4da6ba0611a1100bbf14a0881e2486b668bb51f137a6a7deacd85461f6",
+ "b9103641610e7fc11a6a2d6c7bf378bdf4a992fb00933a409c03a8f6fe2c39bf",
+ "6077b14cf061a280c1622f21605f815ad2c68c82d00adf4be7076ae4231f9979"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 3,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": -594424904,
+ "scriptSigs": true
+ },
+ "hex_tx": "b8cb91dc000103733a19e4000000000000000000000000000000000000000000000000000000007a4632f6fdcd0148c8d6c4a16389b5a5ca57d5dd3c1ef98adcfc4621f779a4efd7264b5507c6dcb3c74e752fefdd47b7d1caa92a5ca64724df3fecc1d2785e4a76ed3557532e4571eded0a2385f0a72d5f37f0b1f1a5520b7def869940e1e37bdd5b1b4f710a777fdbb1524335da1cc62ab9df1c3eb313d3d1b56b54e833fa4d89b4cb54066e0c9ea64a8fdcbad8758550500256f383d973adfa2a1b39452bd218f16f18f52248b31b23af5b573f40e41e8d2333f9d5cf2a7af2bca541ee8cf3ca940f7d578b33fd13e8b885dac1d10479dcb9907bf667ac32361148ba268668da91b04a10974fee0a7119262062cbeb3f0de101336b71268c9b20c034f57da61a64d21afd3e8cd9193fe4b16b245c4b46b5e90a77b17416d5227383e19dfa72fe06ea6cb09ce283c07330374bce788e33aef9f19d9185f52e5132cff5220b58838deb8a7c7185d6a2218de5995656cbd1ee2de93c035b339f9d8bf548262a01a157d6bca8809cdfa3c97cacf843486a99a7f280257f2f32846504458faccedc511e144f123ccc9adc1e9f3b34390096c20ca467cae4b30baac6796184a9c933184dc6793d9b2b80aba55d56a8ea786aa081b6b867e7b236207cb01e773bdb2c764549fc955cfaf98d1935bfbdbfaf9bb1c34e3738812bf5f2ac4fa3000000000000000000000000000000000000000000000000000000009404b6f800f4e4f52c163d1e4200000000000000000000000000000000000000000000000000000000aa49db60fd2c011902bd5a2d7327eb901214d39999b3b939b182ed7d9fda9ac45661cea326c1f9b5753da512a87f5170970d375af04284fb973f11b32219935f25d30bde60f32ba7a796e9d699327135b718426be60e23ba076dc7fcf93215cd0703d8ac8c4370f87d09fe19c508a2cbad345b405325d6cc1bff5a9e922f683c888edec5e329b970713c1a5a31c9f2788e6de872da38893e99f5a3fab0f45d565ca28ac675a2ade933651cf73358319977995ad840abe4deb94bc99e11541543e908481f72b05f04f9dba08378d22ac97333b431ac90502ba7bb954f5809f85b5fc48efe3268c60d964caf9f7ba726c89fd3654fdbe1abd99ebc0f4f702e30b01056377a114fdb25be013e214d6964a5517b3c173b4e92ce28fd17094450993f53a9d66952e06bdcda1ad36ed9c92cde68183e06c22cd804f3b509f1c7c4ca07c8379fc44ba9d006767866231e4cddd1027fe527f14d60674a861a21f28ceb777d5c9ccf49954860b054bb1327b2681f6fbd057b3ded7b468f911a440428c5d9b290fab62f9b59273e01d7f898e7a7c00b689a4d0be67d59abd17d8e7082c6e66bdca13850fe754b60854eefc36981e45a1a3b6d690006fefcf9fd2521c6737bbfe4ddb8757a804b38110f6863430d3572f434eab01b5f60a692b9da0ff212e63655b41232403d6e4b85367b634c68f5e07b975ab3280c3113a03fa2e8d50c0fe015b1380e8887157cd539e16dc10a5e4dc82209755d5f1408169e4e8bcfaf4b6e3db0a25c4cea61f10ffa82d92d439599e3e594d2511ef4f753a0ecfc2f3e34661d295c73e6507753ba7c7f7dd3d7013bd26e53c71a5441fb85620eebc34b0142ebe4d7bf4aaefa69b3a1efe51e4eb1a72d3b4f58a59b769c5c8882e2774cba2011fbc7326d0dc542b260d5273454c137a2f73f5feebbec4e59a13d97c34edb44d3a4027e8781327af40cd4d36ac83057f0a4b65e89e4c0dda809335341dfab0287f40996bfd5cdcee0a23491d766836c1f9cc9ee5799a9dedc12ce1634a98e2339c8f6346e806db1df93013c11e1c2a3429cbb6a07d0198937853b0003926a6929371c0bda000bafc3b409d23f13dc2b335e3152639c182a65a8f5c5139f5951f958cf4954269c984302ca5ba5f74c939695fdf8351bb55406aad1a0b8a68ee6579e2c68955eb94f6d883487497966f89eb3c5feae5cbff08bf340af79d58d8c3cc5ca3e13ea626961cef01c55a8faac81440b1b74684a57fa715238b1d8c94c63236766fc25fd9f271c383b05a11e7489b87633a4324b85846b4487ba9dc62d79492b8d9805a2678cbdc225e7a3f050d435c846ffb53ae3f839021229acd939c8f82e3dbe86e13c6b2baf38d9d79aef51db0d0acd1324967c7fdb5be42bb84f267e8adf0147c3b31ecb979aa31328b3799a076d8400d246d5db9e31ece5bbd4eede1dbe477f420023f3f930a0f4998b543f035b2608e618f862aaa7395256a617de91104b19e2ecc4ac3dda6f263aa4cb008f7240fcc88c590382ccd2d8c1c6194c850d2591e1745e2d53d9d8fb183e28d2a33cf81966af225f0a1219cfd6e1da9a398099dff30571c37887d8d0f773ba1593c39f9d2862f0fa2e02fd710140009c89fc7322fed7a5f14728db863b9ef494fcf42de39dcd6e46508b0f2e000ba263b93570ee6f028537bca50d87c7e22ab6b8de23b350317cc9bcb94841cf18e7eb68b8fdbefb2025401bf2127c417e996a83ca6b74e2f4d20ea1730737197a6b78d1a057f8d67d67ee0feed3d0f30d6d1cfe9d948b7f0a86c6a9abe525fe4b56ee091ad0645ec29afe83581ba0fdc09d1b0b37d41909f6c60aa506e658590205ed2f454007f46c2c4b45d799016df71b664595da3df4cf08f6de7405563b3035809d80cdd027214a850f7757f029d2d650f349437e71f55b2387ebfd5d3e0d3e250380f6f576b624f2f11a964233c1fa3cc197119aed41f7e00f2128d29d77f90c799f024fc0fbd3874b349c7c3f3f8f5eaa86ddc39e4cb5cd84bec069e78b8a4f121746a5a133894a41385a88f2df9a1707f91c2e3d711bce65a32ab79a120b133a0ec8a6760f511f04016162d646664bd2c6455c79b7dd0738c9171f8d8c108c5ed2ab434079664e2adc222abcffa4cd5adb4a5ca7319ab0992c74bd8ed244dc153b58157549fe6efcfd11dadf190982171b13048d0d85fb77fc79d1b4eb8e9fe31690c6a452c3872089c4b472ffbba59565aa2bcf086161d8aae852c9311ce35476e2d35a99a475fa7f2b4a2a2409c9432bd055d848c2f5cbe4df9408a807a039f8fe0bf927d4d1db654950fdd81f42b4e96d1f7b8f1b228825fa4649d0f506b97b269b0a3c1608076adc62ec5e5ab3ec4954032858605a882b64b5fd43ea52ebb07882bca68fdaa40395a0748655c90d35e62b80ec1f8b12bc92d758fd18010f10e77980b531fe6b9e2ac2c2a1055925d8ee9cd24b0b97d8bf6a7c8345aa410819a86115ba04b717d0a92939bd79c564564700160d098fe4001f9187ca250d880b0880dc7bb7c6ea057f638c3496308c3f62de08988e7be3822bf75d4f757d70a0ebca25fad075d8d131f3ffa979ae3787980143b9663aeeb7c8824f00d6c8fdc809224d2e12fe206949e51d85550e200484c64c0da3fd1d1674b03b5687350793ee567ef211acdec4690a0346460144a4b745b34e7bcc87cb470b4c5e61fcd57033a0a2d3e15e974651edbc2e36be909f083a15fe9b198b3081731d4d853e386ff1902f3941b2de824db6b3e85346743f7e4150b3f69a841886c9d789b15f9f238320f77748068c4b5ff760a6e69a834d98b5a1ea24533e9c10a5af5b7d6d61600699fe39795816bebb6626bfe434ebcf1d33c6fb899ca446b9cbb8fcc29a38b7a5a997425d7ac0b3efffeb344cc8ada7614592df78025c2964cd1fd90e9444ca3e8e40c10590fb0e531aca63bab19e9bce562bffff0a06c22e9d992cfce03745ad4a2bdb53dac2dd87d64edc352327a6785a213cfd9bd2035fdfb9e3c680cfcd45213d2513c7e9dee7863eb2ca087cc9bd4ea9c08639290f32ff31682e07820d044384081e750a750e4cb1f8590cf4736a05731072e430952198800f3e586ba605761acc305f192dffebfc548b18cb91c21751123732547d8c784fa5a8cc952f9e941436617cddefadabbc1b12e90723193e8fe213b21a49933a72206487e43c8f991ac1b556429bf99eba3d130bd13aab01e9ac6281b548ff6824de4a731c81bc5cb328982e7a36f239fddb1dd4007cffbd56dc2892c1d6ad42a6f9cf2ad895ef837ca7273e6d56a48f36faf6a42a1bac12a68d5f22cf54",
+ "spend_index": [
+ 0,
+ 1,
+ 3958408894,
+ 4294967295
+ ],
+ "result": [
+ "17f1939a60adea501d1df741db5aada01c24a58719bf9d2b07d55a27c7bb1318",
+ "7154f2bbdddd70c4ff507b69d410bc417d7fcb31999a263c91d8bc791196aaa8",
+ "55b6cc0bf1f740b527d2504d528b14d2f984d341884c92973dfdf2b9eaa1bbc0",
+ "29078a5f9da6ba1a90c08ac1432132da1a4f3e980113ec58aaba74c3073e4e2d"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 8,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": 337442454,
+ "scriptSigs": false
+ },
+ "hex_tx": "96f61c140001087e9a414b00000000000000000000000000000000000000000000000000000000bbb460020066e56a7726d9c16100000000000000000000000000000000000000000000000000000000a0da8851004bf105cbc37b51450000000000000000000000000000000000000000000000000000000036ffc13d0086d145c39025520900000000000000000000000000000000000000000000000000000000b042386b00f41b6f718073966400000000000000000000000000000000000000000000000000000000a13d214d003936d83037240b7f00000000000000000000000000000000000000000000000000000000c1f53e5d0032f83feea6e61ba50000000000000000000000000000000000000000000000000000000098a6c744006b7b9bea56d181dc0000000000000000000000000000000000000000000000000000000068c7606c00d0ff126e0139c1cfaf06e77e6fc81d2323ad8d445ab4ff24813f6b9b014bfcd828d4f1e90cf35b8277fdb43c1f6c7f8d6c9008bce81f0c36a9b4f2cc394d17f6618e672ecd63b31012109a297fc6d1bcc3802ad8bfb7347e7042f513b97fd3c0f0ac2127367c9a895424e046b5db194fc21c25a8ce132b3f53d82621d0511450386845a0da04eb360f133e6047ddf50e32146783d2acfe5c12aa80e892e4f203b1ca89392db85d18c64a80014b67bacb29e73400476de764834c9a1d4304ad44ce0632014349032b0fa65bf526e2d7c66081964c6ef2049516f52f3e2154e69ad2999431baa121d75db2488e41d7bd5b0cf20849efedcbdcac5d8b4ba43c773aea376d4b40f9cf71473900226ffeb66689667b7ddc6bee7c0e9de94af8af85b9d177317165f8f929145eaed786376b37e98b5aa847bdd95f416722dbe25e08c0a5828fd2b7173f904be99eb2024834a43e38e14843005b9d6917f8761dcf87e57db9a7bc7dd13f8217125c408b27f72a56da0550d1a1c5fa76d7e9e41287d37e1bd84c3b750972b5be044b6001333012155a0143dc25abe04775ad7531ebb5c763d5a279675ca655c52a80cca830019b878151c86af32111546c7e5973da75ed378a75d5b760282f2504359157d8bd69311d0765c723635c80b6659c438650ca6202b421d2922e629d0b3a6bdaddc6208a4ae49bf9229752a8846291d754a28428aae53ce63a9c62bb8ada059faad2647b27e7f5200464361b03a3eee2db8609432fc9f77275ab7bb9ca2fd361c7f0f91771f3c52828ec4fcc12455b9deee62106cf59f415c9d18b39ce909e8687085338c2f81c6c057a190597249c39b63795ce575ad760d756302fc8cfe391d19f9ed10da1e64b016993d25b14fd5f01ae8c13e28f211da8444cf468eb3d85b22f47d953a2869cf4cd9db6c12b78025b7e66cb7f5b1b36a925edf3b550e0682d0e57d6f44bb21a7532b76c6dcaa9e02ff60a38d2e795d934b9fe08c9ba900e46abd8abea41c95e9ed7861272fb2031adbff68a64c20f300422f770f2e70a148faa04cff451e396c6f6b9ce6c4a496396c63f25ba627085f0959edc0a13eebcc1c3e4707f659e6c3e0915e6273ccc89cafad3807640f8e0b1c186582c9f5c287b4659aeaf4bdd8af0bee10ad39ba72d188173f8ade7f34606387e12944fc000c6351b1d05bd64c0dd7994cee575c93943a7282934536836210b9faf05a0aa266fdc4a2dec83e2858c544d054a5ebb05b0416e8e3e7dfb47c675e8262d02c2a45a4713cb1edf91b52d37283a307d7dfe4aedabf59a6222a485480c5d8d6d12be9376dfd25e0a51fb3b7156f50231a672ce1e27ca8c57a3dbf4c9ff16fe005accaea603b3d5cdc90abb616b39a8e8111c22663ac0fe15d554cb77b8c58360b3a0e49ec7503b32ee9beffaee1f075d97c22074fbe28810372ebf67d0a8f8de51e3e683ba281f3324ec536dd2222642fb338c6734e4a21c7f9106da99e2a54f681860cef364df39cb5fd217ab558e7a30c005ccf1cbf94909efd698dd2153a303e7fc8b4ee46dca657e3dd5fc6d90828b04cd67a99ee5cee2f1eb68068d97cac7aac69008bc41d61499fa95da1831735ce3a5fdc5edcda61235784e04771d277bae6f06548a609c164b885ea74f76d259d1c7edb1d7d0cdfd493155025ce691d6ee0729eb73cb86658b004ec6e9bbea2a95b899f7afaa8e29c8b9ea9d98b744a487942ac5e604069450b9986c1e1d4cf4e392c7afaa67ef0004fd57016fc90754fbeacafa6072ce2af42758f4e60a67c31214f0790599086cb75e0f1cbf5dee78af75591ab769be419ffe68789d540bb81249f039f3ab1a57dccd3c288064993db495db279c9f926181a39c35017359214c70ec64fd60f1114ff188e181e7e741b873217b06d791a6065f8e1be48f37e617443e18d497cb725b9fcdd96621e467b8a0a86b324fa01210263a3250799ae2e12232f8d782ac03229b1977a2fa994dd0d19d38cb52b03cb48c1bf4e06da1da5a64de11683b526cbcb2da296bc81da6a11a5277d709fcda6c7a55b6841a421f51681bd60741d9cc1bdd8258ab809e38b2b29bba58cbb50887eccb0953bb6b8f55a2be09ffca0c4b7bcdcc6e9c72e3e38da0692bc189eb922a1dce4ff58aecefba92e64a65dfc2247b79e8e1cae4b8e0fe8a149fa20427d6b986ffcda76198b1c196e29d40a8e1e4bcd492a5b7572e73eb157a451ea1a8838fd48dd491573bc374582ffd5a0101e268d28a667d973d2d37458f15f17389f3e54a5297d947180eb472eb491f098097b927dd6abbfd6f76381f82c9b3f56366efcec7ac3deb41db2db24a8e922e2050aa8f62b1698b1bd3e879af52cbb5f202b846a12bd05ec8331669628f30b5694e81814220093062e3cbaa8031c2214d732c069d42f816b2be2f8472fc7d3c8b7c614f18bbcb20348ef0a8401a087876bcdde9393c529be6fe08d4a874d656ddb7ea3bdaf9ce56f665c0ed2f29aada7956e4d1adf52197fd149353e029779afce1f25f292685e0d4063f412b16b9ba8041f356ab194b975d8cc352d0fd7ee5eeaac01af1f8dd831302cea2bcfe5d81005e9b73d24f78d475b19b1eb90502813be650a643aa45ea8a101527a2972b142b8366f4b1ecc3993efaa5f274a9719cc0ff12ae48d7899626368c3939ef9a7872fa70113ccce16050bbdc1c2fb93d19643f6206641e9a776587c0841112b9b96dc8c4374a97cfae1936b031ead072db908e8814f75e874d8ecb4a413911b0526cefc5342a667d559ac61fe91f864dd0e4e281b505d5b31a3279dc4a928ec8ac983952d5dc2cb6d0ab415d7e020e50c9d9125b443ea20f30f9304067eb920a6017f2f9e71a4f07b4a1aee6c1e4d31ede35d897e2171a009efe4cc90ae37d737799cdeb0b73d2ae9ba877866d6c28b5b8ce0f22f4e92849e62862bac8be7fc2d41aa401d642cc7ed9a7042c73fd2598affacb48d1b7daad5dc6e061d390eb0cccdd5ae1ecc3a456a4e8bda8df96659037c2db23c3091516b9a625247ae9bcdac0abd7a987823d702b2a8a3777976e59ac32243ec83abb866bc627f4d0443575f7624b280286acf94e5a1e9c694820052b0f669556c54cb6422055d116f4fcea86fcdb4a7ab7534ce594a5623e7486bbb003c843520bf3a3f38c7ac8e0b43ccc9d93ac7cbbef8933b0db6f14ce144525f33fb9908c5eb1359c95bca252ba90528fa5074d639bd0b9a4370faf11d6d4201c0b4d6c0d9114f413a8f7fd0e259dd275460d030995e54fda775e4d086b04a503fdb8016af3746bf16cff65cbead0c2f4530ee5fccfc69e88e64f465d8ab44509bd5000579d91be86675a6b2791fe4512238fcdd5424e3ba12590d1a0698f3ab5fa3b3840ee3395487a230b884abf9ee8d801b6e77b2b4a4258016c31ca090dcc9a57a6f47d93b1fe31f6a37b2d28eb0b2a58f79250ce617cfdcf3a6416ecc39702de7372489e6900a2adb97c3a4a8eab7e173afa9b59931bf6857796f942ea25cf831f321c04afb9ac09bf1c15e732533c667dc53da916c447749ad90c805c7e2be056c89d4cc6b84a1986e532af2c08d86d7c25f9f8ff6ac8f3169850693c798532c6feffd10be80a495e406f8451f9d03929da93c70ca9f6c874a2288326fce6587b5ec8eec8bae34b6a930a515941546e34e8a758adb74a8e818eb843d7b30d8d3e9ec5a569b285246449a5089994c69f44bc1997a507ecc2160e5461642b2d9605300aa63f0b38e194ab60e546371fb06469331a78aa516b811ce6aee14ea202309134498b1f9fc082e6ce77441b602d41ad34910346daf10c8349230503a54d937d758a5661100ba17bc2275f1c66c78fd2c16dc8d7157f7d196b25a9a2c580ce6e92ad7ac950469c0a1cbc4b7bd7d9f8f0f5d1077ffdaac3fdbe019ca5d7f0036020a6708ab4fe4ce27bcc795b198eb6be3adceb37d825804579a88f432f183905554dbc390b85309746d4ceb274de0e805b7406c41c6ec18e9ac3e9eeb2b3c9c0b99b91dd63545c4c3d7943f81fd7408c4de733046d11fb2baf0c5730dc6e1b8a865ff1b99b23d63ba23455d699f14a209b092e1c02fc52254b129009be00d0598b6e1a91907515661ec67b9b9769379d74b536c19cf8a6990531f68608bc355f45c93335ffdf3744fda9a83d71d5f2258f226b1ab0c3340883b7a4ea4bf70462deb63fe251ba197ab63e0ece6eb3ee3aba4926de25730c3838a4a44cf0bd31e2847adddfdb6495df84daf50e2e17f7e46fd0238a001a4d7b9eb7d6b7632369a61c6f14a82639b479566ae06eb610333bf7b8b1ef323efb800ff4de1812ef1befa3b69d164f9dcda7b042c85c3023c0a65d7a5ba828a09d4b201a8a79aeb5bd2103a4ac4653f24b71e722e33e86c480bdd3c9756267389186680ac4fb5019c4c26ee8f03733f27720bfc5e21e61270a7a12d4c0027c4467a8a998e94295a20f5597aa1fcf92d913b41617ef535092e35d7cf821d4a110bd1105a899b2da6360b78a02cdb281d358652d3a26d6b04b1b498bb8e12c175d01a2fd9801df9dde52c5e44d1eefa91321418c5321ae7afe08810f3a2c7b311f63f4468879f3b9cab3c53ce609e24e94fc0b753e8bf80d90a1e8c5db717da41626f806c453b99ac2856f923c420567cbbaeed31967955c03e9782e26012d85e2fb58c556cefbb782b0052ad5e2a7faad748e9b167bff703460220fe8139ac904202a9ea095f6b713007f0c2e51a7f4062d3a6481757440807ea705d31b0f582bbcbb21bcc92c68902d51c4d8b2c750e115e4725ce6583b9353089aa25706edb0d02ca5ce458b9ada4aaf5d9eb67de043631b5a334277134f17eee9ca692ac519645b98414d35fc63a40ef2498f4e972511d2ad23e928432cdf1c17ff2191f49968b9c2fbb2a19464289223a2a1333b3b462f972affda45de0669248ed796e6bb65bd547b31830d3ff7680ebfb8a03f3514e73170b233975ca725466c00091cfc48d6d561bb4c894c0c393ea0882f517ba5e227776e9f47a78042394386698118971ea58cb3f4af225d898a9d355e5ebb30988d4fea2fbea217e2f628133f816b0422f67fe05f9fffb64db1e0d95ad7765334755c0e7ae90c6a36b7c5ef0001fdbd01c1cd410e6e8d3f9ee6911b7b10a3fddc7a69757211100d1cd938e19c38ab13bbef52195be90ed215828c948e06b11254b06d0c6332558762f4979b30cb16b5d44286c55d44d7563d9c839aad43e794896c39ae5f6c59d1da00695a25556d61f9a257b9c3b6517b08270e567d5983b67284dc702a166a508bdf5051c34ed68d271d94d1c4cab7d17fdae3fba090c99c306445b6350200547448e301728cb015b3e0ef0c5c73c07d54efd942290ee08f7cd24ffd68b657a490bbfa623f3fe91d8ec8cebedda8827cc4246c450f9f313bd44bbc9d08a60e29e8a6448cccf1c8d78b93cb03fda2c837f7f9aecac8583ef11918b057fd1e6f28a2be0fc65748e7ccb424db21beff9cf3de47b0df24b85fb82bc39820c3ab56af99e42f62cfce6ded2476bebfe42b1559551a6954f89b7d66a7772cf0189ebd69287cc0f4f7a6d3d6366109e2509b743ad3c7d30e1b31b4b4c2fa582c6d04f2e09d880be665017504ff768e201612aa5eb10a967f30267108ca11768a25095443c0c6c557306ee60e463d96d38c46adfe2213feb5fc37aa8564dbb6e81ff381b105d37b1fa50a5862873e010305709d23342e418fc8fb031b59862f9581176e80963bb6ff4fe903fda3012a65baa205b7d619cc03238a5f7b8f9731ddde6870823bd7aaf8bfef5be8245aa6853c9f132e83f5e8492e3efdd9a807dbf1e82e609bb6648721ba15bd3d6bf566b7fee38583029b32d1b955b08631add6fbc93d023830ef70d12722f7c8c98fb9b5bba967e32fcf3c157d40b9507c6fb066b9224d13e74037bcad873f92f6017418b64079106900d37814696e0cb0f7ab8cc2d294383cc7ab2a7402b2d7ea5549ac71f7f34c4c762b549ef6f8baa07f33fc146dbd707a295badda26add005e6398379adf6f9b39b1e9aa0f9c82bda37fb55abd53431c3a063935f52ddb91d52c94b0b0c1c4c6fa2d31f2f5e04ac549dfe8c720edbcea0bb9d9f97e1006b078064626e24d692c5370e67be6af073e873a0761f27ab126f32451b00a320ef456ea42a8f474797ab91ff0d0cb2f5a89180916f366e6fc59496323321c85c4fa3c3e0608af8ba1e9ac0e137292888976c8448c4bcb1637788def1788eeb80c3de15dda09d2aad4c8ed4e1cb71e4dcab6ece74b3aacc5f07d01b6e0ee79a39d38a925fddea413d1d1a57e5d014c5cb5c9dc000b083c9fb5ed3a653edff1affcd7219b57b7241ce01e88a3a7e0f0065f7db7ffb1ec66a671f61e0b41c03eab8409a96f8d83c8322078e69ea867a80daa82bb084f48aaa2703b7211032721a5c4f1fcd3b508e8a6ab8ada0776d296f68d80c03e3c958c9ee4c21f2a89ab2d67b82f1be09b9fb06acc787a9d50529ba821181d27991ee4b322e129565f864ac521048677d2d068a8cc33e6da6fde37920d1250e9242f82c0e22cbf6ed18008f541fc14b2191f6d933bd82cabc1f8b4cd225ca5ed054ebe65107bd3e6f5fd74839b4bc4732126a9283dab4c2bc24325cc63933f583676d090d56a9a1addd38032256e5727d692992225a56b23f6edefab70a7cc0e4c998f63f1ddc0e68dd057e59ad4683808d",
+ "spend_index": [
+ 0,
+ 1,
+ 160980537,
+ 4294967295
+ ],
+ "result": [
+ "c2edb65a3843910c8acaee8ac8b960a5ddd4bcfd62b58f50c7a4cc5b8d82ca3e",
+ "663c865131db07c41a98fdadc60bf6144caa9f1996b737c97ec87f32ddaa3bbf",
+ "8d9f467cbb9282aca24a8b49bba8efeed62cc664d53c519804b3ccfe6eefdfc4",
+ "4e6c8c853edbc3ee372ed7f2040712ea193a7e189e99e0713a48cec8117e4984"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 2,
+ "Witness": true,
+ "Version": -208179031,
+ "scriptSigs": true
+ },
+ "hex_tx": "a97097f3000105fa25780b000000000000000000000000000000000000000000000000000000000f7d92c900ee8828a0e9b2183400000000000000000000000000000000000000000000000000000000b046100bfdbe019441f12872f8bfa445d17f90616607523132c5d6fca1a335dc016a94ae83d7dd70de2cd8cbe030ba58488e5631360cac3cba5bcaa10a68bd87bf6d5ce18e635089d64c2aca7f6f2c9064365f40f5873c66631fa54fd05f4720ba3e2057292e8bc14744af9fa6bebe0f027ca27486841a6bc46339e7df5a2b1ebb3d6afd616f430eb383ad807aa5ac6caedf6222ab3f1627c3f8b32c030cd06f70566635a069016144734ef25708f185ce935a993e2775a7f2a30f2bb73175251d8997c977db9b5d9a84c921624a06e7a180c09d2d84f37c750bda8a20036507d60617252ad16e6191b660c576f6170bb28e3d663e40e6281741f831b71003480fc74d8e437bd83332706b81e060ead39e8146696582e086cb51c83131cce25c5de2f74730e60f184791fface969ce21fc9ac64eb9b166ec4285ec090c371148e355c933c99f79c65f41c70413883a4f2546f0f303b844fa094b30241ea26ebc3c9352e559db36c4daf13ab29d87611f834bd49eed37ab81e9ebfb64d383eb0c6ff2adc6f2bbbeefdc8adee724564b3719b9d543bf230f53697df5df96bfcb1a929e9be4985f195f07c00b4b97ccea403489243649088abb34a5b8dd9ac82bdbdb29a10d5134be33e6f83183f700000000000000000000000000000000000000000000000000000000fd3a8efcf80bdac12a52dc284e40b9db3d74be831b67e9ad572141ee9bb1801fd8738efed388e93660dee7790fb483981f8e1664c6d91a0ff75e68b36bba3ec063062e9fc5bf41841aff600f3c192c43e83194abcfa1f0527c9c7b7b715fed2872fbe84c9b5cf0addcb030debaafe86ac33699dc03dedd6f24c3c87f54e5106f99a5772fd6f7cf13fdcb25d4e8023ba4867e72666e58c4f526e2f2c3b24d3518948aeae1bd5f331487821ae32b4607e8b1f1d8d9e33e21b3a46ae09f6a32a79971c9e778587b656f8df55fd78651bf7913bedec1eb98d3921e5f7d6265a0128ac243d98bab396dd78a2635a9734351946ae5d013e6bf7f912be9e0bec689b93abdc22c0bc80000000000000000000000000000000000000000000000000000000010c9f8b707c0fa690adf9c10a15af0bfaa0194c0000000000000000000000000000000000000000000000000000000001653f913171e35851593fd7b8dc3f177d435f7d76d5d0351d3311c27ba9c677e020bd5df2e915a8531c8bba0e037b307c1799a180b382af53518861ffff74c5ca7363611387d3f548248e27d22b5ce473acc247f62cb590ea5dc8c7b7d3ed9647d508513efafc78168d7dff4be1ba706f5f445b7d4e32c0fe7026fd6b5d262604dd134849853955b0f11ebaf618eaba7e2ab56d29bf735b9f3bce5cd4bef65a26baecf830285f3e848db874eafcdc632ee0a28b03d0be14b3e4cbc0b2f7a509d7e89b70a1a183885d81e9b7f3e11c981210149217bc31f4938c31373a7e097d09e4c5cfebe6a3bba73cb675f61af1d07bbc44c35ef2f9262ac4bc8cf0250611ae4c4b1698a3fcf91002298cc5e82faaebce41aa6b5bff6745a0070062b6ca7de680b29d0607d7732cbbc0be090705cd7e467c3f577c7c5fff162e2f502d0b1393d83eea2fafd588f6700574d357d8da7e453a580a117d7a97459137806f9b0c2b842202f576493b8fe9d2085a10f57cacf3dd2f8215681c588b16363073ff26b39635b76abba71890d882516d18f20bc1fc0d19386b20fc24d2903efe5270a8ff31528df06e4d25486003e896a2f8c4bc38929724b9de57e8e9d83af6331310b76639d01fd38011a14b17778860107c4d7bbe9991c9d426ac13f2c16ecf90a54510121a1ca91542b1c345fd3c44109af0917181448ba824ee9a913c50b2ed815f30f1c022edd2b7253306b4540b70e55e6664ff3adacb859968b45821ae0d41645ab293338d9cffb38d65ca8bb1e23fbf98d458e9752f63f47a508683f4234bd45af58ce649163dd1443fce086ba28bca37906a097d9ba07443c4e48879414b11dd69964935cbe657b6c6e974b6083738c9c270985afd8838ac864cb642f24e55dfa10ba468f6bbefea10e02819f0a6d6c3d8a83243e9739fb4685edaad91abb9b2a88b31a42c95bbc806c9009dac3fa3ee83100f805108701c5beb28fa197926b6b5389b0e730d73ca847fb7352df11807b0d8772ecf6888771ed2e5bc48953c3ac8c5ed7690e200b882db04d608f326b7adf3a26edc802d8e6b078ba35b30003fdd80133d4f54c723911263a74670ad11ccdf73fc90cdd3c9f0ad6a1de7b06066633942fc2e1e4193079b0fa68c18fd7622be69eef1d9ec73ee22bd19a03e58201c59c0dd3b2a60261233cbb0ca6bcb6668f05bae58c3e50aa8001e0431e9136d604aa18184a6770d17f6e61ce4586d3aee02e4f9077ede416bb4cbdd0885086074aa350cd7929e946665c857d3aa5dd215939fb4f13ffeafd36f570daf4453e5e6e01636f488a54c489b60e451e736482ba94d627370911422b84fd54654ffbd604ecaec74edfcbaac05bc4f0278a67fdeb3e0e1cfe532ca472baa851620e62c06cb1276643453388f2f288a2764d1032ac7b9a524b9e1b5bd796da47f511dfe7950ec0d87720dcbccdb4007b0efec6e043029dee10c5963640b01d70adb0420e8403c3db99932a019377e0c8d91fdfe6e64d18866b5f882f8c1f0032d19e596596d84cef24068f9ebeacdea045f31ccf73119c81330ee89fcad9a54cbcd463c55ff7cb45ddca3238262f62259982323c1fc4e961b5ae80eb56c0beb48cf4f5461dbe6677c2806568f2977837092aa6deb79d26ba969165f3a3dc134f99339f44f300bfd537d9f4077bd9b60642c47a97f80fd2aade8350c39634759c79bfe117ce1152dedb35e6d0d1a217811dee07ecddee538d08b8d273e5cbfd970189b6e24f770efed56c9c80c4074c78cef8b15c29eba5a06f86df85480e45baf934ac975857b3ddace566dd4b4cfebbb6259ff18a4447b6043289df210eab4824b076a5dfa73c1bcd19e5fbe6b5af679c77508c3aa107c24fd4c9e977385ed90616e2f9b627965c9a9e503ff1451771423543a9cac393cb9d5a8ff2818b164cc43450b19f80d7a7cd92e0ddda053961e699cc57f99ce9a77ab0dbd3b7b0282f16c75af2fd99ee7440e4f304b3dccbf9a0d65eb46c4916fd0f3acf459c95528c8d7ef34d70b0b35fd8f51f0f9883bcceeb38eabf17ecfc5cceb6a96a871110f2c2db111a95295fe1d681bfd942a86bb82debce1aa9b2e484d7c324ad48929ca77f09fd13fff6ed44c3c48861ff87189575e38d47470e627420f48ecbb49b50aefea244c11231c23f5fd796c7bcef7309028f24805aef538edd0d5da266f830650412a96ebf8d6d88140f16433cd9f14a6f7c937366c81ed19e7face8b71b839b5530fa2ffbd0cefb4190fb1e48172c28fa050d066963c76b45607d0c1084c337c1a0836189873a5de399fb48ecb99aaa98f8b670b5949ea5fdd8019536d3cc39af27e65fb086b7181a3500832eff8f48d32822fc817acbf30a955d3452262f420a49066eda432819b4da4de9c1f81912b13c04b6929d4805059c4d023164ba3cb1a2dbbb4d69ed5066768b68124303d3f214721952e65f3f04c5c9e139839564f5039855c81b16f9cea1a1537798ab1d6807d207c15f4671f12e056e07cbe6d0cb134008614c8f2781993ecf80184bc2530d642d99d380559b41b6eb435d0d2c44a03b3226ff9dcf29ac957e9d8ca907b0a6eecf8c23751b6cfed7d28ef413ac63396e1e28edffd97e1d81c66d9d5ebb4630e1e8e103278c63b8b38a5e75d12d53c35c2e117d1d94c1f95521387cc01107aed86b5d4b9fd2712a0923faf3c6dec60dbed31bff0df448712f705b875bc3a460e82b276feb64b9bf620e037ac8b2398c439bc252486607b41e28467141cf083361a65443ae895bcfb46e69fe8dbebf901f8faa379652caf76c5f191acf358e093f707e1db4ba52c1de9914e75a03e9942bd7b78b582562ba37c39341ae6816a27862dfb476eaad862e142066127db08460ac92b0c322a281a18aa854698451b1ec896fdd537b2d335065e333a36305ae8ada624192459b375471b753ce214fdba256189bde018aa50b4cbb9d1fe3a73e6ee659679f0fcaaf697ac5ad9591b7a1c904fd99017f67fb0f0574169142356cae3dfe973ee4d3d2ce73955cf1217d6068d564aa0347999256e26be6524fdc78f0bff86c96978f71426b13dd7872c3ac7bcb03bb7d246763f5e1cb9ec08ee56e6ad6fa9d7e66685f2569336084b18d9eba14dae3ed3d39b9963c72de173ee6c03120444ef84a5c956c42c022f410d8ab46f7ccba2a7dd71cc829f0e891edb84541752add870837ea5cb2eb8f7117f2237d8709d83ca6e725da307436930639123772cb150c50945bbd2d7996267d2646950654126abc294311a16d4ff5628c117620d3a4bd4aaa0f59435fa240f0aab0dc2f49022b79a3030f6fd5c65a93ce262231c84ee20d08d6fa166f613f805af2e5789107bd7c3d7cabd8a09a824e9a68829fd57481613fda02cc23d7c0081d73fa7c981b98ad06af6e382f23a51148eacaf768c977c5b174613eef34e3b3c8582815c8ed70631f4267a585a8696f9ced6bbe7d92b1ec17892be40a8d4aafcd1c4ae7f507e4ea9d10200c27f7a9e4ef2d35254f87b64470b37d1c022a7805dffb2c76964bada340e59e38971d43d0b0c99b82f724b0fbfca72bf8c5211988c0231d9852c5f4458a0878c0ac6b46d86e8812941eb6da4802cbaf8ec39a33c951129259a6302757e85c0a27af6ea7d07d056adee32a1cea48f3b69fe760bbf7a10bcef05a440401782e1c63df7aa2ec20982ab3b50955f25d5d155dc9ea7ce3376fb1c7f3e3d7e62ca04a15f1652b255161c5cd5b1d503f7008a3092dbf623dd9ced7ca3012845a92706b0a65168478f7d1ba6261820b48c678ffdf5eabdf17395c69c8163b3a2f56ead84cc91a7eb517621db39ea42a3edad998e35a834d8e9ffd3901594ba8158ae19f276b3236d33d81d02b17616276a5f3fbf57c419b9900003be3894b99f5d3cabd4a9226406bc5a8e1e82fb0843d1dddcf95f397c969bfb6ac625251062864b5a3cfc6cd18a031ab61caef73b82a7340f788a1af5e2950b67869d73ddb4b6fa69f1ee21e937a9fec7b06f5cfedf41189e448dbf2a3f7ed7724092890a34544630238bec759e6cf7ed512cb492a2ad9ef68b2079e928bf0c5b335c07e96048d028ec537614f034844cb018139b57bb1995d86f43b63e51d090a4fb259cbd0c0966a5c4fb56f1f96b9e03db771ddaac205faa89d6df5866254ee8bcb9667bc339fe4494a2f1ef5148bd51853ca7fd1f2d639c87563552fc05c4793e5fd3edf37337406c0d466c35294a98fe53caeced772cc910e3000ba42f69f76a20d0e3ef987702f4781d214e2142767164533ec437f31992846f90af1f92339dd44c445f43ba87bc400ca43567c9c1bd1231734aba642e1e2e45c10adbfb970eb4ad64e3c7d9d3b1a3a92f628391496959ed9e0ff99bfda2bf19e9087dcdd4c049de6d5a11578b940df9a216e070a82f8954ed42a45a8f6893116d74f15142b45da7322d0d0575aeae811ff1f05f9283e2a1eee43457e714383f25031005f7dfc1fcb4a4b6ead58a0096e9a0f68352cfe43afee9d695cdea3c6fbf4646e2c69059d28ca858d8bcfd76755cebe7f3b616067c6a9bb5c5404922a025d00565c97cca4c5cbfa9d950466cbba17c7f12fac99248211434a9884afebf72e4156a54d33e2eca6c46a8eb5eab25391ba031bcc04abf76ef65f299a10936dc20b570fd50b6a734b9714cb8bf77db282cbad866a8891857614fe48fa738302de7ca23aaccbb3108480f425f92f317d3a538f732d4e30f8247be738fd49577303156c77882d7b85941affc159095c62c515365ff603fd3985c4fd1598e645d6a56096522a3786c24c8b0f561fce66df51d7e6be34f7fed635319c3d899e66b18a82d05f9064e7e66a82b1694fb7503562aa553d097d5f4a6e78676f010285c88f27b5a0b3e9ecec27479b55328efddeee4a7ebb7d401c9a7a7a2815657c6cc880b6fd7801f36b79fcd809320b14baf520e23c3065e7b081b4fd9d55c0e7e492aad3a8d6abaf2e279c5c89d7d158671dd6138244863c75036684cb8e7fdaf3155d90a694d395ec3d2770f35ebca5880d3183980b691c498414c40d4cd1e084e3c36ce1c392f92b297ab63e1d9ccd84ddc6c45ce6cfaf39df8a834609ed1c88e2dee15020070662022886bcfd4593c8300cee69c0b414df1a542cc8efd80aa0f6a4b868abdc0f6fcbd35ef79e10ff2d5fd072ca8d082821a8329c8daf651237426206bdd82287524d6de21f6549bc62738fbd1a2bd66b9489ff3a769461ec53761112d6f1fc16102a4a66e126cd354320de2558a54dfdaeba713d135d23ae2100bc22b74680f69275ba8dd04200e27ef2ffbefa0509855785c6a37223df654b9720addb65be143cffcd4d0796991a4a683d566325b70f05caa668f730808af646c811aff91621cface8ea17f2da5dd1fff5387e65169ed16586bf20c9e8d82cfa27c0a5b88a7f9ec982721b51e810e19a27d42b2b211684c31751cee0e69dcfaf8a",
+ "spend_index": [
+ 0,
+ 1,
+ 2519856964,
+ 4294967295
+ ],
+ "result": [
+ "ff2086489bd8239a77392745c1d4709be47f9f3a622cc0185e70767ce8c7d386",
+ "7389250c5334183c2ba13e0dd8fc2fa16640d07802418d63b3edcdb42e43d6b2",
+ "dae332e69edc29fe196749f4a8139cdb401e89bb7be4322da29806e788ce8608",
+ "83a6690614a97c4e9bee5a61b6a6e8fdfbc956ba33c7f3411320c7f3b20840d6"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": -1769011343,
+ "scriptSigs": false
+ },
+ "hex_tx": "71078f96000104fd70808b00000000000000000000000000000000000000000000000000000000350b590700f0a00891899e8f4500000000000000000000000000000000000000000000000000000000f2cef4c800a8bd1f6472219e52000000000000000000000000000000000000000000000000000000006dde36cb00e70ec0c43d375bcb00000000000000000000000000000000000000000000000000000000558b89b600a67d6ee704a265e2745ebb9524c88857f1ca22e99d95d20f3e2a996abf3ae45c711e2b198c4ce1fe79ed484a459260dcb6dc5f0bf6b71ccf9fd93e17b414c03906b9f38ca3db4d7719e5ecb3253896f5e2df8ad5e4ddaf823edf806d0c417a00c01f820cfa7bd1586052b0940292736f41c6c44e10645f7c380de93fe9d925eca44e23383478eb00ac80b180996ebea3b6c4f4edb599fd2894ee978d94f3de95c34ce7827a375d4d5beda4aaeb3bea83a13aecbf9a98161a6ffbd5698a48ed0aeb56eeab370b3822d8cc5c6f5fa08dc3fceb92453ac3cbe7ce3224e4a81dc848574310c3a8fd8930039fc5af7cf59c32f8171b00db8d82870a2de6c56c336a15d358fb5c7181cea7e861b1a4e82f98c52b54948923d4edee3aa26c2b2d371c19aa91525e5fbfef27b9436e9fbfcc00db7f64c31e6ace8c94f6b074a4aa6bda76b3e9a062e7e124343d0ca6669464f4592eeb02ab7f467fe3b364a183f6be75c4ae239d2ee6be4d77cd3246f2f83a4eacd0ada764ddb4e721223deb0362171c8607a1fe3dbef48184242ae183d220bfe68c230ecfec6bcc24443790f3cf9232506df8a8a1c8c32f40d028a27ea9394fc890c3d0cdc528de4470b971a56b46bb0effc8031691484bc942f24c2699d90719aacdbb4adf518a7cd1f44eaa5894c98e7f3bac8ceacbb72d19eba571c35a3a9eca102156dc2c3beee5e51fb8bd70610ffef0c70601871f668e7f3a6e4f27b166e678329026c9005fedf0e48677416f6f39f1cdc355ec760dd03ba4cd4b129bcf13eda1f59726117ae987c1e28f7dd3ab436ed877d2b1bd0b041bca2590d6ca7c0a1a2e64e8d23c6a42425e64b2f7a592cce4bfd3bb0796a372bfb47294c58c7d0483ebbf3a2da3dd5daa9e11b52bca6dc8c3e2211e1ea550603573f34f1ce36a0883e09bc1d49cb239f8870173d96fc6e07df60dde863be15a0556b2f87a4a50e8f6132aa5a847c354225adc51d6eb49fc179158bff2344e17371b7bc4eb6a60ea29e8be5b785cb63607a9433ede70109a88bb99770ae32dbb9064028893ecc7ff4b8161d9c3305bfa21cb5b73dc41c91be927111a5c98190025c867ace9358b4f6a6bd5138172e276bc6a5f1ebdc2b04d4cc015768c3a3cfbe04e449ff7fd9edb982aba62e60580ab1760bd6d8c7adcb606b3194ddb584dcf03fd1501183c77e644d6ade06c530c767c9bb4aef9ac82573884d887dc00b6b24c41d4d33988b97b9534ab06a94766c9971520a4f2eb816d47c8c5f383844117f6ae686114f6b51720667cefb3acd2ec8d7b6d6fb64bedfecc74424a60e5e4855a4468a62fbfbb94c522e0ebb1415c2df4843e8eb1b65806053e28930759262e0387741da281e48bae924a671c2998d08fe3a9a6a8c4e5a0c72384d8c2ed2a67701d5f7e46034ee7c4430395ff2953a5aa0ca9869f8e3d45477930134e1b763bdf7c75cd6ccd914c1f820bf938f922c070c22fe6853e5ec96227c8503df935290423dbde73aca4eb203f35e570c8abe4890dac5c7bafb8d9c9d5388e895c41574dcfde1fb23e82be0b8f90b140c07eb7a0077e9bac74f2e45a94b6b6ddc783143182ff95e0ec1318f5878649620c863dcd116515b2d379df6777166c280eda1303351e627362b4225b5057f8a0fadfd99b6db8a78396cd498143539f90f5be3b326b2e26faef68236eaaa0a5d00564f93f69f66d6442d56ff4d5cb7cccf8e10c467452703044710d38aaedc0cb5aac4e9aed47670fb54ba6d6ce0fe14cdb140c58d47bdffc0b2d28a26c053293a8fde201178c252edb515c15e5034802ec8f01b59a8eefe5b6fd1bec5cd99f1e5ae99eb06e52663688f75054a1d9d385c580e246e4f235c7bc571f793a5f3183696d881f3c01b7a48bc4e6a22f73f872c596d5200158aa39ac3dc9301fda6a4aeff63e45cb5d885fd8b3db414f4eaeb6132ab118576878d577aa7b989cfd1062c6bb58efed34a07d6c6896d79380996b54cf6287620a5fb143ac3e9ea6265a8a1ddbd7fca6878506985287c516fd629b52fcc97b72e7452817a4a2ea4527f3e7c983f60a76a9d5c1e52ed427ee065019ccec027d8cc1f132a9d2f1352fc85855f21d4cc40b86bf33fcc6f97fa3bd6941eb5bc5331d6766bb31fbda0eb46f978a336312b14b9e6af83d6ec793b89c486ec8c41ab9af53923938934931d387a29259034af2380da3105fd58eb21ae5e81230687c5dbf8a0fd1151937d9abd1f1736aeb50b6261e1ea7d5f4268f24540a6eee067a1d5f211067c8681b5d9f902fa5c2c08c0185a6484ebccf4b364fb41fdbc2d6c6eb8111a11afc5476ca5cc37913ff504178f22a6ce2ac4e60cbb0c2465116428fab889fa39246e31e60a39840771dc019d2ee25482959fd4aff7ffcfc3d583e6b686918a73d1db5dd658a8897da241b40951e5b078879b30007c8f914fc978ab93cbe92ee645d1eb14290e5af48c0948bcac2d401b448e397f5c80411772c122a021af51deffd3f998e31b25faf1aba08d7b48e18c16c2fab8c0eb45456b474091fcf373b91f4df98487852dcdb60e1361a8ab8b37f37f9417174a178f40aa98c574121441522cad634880dca326c13358baf0d77922f922d9af20e7764033b5958fed0b9ee786608319a661908d2f3c0cf5ca3c0683fad6738d40f4af7e73d48a9216c4649c8d8826bbc3d6e9b72c82a378049b1cf75214bc6fd99c8a6a403eb923329ec2aa50702aa03fd9a015da6449dcd9a071468f191bd6283100872182b4a89302797627cf5459b9abed93c01987aaabbb981f7014cd13e9cfd862728c3a29629c527c91fcafc6a1cd092dd4ce8af1e2230fea4d41be1a4cea6a87be841e1dd5a0cd4908cdebca27882376d9a2ff789bfdb7ba13314bce2b9a00eb6b71ef5d4bf498458a5e27245923c9407c0fe88755005174f6849475678ed491100c9fa4805678b349f4915e9aeb04dbfffa898bdd7f07083f50ebe6d3aa712e2030305142f968a20862359078e94f1f94c11783fa7d4d8967341358e74c063d40cc768da891c64cf92c92a6960db3ca484511c326b4d823efdad3198025b4fc3944ea72689b0b7120dfef825efbc7753b4a1b6cbe60a03395b382a9b62ac45388f0270990e5e720a5cbf61bd02bfeb221599d622e749557930841a1063591b57f00ce8ef8ab2d9518946a8b4d780d30e27cdff3748b705e4e4f683b513502d04b7213c4ba944325ab3ed7be4eb58744de16a7970fef27b23b2348b4d54b8e927fe322b98e47bc50404c9009a4423697326eea9d13f21b288152dffc6f9d433bbdf0a3119787a792e0f59f63ef6fc47bc7e22675279d621f8d7ef1eb96840e7928da8e9c51506876bbea54af8cd20c71585c8aa013c29babf38b4c1426e83525a6e4d56cc734de9ddb93cdfe373ac75ea8b7c8bd4d1faec95d1d805c8b12c3e680c2c909371bc95bcc579a431c4d5df19725b1444e3d0771c5350b17ba0cafe804f7af4cdce68a87f5fbbaac4b20c145bddf8059c524717cf860319c2c2dbc07dd3b41338a151ec6c3236c02620de1f5b40864bbfa85a6cacee63744a49ba070afc5a210a7ed25b8707c23b1b05e6ccc1659dadb9ad2bcb0d07e727f71cfbd67349aa34c442e6c23005b9ff921a3a7f36d8d3c0e2f23c06031d13016e07d1146995fcfe6bad4b7f2ee3a5a22e6e87307f710b8d8c3b00c2c55df509cf378fb6eb0b7627ad9939776c6d4f3a8e9b432ffabc3e8341416aa32de789dc06754f88633cb498581359ac3abfc7713da3bd7d91fb2ea5ff9e7a169deb3ef1947f1487e1fccfbc28f60734888c80b718a156659cb8919cdc5ccc702b1d7718126189db6d9bcb600060e216fcf0d5a4d5eda055b254bf3b63b1675324681675b328bf001f4509becb0150a79fe22b7c0269a9114009d4a9da4bca8a872e81efdfb46a0d6c4a73ee5b3b99acff49ffa404cb3614a1774d8655881e7d41fa8a4613bc98dc7b22fc913cf01f4aa990b984fcc540e3ea286cd3486b4f1cdd92cc3556118f02ff259b6c1893916998628db54b14c803b94958d0711695d90dfe0d8102618ef82bf999d96781928b284751ede7e3bca8b04ffc69825b8622f457b312eb95b31f765ae0891bcbbaa40fa886e9cf4a55d10ce20945f364b01cd76eeae456188e4d25f40d02e31675c085",
+ "spend_index": [
+ 0,
+ 1,
+ 454989834,
+ 4294967295
+ ],
+ "result": [
+ "2ca8b7b26428b71b1c427e1bbde29e7219adc411a5857f92b67a57a4e17e4561",
+ "b835b1f1807d7c19fe9914cae81d288d884d5216e35a9f51f415e5415200c00d",
+ "626ae3ae67e58ef244df2e60c3219cf9bd30537828a70fd98e0d553db185ca6e",
+ "49953f533811a49e59f60d6b507d447528ee2e16af04c29653a889a7afa34c9c"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 3,
+ "Witness": true,
+ "Version": 1087930968,
+ "scriptSigs": true
+ },
+ "hex_tx": "5882d840000109d11d906e00000000000000000000000000000000000000000000000000000000d1c8d516fd1501a186435131d0d9ef0027ffcbfdedb642c4fa0450f8eed99b17f0c3474757c7c9d844b0f79dbaa823333099cd816f889cbb650ef5f599c314ecc363ab80a68eb7913e8ca1fca9ad2d1f75e26066b413e3f24791c53f25a09944458b4208adaed92438b3faadf525b7cb79d51e8b265508524ad32ad68cd8f6464a1391e9253dd90fefdce871b92cc10f04e87913c6dd1d8fd5335c078431a7a7845c9e258a624b0ca6a3d65be769f069de978996245fd855babcd48d319578805dfa8fe7491e6b0a9309fb0fabf259274696454968abb90af4333f53c74463894d537aba51c3146ed2253f6f492ec6ee2d6546476d1b604c152fc67bf838ee667e14543843e5fe841336d7e3fc1a0b772a8f0b68c09388bb3f333ec3c907612a9478af0a000000000000000000000000000000000000000000000000000000003247f14f004fa0189628f5b62500000000000000000000000000000000000000000000000000000000adf0cfc8fd9401e650024b0336cc11f1d733ff33ce9832236f517e86ad9d92dbe3f99a60d760e759cf036ea1df8f23f300cc21a84815a07ab8862ae5448fe48a61b5c4a73405f145e623c93ba814014d71e97007de76449596edab5e4c8199e617ab7f618b81b99c72d0fb093ea16e18ec1cd6b44b083511609a1ff64219f12673d869b7679b783a988b63ec97482780ada3354f4f7e60a7e646976c20c1435d7487dfca1927199086d9ba22ee53527675a890cc0ff97709d64f143eb8058a5f39c0c5e0b29aa5c1d336e8e1e4334a82db93d955a86a6180266aab667fd3411269a18862be399d8fcda14b86dcd4d8d01de1eff667e130ebc5f8446a68c65b69ae54a562daad3127c1eaa17fc3f25949b9c5ba6e56a4e0123f5906d552a3f40f54dff4bf599e0a36b8b59d381f67971d8210c4a874f22d4f32cf8c895df7db0343841b86d2dca2af9e6b5cc35aa853f35e3b7433ca49b47133e96b828e6edbd26b24e3a589f2b0479bb7d59bcad7e2c956208400d96ccfc612c04ef1f6772829902593fb73a1960415cf554e142a1ab4b7938c0b60c9371366d0f7aec032ea26d0cfd7000000000000000000000000000000000000000000000000000000000120c9ded03842ac4ac4f2978f342400cb7bf6c57742b077a4d151ad6a54242759f88508cb1b1d51a9a56ec7f3f60aa90d42f4d5785468f93ece58937ce5471b4b6a51c72b12b9f8ffb09271648f53d05df8b2541f07aa9f66747075f343b722acae5d11ee89bbdeb8c40cc6522f470f7141ea40874fd8f3823e3b3ea4be67928546f389a60f22f74916c48a2f74429bffa625f84acdb7a4cccd6b7cac765fb44708eadb66935a9d3dcc6e417835192a9426e5dcdd7cf4df24ddb9b2a9ae1a30dd22a5c6f6ed4ec3432ab322ee791a83f5c6991dbe864c96d9c48cfb500000000000000000000000000000000000000000000000000000000072325ce1fd6a01c9fab206814c27c190b8556df10cdb80f1ed8ed5083af50f2845bf463a85fc42c308f5b8d1f9474963a8a5f5857511b415f9c70b5544db3619208aab12822862c2f8032c1f34876b405d5c2ac3403902bb68b88f252cd58269e11774b803abe2f68a1dc2b81d2bab923278824c33187a91d94fa57523adf4c3bab05977d1b91f190314247c21402f31b9841c5dad2e91a55d2d55b8ab4c979e32c30b1c3878de7f96ac377d4c57f833b0610940ce513c6da1a96e24deb783b685a2505b021ae12f58a758bbf537ae7b22e0adfd0650699d14359c9969e2acd89115f4b5699f2d00034fdded9423cb93dc1a71f6c7044925787f8e7ac3763d265f8c6f8f601ca158d123065abf8e240d22331a3d8d6932e47424fb365f3b8817b2d6132b388e18b7750ea859979a9db75dfff5a3aaa3ac7651e90ac8323888ddffcb5d85f6fc44e21d4e745f1bb2f98709881372d1b02a5f98d59789230189cab9f2a0557deec93185ce163ffbb5a95f2794fde6401fc3e02c00000000000000000000000000000000000000000000000000000000ffa093e2aa83442cb66f504b4317063a9616dcdf3c7eb8342b8e376492929e3a7824af63c20f7e68933e09e050b7ad6ffa6d19c002f5c996f7ca21b3c6bce4c1c57aed09a215d190ac43450ee75121aafe112ef6530ad1300b578c063a7e0f6979d087fad031d8ece71fd924d40a989f439d4ee219b1940071338760e63e40f6f9a200f850cbb57bd28fc4d210e362442baff1c68e169a67ddeb5c18bfa9cdcae253d49b0fb5da5727657848505bd11b9e92aedb8703c8000000000000000000000000000000000000000000000000000000006aee706e91bdcc8afde1b433d68ab15dce8289e92773f52bf999aaee11d9752b3bbc21be66f0bdf751b9f3a76bc67e0e840c0732b95cb8a74d105f783fdcbb329a46ad2938e0cc234d070fcd78393c08f184ce76a813b90412ed507dcdb903dd84808041948e6157e6ace0e96da464a774c7d139114e61ba7dc70990a8adb253cba2761bed4fc16d95e0d25314efcbe73e6a624d1b2e1523f2ff2d4e3c8a0000000000000000000000000000000000000000000000000000000065580be9002ca46165d11b55af000000000000000000000000000000000000000000000000000000001f2269cd00f8a30788031542986735a1ff65c88b802469b6494733b38d715068adcc3e0f23abed17c489cd02f15910770b3a152124eb6817f964c952fc03b20916823e7b2eb78ce2bb699f7f75a8aabcc783ca20a173b1cb970eb856dddc4e7b015fb1483965c33881704f5f644c8cc5cc387f9f2093f6ab3a5202540c4cbb5926cd90029829f060ee1d1e58041e26438938c77ac452e235c147b1a2ba7ccbf7785c761f8025f76fba58cd5db56f8468865eac56349ba8cf7d071022895dbbbcb98f83ef1dd11be09567944512705cd0734439c2a48e504b442b576f90f8c577478562c83f7a4d2b36560505606450f8b1281ee013db911de9d028c660c70fbf36581b680b11c4f0f5e01892b94cf03e96be8e9b6f4ca3c8a17e221bb97e4059ba7b17e2c0e5bfec5151e62a590b11bf358ad25c2a621aef685f35acbb8a1b53af4fbb9e7fe764c6ee4593dfc940155c8a1f5de8ced50a7c938f18098d6b670f9fb66c161ae33b9cd140baa3f4179cf66aedd3467f4edac01f84fb6e3043137ab7915da543187b0149990ebf20499edf3cc1f61ec1cf66425c05c6e7cab47617587c114cb19b5e05a6aa1132a1cf1593ca35fc28c8f163da373bd0b2cf264e67a63e57608037982a3f73adc2987c09d2f394913abd30d7e60b63efdeb2ef7a3f44bb01019e87f85e5820fd2f154f3b8786062937a00e86a9fa0f241d6b27b16031371a8c5824917b7c64c39e15dec48551746085161b7af95b605faaba0acc9e02792ae92af2c9c827eb4dac215710d4717ac21b18734653e3f4399b4eb894d713e5de4ba1c27a12bc13587da6e47d77f135f3d7d9ce9a9003ea3915b05eeefb4c039145c669db6b8104e98ebadbb3386f8a7bf9865efb18e26fc8cdc901f76dad15fc0cd8f18be46323f16d425acfc170a8c20a84c3c2a081e120ff4c09210e694e9dde489d222b89be1e2124878bd42bf726df6a3ac2de8af64694b8c97cef3864efffda643656df603d61fc31fd1eeb499c4111b9dd0f1b612e48f0bef9d867c666bb8f2a3191714bbd4e80e8f5e994567eaa174b26e583fb9739b31235d03f5ab507575fa4c8c82970705fc581a32fdfa3cbd4140c9e8b01c8c1eedeca2177dd7be00f46063d23aa483ee1f69843fc5bd63dcc6024675f9044152e11d530fdeea913b329b2f13476da2d7d3db8e478147fef8bb97395bb32b394ef16629c0dc9a639d4f5501503efd255b65d1fe5ed611737f7fc0451d71f8c0f540000281bfef07fabe9ae65ddfa6641686f0425ffdb45264fa32aad79a72b717d14a9eb168e83d44ee35305b4c3c7c16fd6f63b4bb1ccd38087c905b653270e0720e92f3018ca90c78b4c679993edbbaf4e4851f021b32df88ecec3c41abe31e1832a7737ef0807ba8276a9e7979067a90c3d129f9bfbe14dbd5b3cf9d69ee074a20572e46988f8749e8f8c6b4646ab8e756ca2ff9015be14ba0008f3c7a00136dd300a33d81b2002f4146834b9ec1650eddab1b9c9e80a163072cb2675c50a8b474ef2690529fdffc56661dcd4565c4868571d38da25fa52f724d1717de4884e26c58ae97f89b6fb7d3a3330a833f09c037ee12087e23ac16ad70c9e0b15e733f5cd024efc3863fd6f01c342e5db193b50b4f28ac75a7936a31fdba44a1c82d62da1dc3b65259878d1e7ad1e35ccb6fc3dc5c76591df1975da5f241055b50f1794d201d4c9daa47b31ccf6ebe8209cc1b9bdce4d9255dba5d74d929bea4c142f3ba02e91c23bcae26b0c9055296cdcaba4067377604f297a799f431ddb0b2fe89c5d486a5b087a6d1a03f33985e2a5bb208e8a45cc67d3f4c167c61a01fb1caa413b910892fcc91055763f69b62c7acfb6f19223c0e39803da2face3aa5f97a0b460372a1a2b2b315c32a300779ae9f99888aa89936c6a7709035dc54fa32c5f7e4edcc06ba707acb5d21792717324d37a27d34a32e23f1ac6b499e944513e44e0082a1043ae01b4f7e56294d89e6138592f8482ebee6eae39541a1629afb8380e42a8b5cdcba9e5696c34cf55c29f3de0a4d9c02cbb42dc2ac325877487969dcbea36dbaa62e0f03b65efcd4134a15556691614e72d07a5edf5545ebfad0155ac976da8409047a32fbd44023d543848eac10a9431d0001e7904fdde018f6691643ab0a74363b5fc7bb25615aa7170cf1f708e8c664fa9ae853a619dbbb47dec3a02cd76e12319ce94052008449cf909db2fe00b20eb2ed0a36b39b9727590428f6a45d8e6ceef2ac582143bd467ee796274f5a92f84bafcbea39f295cdcf8de8474fe03c5709a43dc73ca0cf126c5b39d8ce8df0461d5dcdb6d29f9860c7b300dd571a62fe5ca81f0a96a0bb050fb11539a878e2c69c9f16793ba315c35886add81b33f3b39854e468288f92be2c8822e8f4e074bd7222200adf8e15f6214a9a69d73cdfe78f5a42e9dc5346287d83feab8c41052bff3757673bbec13182b1a2e18e581f1aa0d50f7868b9a947816cfafef7577eaa8280176002a13db76bc4fd36aa67aff8b000d5069ab18f619dbbe2687833c7ae1f8e4cd078d240c3a9bff7109081314b342b61387e86c83b646c1f47570ba13a9921488d591616e0c9cbd0bc565a43c5b77f8ebd4e6982c63afeba586bf05f70d3bcd130dfe29833c9f12a7be2d6d635eb5228cefd7e4490a2b8c6473e38450770c189af0de097367457c8abc7f22f80205c0504eaf5e8d19a3908a65467f7b1a4cef40c3369cc6ae4c8a4553081566a1667decb04f520ea73f3b2da9cb3febb2c5a84b623e21d620cece5b4bcb40de3641afb72ad71dc00673d414b2a5d1f45a289de1f6bb2226aa3a31711a931ae68f67ee9efaa0df12e6acfbf4485a5ad74e49a7355667fcd12efd4c0124aa6676322213513bd81322778887f8a83b90092801d318ab832bd270a37a5e97004e5da6f46eb97189f607217314320577dee6e47dabedffb2f5067ac1d50ab5164a2ae817671171e6a4e432657d856c75a3cee09cab538b90d3fa96aee3117a2fc5c780896fc6540f25e12ba8c9bf554fa2efde7126a039a64e7d830ccd735c753b52f048c30a613ea6524c774dbe4df42fba3cdc5827c9dbd1ea05c02968868bade637ad406ea12796a524e5388bcd354b622db22e14ad7c3b95a7c861ca1bd103e9a38288ceb4278f8b5ec7f60295ce9255e4c34eb6e4226969cbb5c0ef66e7d74e6853165028a58044101a07b68ec19e2cc37acc2114226379166297e53950b7b1078b5c0799c7f4805fd104ef202b50aa2011d3339d50fb9e2d37a0fbfaf303cc4011348acc833646286ea13ae7b4f13a655bf78edb1f30d1ac3495b67f22ba70bec37542c32efce0af454629a0f91384149cbd59991de11780ee8d3433fe8a4e9f465ea86bb0b5213d160bdf4de6de489dee6c60bb73281bd206d3deb9ad8e849c959d67df008179cf0e91b7a70785c55fb35bfb9853b17ffbd7ef7c82bd56d25b2a3e184a69d3aba2fea43f421597f4abd0c2b1a74758c55b5824ccc1474f0c8a7dc9eda88589025833d2abeaa53cb8c07ce020effea5ffd9febf976de95819fc60ae81b4b6e1918883b895e966259fdf13331ee8b7d7d301fd1c01e4befbac09ea666c088b6e686ad7dcf07a36dc9b4c3908014246a34efd904f6133908099d3772cd45f7862245fbfc2c3d935125ad06b84f2237759450d8ff071da1e798d4c092d49de5911de9bf172f9110f9c8adcbcb2e18b9ad0057f1df919387947ee0dc54933a7cf02d9883c711338951481ace24e570664b50a6a0c4d0990bd8d6dbeb1b70e6fed55f04715cab4213f5e01ec28f6fd3d03853485b1930e29b995a17aab9d411f7e55613d65a8b5558aeec5cf9c2361855a3031810ddaa5b0067554a269f72c3dfa4a7b591b8c2bb26e87c69e7aff9ce6458f908e855c3cd9c975ff35a49583fa1d6886160f6592e3b17765e192093b6d26f36ad1213f9e5b6e65830d73be96e4f0b431ff60e74e8cdde280c6f7ff184939bb5c04fd7001c298a056382619d7d85f178b3cd8399595d2209d32d07ac324718e88b0c65db437ae1126fb84baaab6f8b6d619c011c911fcbb4afc046b84053ac6b02c68a735853e7223db64de740311ced5992c9fc1707cb1ebcfed06adf122c0155c0be4ac95844607da8458835a72ad57936567a444bc3ea84a173246c14d8a3b38494e691d60f243798773c74e03c82a0290dc9761711d05439ed9a876f82fb0357cfa109b76229c60c79fe2cf1921c684fc46c3330eef8a581393010d8aabacc50a31fc5a6c6620f728986321cc9ae3922678a6315e356ebe2a3e92daef08adf3fad5308ff0c748d56dcf6d5f96bb4a5b3813dddb790abe43fac3c431a064229977d2b7573dcddaa1c18c11a3aa215960237418bfd39385885cb6ecdf7fc02737fd6eedbf9e3094eeeea9689e43d136cc721a119d1bdc90c42efed7c982251ed86876f4706ca58947bb1a3e2787b36fb3e19529947b066336553158b427a403902cde7a6d072a6aa6d6e15ab9e95ba3122da146403559d5107d51441f3e3bb40f5f869534c1f49f7aeadb7c6b9d18b3a496864928bca65656d7a562adb078a39292e2cdf08690837cdbb3d501bbfa6847f77bd924bb07c4518a843edbdfc7b1fde5eea2d4b702e7f839678749f090a8b803a8da0b80e9d248a8b689ca16bd79c0f7289b88160f0ffe998c00c484e30e7a978e99527540cb8d0a15ed505758664af7ec5983d9d08e380c22ddb230d8a542a5a0237577fa20399133db58849fea3a85fd4ed4efa30c4af23e3f14d0c8ddffb45f191145fca63229dcd83863db507a7a602bd5505466223ece20c65ac753d28efe27a122ae2563dc1bbd2449a4e80aaa19450af5cfc23c047e66b1b26074a72828cdd81cb00b3385d1c3f77722b232cf59bdfc23baac41e72872ea034a12fcff4b7cc903ce8e30140000034bb3c82984c566a5c3e95a1dfbd795ccf495b162339f7d767f0e75413394e755bafcb49d3ea87c1bc6272209b393af99bc6f17489e8292379922e659797454282366d4ebbb3408c2968cc9cefd8101ffc275bec9b00f0f305b937836bdee046d36a26aeba87b63e5ac2df090f02d7941e3c6cf3e0264b964014bb3d52d4050f8c5fdafb33c34ce9bc2e31e1c749a7cafc7c6d87fbc0862129e7a5c45927d84bc32bff30f4287dd27f9e35b61f92e9ce5d499ec93dcb0a093a94d2b2a400b0cda1e2edea33db0cadf89255ce9bafce2a6a8945bc4daaab6a0f4ade3ff870464daf7292b83987bb58804f93e17b80ba342bf439eda4ac68cbd01c27576fbe3b90d83ede7cbcb8bf3ebd1551bc167ffaf17fd20c63852990a9f84687ceecac6a3bc11eb9b02b31de864eb137ae8d34a49a5a31ff8c0c625aa2d0f8393769bc770f9c7a1c915bc854473dd9103e698b9554e8bfa569436849431510fc5bb3a7f5fc9a7cdada6b626a77b388a6c2ad8405103895236b58040368f107f78289007d9a701d03c8983f893c9bec8bd0bccf5cca6fe23b7f84a5c313482a07aa6d296beba70511ee4b731835ac15d19b5cd3fa56b2c7332261e05d3c45f3d0849be54149b30375ca6efdd8d5918b3c87ccec57e60fd81014bbb81619eb52cf7518feb7b9a7c31e06c1534ce2f9ce68c41a889119b8fb7a08a96b27663dbc2834624f89d42005eb25a9da928963f76505b41acfbb78307ab7fe7c803083e0ade89663491e0f34de4784b0767891931b0af5de19f784ffd32f005f367c4cbe20f0af216f1ba8e71d7328051037a843dd0b6464de272d4275e19ff4bd36984f32225bb85924422e8562fce3191fac0faf8901b97930fcdb2a75309a6439ae3cc8df4a1ff96535758ae123ce155c8723023f2119f34051c14af2f6f6ba3029fe0658535a1f156e5c57da55df9474df66b906129765b5330fd0364405a24393e00131dd8fcade97467846f2148492a419d7d026e3a06c8e1edd44ee3c2a5dcae4dd20f8ec446b74d90070753492c2656b064fb59396c3622723c5e7487395eb41258e2bb8319a5e9db2188b6a6bc5a6d24965ffd2105a94f139c6ac04905fdedb55f9b00344a9887c44f031553fcf6d0ec4ebb4c2b6cd8e8b4f53083cd46adbf10eaf646cecfb218ba8de1c7e5cedfd0a8142ad3ba730b71ea559d0210eaa026d85c7604f9d437b1fb6807e87c6cfc75d406506076ab631b7fc4f8681e9a09894da2fd0ffe79ad5bae1e4afbbd57c315fb1a566c8c1f320254db2a76544346a29280a06a5666c02aa07da806d46537a405f364e667f2215b2449e39f62dd441c3d5c9926787385679bf046b8839702dd2da4bab8d018a4b69ebf3747029b",
+ "spend_index": [
+ 0,
+ 1,
+ 2069202832,
+ 4294967295
+ ],
+ "result": [
+ "1f828c6af674e8d1e1b008c6e775a4a20439e73177943bad98045c5bc590a9b8",
+ "6785d0e45096d3acf1afa0b0d6d20e11dfb69a021417ed14626a30009f792e5d",
+ "aface3587b476063d465dc2e4f9180a16f8af0d4123d1360ecfb135cab72aa80",
+ "47d0b57b0b89597c624964d6e436816435ba96288a0eb47cc2e6754ba2b9cb33"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 3,
+ "Witness": true,
+ "Version": 1959860592,
+ "scriptSigs": false
+ },
+ "hex_tx": "7019d1740001023867b0a9000000000000000000000000000000000000000000000000000000003f6d5dea00948107edf99ae02c00000000000000000000000000000000000000000000000000000000719a559b00560d4253039aa0dccd0e2dda6ac8985f9b143b2eb3bc5ff298f93ffb1893ae7e1884630415c30cab9e2c71abd1fd48e817b7277cbe3bb1fe28456fd8213fbe84ada36962c65fcf815971c8efc67f2f411c719222d4b376c6f92d1c56de8bf5baeb2cbaa72e48bd29c0ea4deb6bdfe3113f813eb872198e3f06ee4e3b646bc4b3626f720417c62b02256fdb4e0aeb747197900c0e3d51f55872aaac60354dc7595b42e115dc1927b4124c31fc37ee69072fba58d351794a70e9f313b26b23240c7d90c81c1b266ca54bfeae192ec32e132b386768a1675d8582d210ff1456c8da309f67def5d377144d0c9ed67d45da982bedff793f25d17cf19b2ac4033c0f5c9bb19ffa4946396e7076ce037987a48d486f647b9b48e2a968f46087283a20f817249893c88ea2d5ff64eb3c145c7c2cfda8b23d70ceb4ab4b984b655dc4e18fda081f7128cd63a8090041699cbafdd9f7bdb26f8235ed8b0ce542132ad77d09cfd14f51ecee08c8db139cc99d6df20bc3eb1c54da1e6f0db8558d157aaaa89ed1a0d983c081e5bd8e6fd248b5dcebc712b873765badcaa18c9ce22c8f9340ec89bb53cd007c0e6834282d3b7c703ec8daa6e5fd6cc4362abd4b47cbcb295996d437a58fd7851cca5d25819324e51da4177b79d1e1d35f082e482115db9d9b06a858f50d9ff0beab6eb83ff28deb3ed1df17f7d237e3fa6d70204cedf82f8f99837299dcf8889881a975ab09495dd64d2abafc40b852a7e97884ad42438c3906f743731020cc92c0b22657a72c9526e206368489a9d53697543b57f427a94bbdbd2fd3a4bd7afb2b56b6a1c3bbccb385e1717471320728441e47a1a74e714f060d495d8600002b57abdce9a077355f7c945e1fc62f91900702688b00bfb8bad563a266560213d087b0746ed67176c424d82828c0d69de039245e72074ca1499ad6b6d1058d85ae4a9e39965b2123c7cc0ff199aee0f6cbfd8f9dbc4defeb3f141fbe6d0d617efeac84c7548b8af3f7cc17c959fb3e8ad5e628b167ad72a7c7a7a454c492c37118da23435cc88f8b5660898f17e526638800a118a53fdaf094d55945e16ac956138070de1ff8bde5261cace53c565bf340660a60fcff95bb2fe24d936ea32990241f3f0f48d33fb385b468d08cfedcab0cbc36d5a7351a0026a7d4fa0cf4281303feab80cdb09ee1ba37592e8ad12e7ca891a736cc4452647461c3689eee1987eb292976b9b354d654dac5aa7a12c34dd3687766d65852381a2191d69d4cb84ed513728d7bcff8476279a31c022378afb2d4b57e53ab19a42ed52dac1ecb0edac702fd6501cfd5875908f51d2488056c6d6a38263649844b905436bf387ed391af5475bab504e0ab5c2e22ebbafdb5587e6e6cfe7b580a54c97554cc6254f07848b04f4ac982b69ef43cf3d1369429fa01433b292dd455c6e8e43efb4131dcd000d265f14418d6c2423bfe3d11061e1579a399ec0f0977c9b7ce77717765a90e2a93cacd67bd6148b43abe8d14f4cd01a050d06601d9468dd2e97d462aea18b474e659babf483abc0f102098600a69c1f5fd70d214710e29480ae4a28cf11873e99b647d650ce0dc5ac76333d60e3aff9005b0e9261da1684911bf0dc1a5c2f96e60c3dfe0c6a8df5fce68c61c604bb5a6bb7667957b79b226bfaef9dae992d10fb6f362d6b907a83ef12576d1907eb9e0144ef103ca20f83de50472417ad10513f6aa78219b1697ce9ae9447bd72bfcc7f5dc90327c1e4b5a70badb70b05107efb6746036695974129c2bf1a44eae2204daf10f7039edd39b136aa29b2d7ddc3225556cb5399b93cfe02852fad98e90a1f60f215d6025d84375ac2eb5773885e131a114feef4a95eaea11b12b7aa9366f5709d37dd494",
+ "spend_index": [
+ 0,
+ 1,
+ 2627618632,
+ 4294967295
+ ],
+ "result": [
+ "e61c8a21d808bd6b58e40bec6069d31b548bc0e3fffa1e5e45cdfadafefeca65",
+ "b1c93d3736df196ab73e1715e4a3c773c687416531980a554e53f9aedd3cb4a8",
+ "c9acc5ecc7295e41dd9ce686bc64076f445f58a2787d07efe418319eb16b2440",
+ "ab97e6cac9ce22d4edf7a13ecd667a77ea8ec17530aa933f7e38757d921a0cd9"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 9,
+ "Witness": true,
+ "Version": -582183053,
+ "scriptSigs": true
+ },
+ "hex_tx": "73974cdd0001052083665a000000000000000000000000000000000000000000000000000000005f485b35fd6801431cd23801907a784851ac409634decbeb657f57e914e7b67f2356c0d3c5cb461117bd1a9912a81d4cc8e367c0188950dccffbf84079ccaaa02e97b84045ee87d4948a82cc6792911955a895f0bc5e2570ae9f852434b7e47b1f7bb28231e482746e73df3e7c9a2ff47dbd168250af81b1f67e54c017398a4e4966844da3d210608c53ef9df1e7e60f32d6b22bf91c34d594449bc7591bda0001af45cd07ad7da375271a6459d74451b3397b5a5c8b9fed2289e494204b1bf71101584faba6448186c0334ac5e2c00916b41d75cefdcea86aea5eb692847f544bb961f8a5f3762ab5f629b4f5b1b9fca38c83cd54a72438783aa2fb5b6e8bddf94879219c451ef242ed67486e3beafbb76b783f7cb40515a7ea86331ee5bf7b37642b35e816567fac199235e20350638382411d4775bc963de3cbc9c28dea3f88a422a619e57f11fb1433f0ff059ba8ccfe22792f8300eb3a9f6588c44639d34905114a6987ad1128cd3e1c327932bc918f00fab7da5e00000000000000000000000000000000000000000000000000000000c1bb96b53f4827f22ccc59cc5ee14fb8b748080bc0827affdd669ae7c9d32fc7268db1f6982d458303c024abf63e7070fb787690335b608ae35a4aae84ca4a7550991751df33c2c0b29622d700000000000000000000000000000000000000000000000000000000e92187c35477e0373a026fd7cea7643ab45571840eb7346f0e221cf4461bf35718c4319982e2672b7f083ab5958f47f816a911d8820feb67497661ffa931ffcc8b994e707ed10fecd6eade3a6d28ebf476a959c373d0f6f544f667d58a802a5cda00000000000000000000000000000000000000000000000000000000905a84e620eef79aacf885f15f01c0bcbee7a5c46c16b71c6570afc5836ddb84904e1c85f0cc02de39343596eb00000000000000000000000000000000000000000000000000000000c6e7076f000632e2bc09fbcee918c04d692fc831bf3c13d8f129beb80528e9bbd0cf3fa2d2ecc42785190d41ef3cec8f810d2d24e712fbdcc9d375550a823261269941a55d285ef2e861005fc69793aefc3d9c9674184c6581c0e565b2534716911216ba4c719779654d848f3c717d916fba785bbb7ea590000ff6efab5d5a7acd50e6df99388c5d3b8c045540ec29ee5624f9e558fd1f5042165f4c0d1cbb6ce585ac72399d10ff19e5cbb9713e6601755366bddc0deea6995b06197f8144ab4a0a3627b9597cdfbce33e89ed2d7b5dd1a046d3ef0a1975f420c0bc59acfb1431b624c84f41c1b6d99f9c389a4dde9f63be1a949bf3ed8f8981b95ba4224b31cb070b25a5a67265f32b9b74678a2df22acaaf0c733ef2010a01052135a6854b08805da0068833717c4ff09b6615aa9df33050a9f18a389d4bcfedd764552295604c35e84c20fe87a08224fc351ca935e2e036740dc094f5b3bf2436aae0410799c2a0d8edd7cfff3e4da4384c58f569a2bffc5c1317ef80a748ce2a87de5b42f23c388b502057286b3fd99b196394196d83980de7bbecc1146fb95d02a339ed56772528d0a5bbee26b26fba3c33b9db160df85dc83daaca965c5ebd71544474fc902ea694e7a148f8818ff3b0da797561bc04e039f5e97e55228165601c51b6db02dde391028db4c907076f1bdb3b78a49c53ff84ece976d9c1238cfce0e14073828aca0c765e09fa2d27e25fcd06c82d3ecdb3830370f55f1ea42b7e682cf79eb48f100303130f7cf2fe6722ffdcec99c71fa263ff68e133759ec9f672ccd10d8ebe6a0b8e2e27f4653e5926c9bdbe0b2fb5cd729a19cb252a83cdc44504304ba46b2c52311a98414d548849bdca6c6d57da3c53cd7e4df714a68ac5ac5f2f0a731ccb19c84114d8bbfb4fb0bc155c94059f79adb6d65063329e691f4a7872b9022675282e9baf7e64561378d0909036af437ce4b95e56a1374773c203c6b9ee712c9e0c745e5a457b8e37363c1cf584c36e633679cbeb79ffc743f4888027b4eed8e45fa8a582a2e9c43a319cebbf225b342e8f42a28c1455c2817b95f3eeeeda604a6e53ef7fbcc5b6785f02ecc2a71a1d39ebbafc9fecd825e231017654783a31cc05f01359ad89029273df798d37323ac5c4b3f401fc535660845c9e894106a0803e53dd3060be45985b6a7d48f0a3aff81b3fc8d2a7e5d9eb6e808224ac5dd721d731fbe7729a227d72d42621223c4500ca287f019e41c88483fd1c620c4315b3b7357664710a402d8ceb07a50590e8d5a5a6b59d22ef68ef6d35a0ab5154dbd0bdb218ce3f869b335b231065f2fcc1225a5508ee94a05588d0786b064abfe3e65f0def6d653e3d05445be6c561fd7102993b2e4dd89af1af2a7dc2950830d1e999e99960794a43e32e2ec5ff98e4abadd95073cddcc33d953c4424ab5f2161b95f870e002bc8aafc8023704cc86a250455a1481aadbcd07e1c0199c0e6e4363f4fb01dc8905983e39fa064ebe1de8401af7244da7216ff8893c01fbb974272e32494bb6eaabd4d6ecc0340e6de827018635ccd6386cd7a8d6cee64814e4c2d89eefbee931f110e230e8a33ad942e2d88374ef7fe5033bbc7bbf7d7b31c05f22e8081e25fb33faa7eeac363b6603e9e30f6cd5928e5308384e34acf8a41f6ea7c1169a710dd841caebec6416ff8a4e6f99b6cff1e937fdc90f8f194e112efa75982969e5671bfe73368ef62696da026a5e520d4f8249742b92ad5378c2ffaa318b368ade2a843cf1b88aa10037ea491e9b4bafb72c831ca50ba884dff5c4d99d0d8b129ca5583f1ab02a251f5e5db820e0327b98eaac31e53ae45d9d51d8a83cde314d21691239a02d0e5943804abb7dbf6bf03c1b7d6b101eddf5f13e31d0cd6108fa81a1d420b7f3fefa9e4d3b92b00fb8d416f25f7d15617bceec73361817f41875b699f7c3e98e1cec69f293d9778427cf1f94681c470db40e8b7e9f15507e86d9b938ab918958521798780c22cf8c3507cd0ffb1dbf8081679dba9c4cf9568e3e98aa402d18fc782414fdaaebf446f45a1d666ee5f024639d39b3bd7a00dc2b59ef55cc8a91cdcdecebf3f1bd6a655daf4b4965e51f9546d15c7967c661a2264b2ac28862b1543a92ae5b70931bd5371e30a9feeba18b42df6fa91dc9fd08b63a61bdbd2acf36bd8ac213cf2b24c1b23c20d8eb1b5bf66620cd247bd2f8e3de82f0c9ca0d0af57ff2e5553f95f25ff43949e56ccf672475218c634e5b1167b41cd2a5c02dd0a85f53850d322daa354939496e450f089ca64ad2167eceec5455a832b1f303daa81263434022c075c624e3cf7e0920735d3c91f6d8ec3c47a471a13855b55784ad09a6b5de74367e4dcb5b8a63433c81235449561ee0acb420ae4dadb0683f8fbba2ef50fbbdafa0a9035d3b3e13e6824c496cd14ba1047f1b9595dab67a5c50d56cd97e8a84af645eb33912a173248ac7678130e4191ac5fc1475932cf5735c2ab74588eff8a83a1f8bc9dd2448b2f11861b86f7e0856a64d7ca4d0f1d29837b1609b13e707e4e3c5e1ac43b0db62da81fcba12b2a1dc21eb30a200942b357bca55f57d9ec32d78018f64cd224a64bc7a6992092481778b7e0913226919c0d89a011fc20d6b47c554fe94158fed3fc92a5f2b2d2cba745044625f9da71e9b5f9879ec2860def5d9f6733545575917230d00f8ff5b51b472a1d4c3c87982c9f653b19a650c67a1bf7e33a7fbb89132ac9bd6fe727218759be282a1830696f06fd0001ddfba61b151c9ef04031e7a6e5b7ca15cb88da64fc97b303ea1f21640140ad0fe340d08c97e3549d20f777a5b8c6283a3636d8b4e409dd3266b7d09f981437aa2a893be0b8bac90f43f423e0c46c6f7b5c27bad92375da64ce7bc08dc3355af033d9b6303e9206cfcfd158b1fa01de372b208afd80febbc43b6f55c7836b66e399ea58c601ca9af4cf92ec8f0e5c3d385c332e38a21d5e55cbd741635a7b8b745d686a58332596ccae9dfbfde4f20103c7479ad14773cdc8d36c272882c34d34e261d112a5b6caac15bf931cf1315837e922312b3da35cffbb85e912853f5cf273e2878d726d9f71d8d39d0e2d2bc89ffca9c61b2bb3d9a986fe284df209d382b0f8f23996656e0457e3a6d43925e758a34bb9f545b8e1b7740236329fa93132fcaeb03f6949049fbd1c11f034628a2cca5ea733f7ec50bff1fcf1af770258a8f355b008ac044cb47c3972ebc4353dfe86c0835e6a2030fff1118b57923672aed6a96d4155d8e55367f9f0ea18d4e11cfc4143be5c027a399f6753017a25dee8ac50b710edfdb0d7c0b8e856223fa7dbd2a408c85496dbed5c8f13668a26832af397c2deaa466f21b5c6a0c38609a03b740f9993914838ca1c7cb18f88447e9c130467e268c50d9e62803d3219a7e10b38a6507c8a6ce000313c0aa9502fddbb3e3d131902e1878fa70ad449be7200b6a9604866a44c0db0bbfea05282a32864147d6d8fbf18ab6addf117af2157c4d13297c47743071f7932c902890510ea0c59dd5e14eeeb3a147b11bf39787e17a5d4966ae9eb5ea43fd150768cc09fd147891f87947291c61b4695d74ddda743ec995b7908afe38ad4f6d5e359fb40aaf489a7a4eb58480e7daa01a4919de1ec7494c326c3056d2bf1cec0ee165b00969a9173b98a614cce0bdccaa36fa0e636f4ed4b212dd088848a4f509cbff3d0f6bef613404d7b0bd90d6a8b9c1b0928c8d15cf057b111b9173ba9a07af0616b7d13af1dbc29b494462ab6484e51b889c71dc0e8c23df73231ab4cdfaab71a0ba40e6da76d954c785ee9236e486473fb6929b44cabb2c2b85bee99639c8b9a84be65cc7935314607c76479f927eaaa1ac21a7235c0098dcfc9cd0f4b6470b67f27b4df713b0b13e7d41227e3d420e107c4d9ecec86e4054b497c6e19c3609b09d573633052c60546d32b82304e393b78367343daaba6f592d4e2012e427e63f4e454287226305b9e5bac9eb3e82662fda422951b1343e1f72a035a4281752b0793fa582685e6a5c8b6e5d9ff9ee392370aaddb07b7d8ca6cddc75adcdac83e4d6622ca061c8bd9ed8f56c87bc1d9885002eb86fbbe35b890ec6758baa102b98762bb680ea2f633f7f77332737f1fef6a5bfdaef0458547e8a7b79c1dceb6739bd29d96472850565a43480636647fef16021b1e430aec2471cdf1d7c9a6ab573081ceb573ad18729784e78a0054016cb38870fe48e48a8070aabb03fd9701f5b670d772834589db835848a121c4b14407325ce7121518adaa5274eaa555bbbfec7f507b21c27116121f89f3c84167d4f1d42a2af145846db53e9c2a8f88f77a25f2087fe7745a025a8743f09c926719cec16db56ad11db0f1ab8f2648311639eb64dac15d4fb0dbad430fb8d629c3ef2af4f9e0968328a4c7d212764a1e94935134ff27240b648dcc23040174905aa7bd36f242e084a1698cbeb7a9a285a5bf611847654679d5e74036f0071d6491de3084f0192a6fb4bd0a1ba3749da843584171a951f2eb3e263f52cb052b9e5fdebff91fbcd6637a3ef9829fe7d93d6cacdaa4f94162192b8e93eb8e8f7af25736765bf28c366e1cb1a519d3136dc07028d1d0c560531d2911f901fb23a26e35a14869aa4cd5d55cfa6d9adb9f4bbc9bf8eec98caa09c3903ea2ed74f3da121d6cb4954b5998316c69b513935428e7447ac8b79fa41b0301304b8e9a05ec247f9ac281a91bd721d1263446209eeb6548a5266e8d2a82791758424e0cc8850ebb2340f6c1b0c24a0c328623826c8cc31b2ce3c059ec341394fc74888cb32dda5f25f5eff22ed26f7b2873c52df9178f28a0ed8f8f4faf432ca70aa6f6f6acb0574754bf8e6f10f4fbd07e9874a51e7fd1fa50518e6bdd9241bc0c027e702786af494739a4b72f37ba08e949b86a4e89926b73817749571dc874e4fcd473617071e87aa2871635227da9257600ccddbc68de9c5d8510187f7cafe3f6220db62d2d7e3af1c5ae926d39559c6c6dcabc38fc0e71a96c95eb2029a14a746bc26c4c0e559fe32a651e218091f5716c0328a510441cc728a83d66c0c519650aaf4dc46e55991649b6f5dd8189dca9f3eb351c8274681d4d644d926d3799cd44d7473f3a30fd130c199bfed08584f7916f1b44eff79348a36351ff39d0ce07df98fcc508a2831e51f5884f281be2a7c83e4b2b16cff1459e1b862b72ecd2696cc483ffc778448a42e0ff6309bc0ae5721dcb988239516dab328c96115b2b882c5112b1e36f52e737a0091007eb02e0074a914ea860e7a7ff042b9979cb9168f5de530e80b68384e1b3276e68693b0046e1f9a008fb013738615b577ec58f9419da832f30102cf6318f5878b322bdc9328640f7136c9b8592e892e675f26c32b5dd229166bc259459c10360aa8eedfeaf893ab8f818703a800b0409c1c4500d69ba1c7e157fdcee9989d23d86a9bac053e7055fa2c596859b3c8c3347f8f223290e4c1a7c5e9627bd5090ce562b27361ebdc2882d93a21dfe1bb0037e83500c8a81ebca2c5e3e117b5f0d50b3619fee8f89c18e5fb55bd147b0e89c39b6f8e027631eb1b0dd6d488e3079a55297452c64094d0c3a25323949801e623681a582dd9779816032bf3bce58f94601a8e9f04afcc639f08e81df7202ba85e06802128ca7f5d341b6b4e3c01ae93c12bd92cdb7223530f9993ba1dc0b0508bc08e2011ed3d3305759ac54a85d335bd31474b55a03bc909602fdf30193b3229e2a93a4f9153355a35039ee0d98ea713127cadd4b7ca9c488312930dbbf81bc938d1381b6c292f33385ca92eea8f131bc0c304575b9a48fa03a424e8c9766a179f844f6baac352b6da31e841673660de4ce2b6e6d5caf32368504fb84d1024a5b2f6c15dc4864bf48d8a645db39aed07eb762e9c2247752ceaf76f61f033e76191d9099e6e8ff5a9b787a1b7dd3643dc417f035a20b2d7a1d99e8b1b8dbeae858f6290566f7c608e5cc7964b6fed8496e8c579852b43c3a78060ca91f52afd035a5863491081d57dbf53ab7b4eb52176082bf0d717c68003aa77e82bcb70808601d6b95ca510248af410a722cd81e669d32cf4685f37b67487245c9a13497dccb9a30403efa4e1bb120d7540b4dc39bfd4992689c412146c4ac0f3043488094bf3549bf72664a58626d015df30b73d036f88b82b22b6807edbb5cf506b8b5d6ee6bd871ebcb3b8adaabf107033b02e92e0677ab627f5c844a19e891940a7f0c3c28ea98b5b338e986ed6e4dd6e25311eadc37cce458d238fff787079278f02efdedbf1dd4209ab789dcb4088d7495345d94794a94025e9caefa53ff460955c1660154668fe4c8fd63491b2b5bd7f5335c99c7d05dc104ba24172e074092ce5fa7949d0d9d2c449d8c0682236e400cfceda2ab232def19549656bd6abdcadbd12c95edf6c7f62545b3f7916421987062fd76010064da9e389a4577abccaef484c55fe77253d4367a1ff3f92b7fa0565ab489eeafb573af93c4773fda641358ada7250a85ec5348b96a15d455e1cd206a82f0ad00e602d450acd57463de4e23e29003839f5bf84e3a3c415536699d8f961ba8f76152178c7fdac2898f0fea6968926804df265145ce7cb9f5dde543f70e2b458c76e2a53f08069abfdf76f4586f9d31287b1fc08056645b3405abef22d911bf44bc0cc23aa8c29338d6cf775043a4d32868159c596fc75d7a924e4ee242fb1e59c7d22f923448a55625c0f8999351a95e4d49ada8ac1902d395da4e52ea81f3aeb429d9becbd4e6f8057b3a1a3d48b7607227f9bcda609b68be03efd4eb8a87d9709151d0bafef2ab615b12d9a77f3178c89df1044c0ad048af1e60de6eb617403cc7c6500d778d33695b9d37b01509fc46e3766ea9589e6bb3998416618bc732ae38734aad3ddcb927044bd0180281db02df1e54076b5b273739136b4348a00ab2369de94ddb335c8d10c568e10b189a50dc87fa2862b5fcb760",
+ "spend_index": [
+ 0,
+ 1,
+ 835738094,
+ 4294967295
+ ],
+ "result": [
+ "2d734581aaf467bace1e46b59c39c08db99f072fccf6d23e82f9b1f702f458de",
+ "a98393b820c393220b19ac97419980b868d41ecd214d61e2daa6044c4a3fa760",
+ "ef56d4431fd774fa93b02e9da15bbb015bb38c500c4ff276c96ef05b9597ecde",
+ "d3ecb3e839c3a66e296e15c974fa1f0d33c52dd94a4ae5ec27f4d6744c17313e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 7,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": 1967939290,
+ "scriptSigs": false
+ },
+ "hex_tx": "da5e4c7500010792fd8d6c000000000000000000000000000000000000000000000000000000007e46af8600670e1b8f697adbd600000000000000000000000000000000000000000000000000000000bbdef6f60068d2d65f6bbb38570000000000000000000000000000000000000000000000000000000032d173c7001daee86dca936cf2000000000000000000000000000000000000000000000000000000006aa761b900f3e89cd460eb4c6b00000000000000000000000000000000000000000000000000000000ccb6e26800c31e0cbc5c9b6ef0000000000000000000000000000000000000000000000000000000007c58f6fe00fefa15063e583a62000000000000000000000000000000000000000000000000000000005689de2700c319399c04718e01085f77ef49c88c42059d42ca7a64f34426c8de3e6388197bb6e68742b62c0ebd42bfef7261f3950313fb5348377be1f14a7b95157d3fbd0226e22d7b43bb9f9c673c5435e4e0a25186e2c9f5aa2da6d9b1e018092349d7515cd9d2a44f01f84a41b20fb8fbe769954f571bc17e0c8a187c3188f9644a04f1f05dc9c1bc1a17049d3ce44f0e93d0ff50fade0bc4914220a417f0f88c606a32a14d8dbe845e5ffd40f2b082154df5a3543873606c2345a51fe46d20736d0c50ed7e041576d5ce3ad328d6340a37cb92de870a7c817483240fda75a7417bc8d2c1de8734dc523c6f13243aa80ee7c8ab5935d30bcc41f282c6cd3f91dda229a81cdbadca68124bb0de3e4a771095ea80f1da2a7d620bd8a2ce5c7d96ea062a02608eae58b356a379967bcaf927ae3d41b2dab5d56551d0d346c36911640feade98759a6fc0fe3dd7a1468cdaca58772ef7c9f8b1eba14b7715055e2d94340c985ecc4cc2e1216fc2824f0fffa7dfd70821382101b329fa42803b056079272ddfbb2eaf65ba7da081945bcb30af729b41c1856d7ac14ae2d6e59a5abf6e8565774e200f8c6fd01d31b48d3c5b1dcf48c8bef79640c2adbdcb929a8f72fed800ff41b23ad81f6ada2423a0aa2e2fe5dcf20ad7b92861551c9c6e8bd6228cf17a05e99bd5eed4d7a6d4b685a80515f4786fee03c420eba331852dddca8d34a0d136b5be7d2b5d3429e6ecfabcbd870dba31bb70c3350485f4178089c6390c40d8a75ee8465088ca2595fa8204989c2fa59ebdeb8b3c90aa3e81532effbc2570b1ec44a1878a3716c39186ee2d6a56a67b2bbc76d7939bf689d563e17608fa6ba8fe05a0265a4cd1c910ad6e9cfd1271c9e38f1d3471f7ee7f57909d6712d0723c4fc8a0c1f216596616304915263c772111ba3dc6da9b8fc3896e147c9cde7ca13fdc5d010f41137edd51006bd67201d94952091f2ca39494d34e979c2c5897668e5a0828dd9b291e428d31654117836723782cae1cce61cef09e26dbaa140b7dd935b1e18e9820555573e4a93c49764091500121fa50472e53851e3c28e9bd3cec955bb39721d863de139025bc4be8ba05b973ef67fcebf908afecaa127c7f9aed12512392a6d3f102595c3d5a2b3286f4c7bfaeb5c5fbc486399b74966a6abf6e262baea23a2d14332e02fd37014a3d1c9c7c5d3e01670cf5111047e0f5adcd1436c627d32c9e8faf5e273b5639f42303936be5a7ede623355493773150aec93259469c59d68ae2b7a52a190c277d9ddada8176a20e83cf2eeb5b6bd2f4edd9d27f5f99f50db42bb54415ce5dbbe680bed7b908d8206bb5039459f5e1cecc2f589475336671007e213eb21d5657d45b3a33f21c705ed0719f8fa8fb9489753b308eee1d538c5cdeba642771b0fdff3a9e53e58c501bddd7a7469d5d5e7e65935e26ef17d07b8808513bbed340efd109c4804c53fa45c02102605ee740e5b003c9d054b88ae9051124ed669ebe901147a3b37289438b6f4124b321fbbab415524ccdb4f2f47845f08e7b58aee2c166e0d4ddc799c94830ba8798820e535f897fbd8afca6822e3bf4d20bb0b92c759c7d5b60350ec086cd1665adafbb02f605d23bebb19b2d520d98dda7ac6cf45255b8db17bb1e42be38d633e9b4053631199db0fbf58444a5b5781d03b68fd0ceb10c0e936360326db9db8b159de2b9466fff9cfd5e8fed6e4612e2964488192b6398fcc9d3e826aed8b8000002fdac0194f9857e10851d93f9508bdb431a5ca40feb9d5b69b4a47d1450c76f16958363ccdf47967c344c60d0a1eb62fd11b5a1f5f951548014b47513bd1e3a4365f9adac793e028caaf5553697ab6d0cfc0193d709453b5f4e94a2d717e3246f1a6a058557ce0b9bb36ea5261ccfc83cb1a60fc2ea36ba94343ef55b22acd8cab7c7ff573a87d654fa0a4396bdd9f870c0469027c6fd3986c99d83df7e602a75dba070ba7c79b58d1d4ae65c84f70551b47ab9f8ca7aa29b9afabb1d5a2c446b42cddabc0f6d8c2803558ff6f1fd28da66abff385d277cc0b63977d2a53c6feb24f52a324fbe84e6c5f620255759b7e001dfe5c82b473851e81f14177359560714bdf9c2f2a606c6dd3baf68670f6ef095ab26985bf537a9009362c07339e5160065b66ce65d674a84b7c95507cf71447999674cb227eb743e649bbb92fe1ac08a4da3bac66726610754d3b6a64d59d94bea2d2060920ebdb319c52d44bd23fe315b6b86a2ab9a5fc54f1c6dbca08694709ead0dd992d3f418daa01e0026bb481f99a16107166f8594e698e85e2f10b91e75dc9d58c5ca9616a69252263a2faeeed71d64ccb86e768d550cedc24fee65ad9e897769481060679e209212cd4e6e9483905cb7725baff7f4c43c2c7f8b256b731559be1888d99002a768622a51af6bb03deba3d185bef9de84c994bc6196ff4696620169b7f53caf763cc9ea0496cb933fe7b8765d8005f79265f2c9b2d9d82ec810fb02e8832dbfc9745156343ad74f0c11fac3ddd911b6d16a669937d29321c8a606b9d1d3afffd15cafcfe822b44ba2d01216bb06da8294d58e81fc9035b3aafb957d0c99dd72fa61c4c4661f11c585180c512409f3cf3bee6333b0fe475417ec9c2a1f781f3353596eb3daaef8b91576b9deb419f0e4adafd8c5e028efef2e9faab37fad21e8c8188059a5954391ecca6aa9b87002b35e2290ff63dcef5640f60032d491cb72645f97d24276944076e30bf34e386cfc1e0ce0ac3632dafb9fb0c2634077c2f2fdc97bef19fc576c12b7a6f84b2c4ece672ee1c60e26548a1af55c90e6fa04a12352a00d2a2f3fcfad95249d997548c672f52775a86d441cacef8aea861786320730e7999fc0475e8a9afa4ae2097e9709596cd45903555b2d18365a5225696b7ab404ecad8089fa0860aef0d4705a49e8c46f660d1ad90d7b518514ab547a567b7ce06f65ef471381de14d98fa8d612c693b634a9a1c2bff887bdf9de59bcd97279f1203feb5f0e024c81b4662edc92e324162dd7690804ae96af23904b5b78be7da356159928d3123bf37ed90f97cb754df65419ebc9ce97cb1bb6afee8516c06e9327fa0323752832124c4a8c609397fc5be98ab28ab976d17447980c31c37ca2995bef7b0d6ad7fc8cee2dd1f59fc35928fddf01dec12348c3c693c66765ca7200c7e2193bac0656d0626a024d5186c7e885308ebdd055e233c4eb5cb82295a6f5c6472a49dd90b9ffea4aa82900ed8f498be4cd0d444d96ac5ff0c5feb63d7c960942a3308eb4dfd3632692b5cb793aba0e2e0b321d663c86cc5841c91ec570f19237dcc3c575476506b463503bd66d377103f985c3a2d4d6fb325dd9347346bd74b4281ac439dc364e999e5345f5261445c89f758c7b04c67c132db5ef7dea7cc14e099ab2558c91e46be167256dc9ef770e4e0726b694db32b7f56a5d40e34d7ce88406db1556137260e8fe8671ed8f75ae5819a7a81bc45e7cfcda70272b6872216afebf9085e58f0cafe86cfeac94257e596848d95b98ba1667b2e39facb8f69c603ebbd68cad1a4fee47c8c8efc058642b95cfd4e672ceab02a83c58d93179bd2a7de2d5c0392b132c76f807ea754d24523eb912429476410e6fc91b5ee277c7177bf947c3571f8396b78156136030f4108402bfa362df0c7ac29ee852dc1996b5e7aaf3bf0e6ee74dab654e5e5050ff8c43f5ee6d433d2c420b4d0b10c99b0625c358b5b4570eb113589eb2c7f89e33079e9c9f9bd5b6b8add1a101fad6db97f2c9a8db4281b490ed4dacde83dac9bc078225daa5c099fb2cb23727fb56e1300b70c94b1e7bf9a5ee6f8fafc49e91e300b03f884d",
+ "spend_index": [
+ 0,
+ 1,
+ 4201556418,
+ 4294967295
+ ],
+ "result": [
+ "f376684bfa2b0db930959566252814fdc4ff59ba9d5203faa7330d050ad97efd",
+ "72e9356eb5405b41e6b2ac587ddc98d847d0bb08eef936d7fb0860c07bcd74ac",
+ "09ddcfd0d8cf5ab3c2f6af59118f0b2f7bd7624145cf4a4b9145c32f844e7729",
+ "02b1bff8bf3a967804f28065609b74af482b26f4a64621ddeb70d428a32add89"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 9,
+ "Witness": true,
+ "Version": 1625509545,
+ "scriptSigs": true
+ },
+ "hex_tx": "a94ee3600001046790111b00000000000000000000000000000000000000000000000000000000545943e30092a9a53f1c4b2ec5000000000000000000000000000000000000000000000000000000006ee094afb7b4f5af7c7d82265bd2e2b8bc5ae38828fbe8ffaf3091f8ecd537b26b7aa2e3e240f30cdfa8dc2a412bd416bb9b99d503d26886841452e317616b800818ba2a3b9ece930fff3d87773c4a604246a03ee5f0a0a0b4a989708bdbf7280c966c9492e1dd84e9b3d0a84789bf1d8d6cfc6971992779d694ff4a772663abceffcef63b87915658906a877ebbedb213f9536469d33f69bcac651ed5f213b1289ab8199581a4bf27349250ef44b05cf43ae0615b43595ff95b98ddd78ba90e1757864b00000000000000000000000000000000000000000000000000000000da523d1800c1add33322b102b500000000000000000000000000000000000000000000000000000000f87411a8fdcc01bd9a5d2365676f47378ab9d858c3624bcf2df9a516a3c0b9043d4388daec747865a95d5f297c59881192b98a81f2b6af3baf5b36c19ca448a31314f00e4de81ba068cc65a1d764d7efd1a11d8b0982bfb50f374125485e5f081ebcc697f013f8d837d41dee720bb04208768565835328bae9b514f2440087c3c8da37b5d46cf93a6bd93841f6fa5fb64477422875716dda7ac0662c682e20afed97aeaa4ad186fcb18c82b14bbabf4273e00ead6c6175f610e737d6fb2d817b8706e89b78450f04a04afc16bac6cab646697323eda5efd55a80eb1b44a283820390d6ac28b1c13836609ad1aafb7bce2378fb966b087307b1ede3f58d981881fb8781ab9dcb65bf0d360d7da6f8bdaf010a779a1209011545f5cf0e85bc2c43de609fbe2a1efc57e11ccd369f8470e819dda356034f097a6e520e192e158630d6ebcd6edf35961d9868dbbf99255e97234e3c41d468c7b1a225d843abf70d0688381f46da144aa45fabe763e887a670831f844a3867cd3a2921bd275178985622c4fc0540ca3d2574ccddb0992b53e7716eb1d7c92c6be2022f14bf68543fe8149f3fc0ee2e9374e7bd5225622e8f35b4b41a244253736d447febfee9575f98bb2cc370f714485c5fc5ddb785a5fe55d022e75d5fcfcf09b1287f580a860d03c8d2fa4a5de87d9f56b5644209805c61d4b4415dcd71b4e97f802dfd5d60acaf49e7872b3280c301d76bf39c4390723778cf31b80319e948ad8b7da2984e7395fb0ae8fbb0183692d7832ec38f80ceed3b8caeedb9fe463cc8e16f9ac50e139d6c541f72b55ed51fb92abd808f453d34af516eacb831f49512cc72dabc6bfbcde8efd93e95d751ec26bc4af76eb9450c0872aab95f49ff69fe074da673eb3c6ff28d48c5085578639e185b7fa4df87bf247945cbdb7e4681355d5c36b763ec54138dcf19e74321344aec55871ff545cc3cc836ff9d62c65cd510f0cca9943b1e4ecd81101cf022ddfd7e3e609f1183623f01e7d2700dd625b0c781f81274634c48b073e000b910064abd4cd212853533b9712eda61542dbab88554b497f8533550d59be0f18976e59a27fcc106bd36cdcbe93ecdc92588288a043c1ba996b73f4df2e934eac749aafc81914da297c4852b3f4e2beaa5fe134c4e5240d84bddd864913ee59be547c78c6e4dc495ededd981e97bf6437cb88d8f5b34b675bbcf07372af1b5fe9c4e2944fd7e15e85a99b7149c1c7eaa680919b6958ecc569ea7d19e76c820e9aeb1b7f916620778b3df37059578da8d8df69b940b5b84d11a60a35e9bec9eaa708492fcd333d0584435146a29cf2987e5bfeb3fd44548fc8b1f15477aa8f004c2f2f3a8552dfe2a691ebd19e6786da5c851f9ebb3083c4da27bcad3338ee61f2145a18951db4fa729e8d3cf1b52bd6538982422196bfac0cb601d0d54057f1f89b59377e85ea9dd796d6181a23744f555a286a80b8df454d06679da9ed2f16533978b4ea26ca74f3c36a6adafa4d253cfffcce4563e936fa51aae9ef4b95e935bd2dc791ee2bc51f28521e4c51fc867fcfa70db703c750ba2f009c3143a2fd0a63b9551caa3cb90d562b749cbe3cc6b8bf4e6ae0932f949c53be5e1f240834696f14d3d8c99519649591ac3b86b4ca1ad05582aa26c278424d516544cc8f3d6ff78c81fe0172865a971cdc2e34ec9946426bc9bb8dce8cbf9ad7515f9fc30f005f267e56701fc0d34397e3214e9c682025ea6adbe454d693bb749a3050b1f18d665ae6df1b42ab548e5574d9ff63f570dd287e3ad60c2733d4491fea889bbd362961c51bb3b103900fdf2027f7170cae464b486f1438f0085231fd8f3d664c80dca6b4287ba08bc7d7242c6dc9787a217eda280bf8a21795d9c474504f45357f0fa404d3e2e5bca1e5929f66dc5bf01967debc0ca6a209f831f1603a89ab336e0e9c10d4f4b9635daacb43824d3e2b847a4ce64da9e24fe72fda4b5b926686a9344a9fe6dd119f7c4c295f346e2b711bffa3c72fd45896cfd99aff673b98ba4e1766d0023aabdcebe3f345149a56c8a4cd2b6c129fd43351a028e4858f431432aa54b10dc568667b4e4fe36bb61578f3a4dc48f5923e7d5c0a1a6df4d97e94c9bc99592bdf224d70f2141a685ff7f45c86499af059c1b445d3fed29bc3649bd14f32b2ce4ce858612a0ae69613167349f100847ef13a44d0d89693b4b78d8aadcf4d49288d4f2455167ade93d1a5b974c8e196c8b0a7f998426ba6b3d6c03e0df46c5981ccfb23933fc271ebe83d341cbf869e2efc8cffa4233e306d9110f9a32317cc0b1e2b8a7e3360c75322212fa2be127995bf61337f17230f5390780e9828597c30db06ab9649a0627267bfaf7376840c9c0044554a8cc141897d931b89c276f051de68818643eff90ac3a8098c7f5796bd2ad6c219c37bb5fbc200bd83bc8f2af1fec796fe37b7fbaf000570f7586ab2653b0bd68f6fdde362067a7c1348faa2818c9449fd8a6d9fd602fc61f247894c3d0ff817ddbf3e247b98501738d5c7cccbc57ba124e3c6cbcdc164eb1820a0e259a812c5609b3b0a904ae9e8c979cacd5dcbe17f0131bf1ccb89e085515421f71c0bf5ae6146c4b918274d6b89ec04d9f1ce291ffc0f4cfbdc249ca96bed942cb72a9b8d358ccbde6522c3365ee8927f8ce7c526ad36f1d77846399de60f7b6a52dd5bbd522e285943bc9a909dc7ec39251d8e971583ad02fa3dc500aa869c8759d711fae7947cbf5b0195d58b7405e58d4ac9e54a58f9a621a8b51bee3f8abd9d4b6c226e48d92c3420cc7d3303b078715b9d567dffd7d3bac2b5a57c9432112b907e1796deccce0cd4042694958cd658e9d3c04546a9982de3eb37d0ed50a0ebb29f133c0501fb838d62ed0df0d838242911390f4d43f044a15a7715c255ef19b4d5b11dd4731f274707d777b8632515559867a4aa3f003ac3939aa6e30aba14664c99fdfd8934db73bd06294665d6e32f90d5c83e838d7ab72010df44e05d0e5286d561c2a4f81eb587a4b6b254fc8d5daead403eaf3764b89b764c7dd731d1be3174e18b11dd3b6b4e98519a778d6c0e1f499c310af93b1560f96e10efcd3a9084e59c4ff47a0c5c4c7ecfc4e6d589bd6e08bd06e942d1247b88121e50047d301f4a869be59b34955c715bd446dc67eebf193d8fe00d76b23db2ecfc3dcb6a06d056725758f33951c2b5fa120d47b484635e1f2d8020bef59a16cc7421160009ed3b6069e479a824b11893222ff60ed1980ca3bf88de8ce972a644a752163af20b36d943b41970aac4b850a443d9f18b514bb3e03b67d033da77b25fb4f1c489db95b2f78c9665218274e62c98273301bde352ae86b846ccd821885d3361f1d5afc13c1b1636a997ca26dea1b334bb78946fbac6569fd69014c9bf5ab713a2ee8f6a72bc6bf10190258c6f48bd0b395be267414097baefb1456aa0a0884cb33c76a123667ea435cd0de4dc413650c0538ed978e291aa24e93559ece861b675275721f926ecd381c53dfe7291b8cf22f747f5c55036bf465aa4f153cf1624a574b5c080c4ca682d1f42b91a4e82b9511c5d275eec167cf49a3a89450731350eae2c9e5f309ea1f8e68472d3a49831c5c4b4362d8f61aeaeec632b9706983da569b85395823ea55e93b23bfcb64f684a9f4a68aff2c93b86e7cdb58ef623e5d59eed84f2b3eed20a4de1132bd2f812b61efa9b17aa25927e42dbab8c21f4af249905dc0166af99fd611c43607654c01cfa46592c3d9cd0b0776da70f86a1b55b9c06006691ad3705177fe1e6c2cebda66f941eaf97364130787a06b2a214fa3bb038367313e6131498a62b0b30ba56edcbe7a58fce7608310a0228537181fb19ab602a5e9372fcf7492f1ed0beb70be36f0f757d0df2cbe73332dd7ac05d60b2e83e8fd87019ff6bc3d4fb512dfcda6a3e29e1c01fddd37c6ab6c11929cdb86df09441e2d4b0f80d6576b0570ef9843a7607d7b970cb8a8e99314effcfc1f0e913920ca0bdbaafb2234d1a77128a2838d20c4656451b5e8d72ea1efd414b08c15ef9306abc123d56037e1f59bd27d63aa88be5ebe28245c80ca9e0be4c4011407bb4120b9717fab695371e21ed13aa01ab717fad00575a9d85478f1fc7d53302e939716485f3b852d91afb3564021c1ee7a8ad9bf20d7433c16a01451fe4e1e2f6dfd1aecf77bd9303c54ac2fdea612fb2c87df6c34342685a0f03ae21b19748a15cf1a60e3712458a9bf1d2d3e04d2f414b2451f1813f8592898c1c5a36a73d71271aea66e10ec13c2dd490339e5dbbce6f3b16b3b35fbe08160b5be033603f72e3f3ff5aca86746f7250e9a359827d0ca7618ec524c00d73bcd4fae39ba28e87c35ffcf4463af0e48a70c86bcf132aec94fda1ea17caa02cfa703aecf748c6c6e5c1c5d169fe95aeb9a6ea012705c5b01a6c6973a2725bcbe9f9ef40de926702c21d7283979ae1c8b585f3e0004fd8801deba48b98f0262a3c550d27c988f26f10a49267a3d9a85b3c409b50857c67b3ece0331cef7532c133de6e7f6b54a4853698a3244fc6fd15c596ea05458c4424c20b6339c0e744852463beb3ec3cfcf8bbf65d08899dd74d6e3a556a7049a7bd61d698a17b34b30e9941b71350a5be9e9e8e0089a4874e5342849590637b707437f77ff172b712ebd9a9ac1b6e76b2fd33a49f3d36f50497f46c6f2d3a085b7eb0563149fb8f2f39c047f50525ff854b14558bc8f7c8beac426c3dcac538f75fdf4fd49aac42969cfb20585bff065ae5ef60945eab906e742e1e749223590c50118e8359a90a4843de23a1c823dee772648ae06f35ab654effde4ad6c34ceaf25eed5b0a18a505b3cfc207e0113d5518792cf40e9b3aeec4c87d9a17a4e6dc5f2c695526feccd08f5ab9ddf88175342fdbfe98ae206397a3643cbfd14625dc5c82c6298ccd7664f08ce5dfe1a0301287fc001a00c2bf659cb177ff56a62034075ca4aa4f7e8c1be7c628f9d15708de52f91419e873f90f21834047609445f15d252341e36ef057beafd8701d2f319c25614864faaf46ee3f5e36b4fdebc127eda0ca9ce6ed22a9d416457931fd9b0740d9683c1204b16bfb6df57cbe29e7256f34cc3ee19c5d577462ebaa2b4ec7ee3176e57a3f79aa277113d2739a2956160696327ab0b9e3db0ced2658c31473838a29150bcf4ac3de0d46d3aea6c779f907a3fb76e207bdcee02b7d90c1b7204b7c98252606c46a9551d641a7a7140ac45ea398037035e9423c7f63ff7e69e9bb627ad9024f3f8c668bfe5139e811a250a8841c1f7a3ea54a61663c120d0beb3d3adf70d2cd9828adefebf536f0b17d92069393652253f4435fb5a598678de9812c439c4a0ade84407b092fec5efa833da4acd19d7ad43964f418c99c1a5bc26e5508c67f092c04a5535c09bb73407a65565d6ac5d77d3ff6a71fc086281421ee787941473c0b72c2209baecde9ef437fe3754b3765c5ebecbe225afe368d811e41ab8ca75f6cf45f7f1264defee12f268375cdff5d336b63df800e88bb686172b18b9ce4b02f1121e44ec7496413da8a1c32ec09692bd3c2a3f826a9eefd534112cb1e8fdde01cc3319f7151e3dd276c948be81cadd2baba98d7dbf4397cb6ddd4c7b31a3d95eb7f125ed79e15c4c30299514baf3cf2881db7711b8d7af60704e76ee3d86ccbbd0aa86c2f308b8ab89f534b9c2b3a1546b3c9821a0c6b9f616f256421b345d25bb84e5fed0c509a52e1f0796e510601e794019e1c3332134f19c477e4888756a274fd8bb63c79fbf5c780c0b1b1fe937200857d7d0b0d5603f6f1d1b3a0ff9d036b237d2f1bdcaba86d10304456c8c696ea600a9f7c4dbeccde3d115b01a70003ed688814b3969775446edef9fc0c72c1296ebf7e4693ba15aebafddd53b77e0e3804fe4b822196180b8a6d9ed5bce10bacd1403ee2767ba6fca2d776f862446b5dc5fe3897bd8a77ce3eab32eafb75ec6fec7734e476cea87adc2b97e83afedd43cfaf2a624cbb5d5a047d967d53ecf8e72f8adf3c0f24307cb46a16af5df7e47b7107a1531cf92ba131aa35da4ae08877bda6a76249f8f57ad0ea0f9f6115cf2aaae61ffef87a64081db7a1575c5ddedf1629cdbaa784dbf9392eba55e6ee4fb8e52bef936fcdeeb66873fe99328b445719ad443ee1df5d82d6526361e09ec9d0ab477b1e46f6fc23bf333f58514e346168b48d1985acb25e57f74ddf8eaffb148d2dc8d8fe02016a81475b0c29c8cdd9e28b2532892c4b39076106c96fd3e019291b4454d04ec10b2971444d6b66099e958baa1108e46459c9280763fddcd814ba82ab527abb7d5768d9682c1374750e942b9dee5eabdf79abf8451d61314882fbd3013048800148390a072afc8ed947b3ea74937f2b22e13cd03ca7c9751a2d21dbe4d81d0875324fcc6a2583b5bebb87e99d16c80b91d76a346d06e9dd494d762bd9b1d742cd0bbd9a4de5c420da980007ac55cbd5c46640e3ac3bcf084dfe5ced8ff5a11fd807e6c5ee8fe32329a24d3ddaf560dcfa4648314fdc14db47f8d6534cedef625f421847f9226d83b3dddea5b41470e67ade0459c15bb726023b6d27467c5a08044a14812ea24c4e68000bb0bfc90cda986e7c81f6ff341526efac4241e82f6430b430a43e9c4114f7eec04126071855707fe8d1e2787167ddf3a2b8d30f95f38d1b3a2405ce83768780a0648b330dfac7d7c1426f7564103fddc01f370c6b93e266c89104335521b28688187286103eac0168283c11af57ac7f0d05d4f9336c1a30009d860851b8cec27587266059f21478e7ef2752ccacd71705f951d6b55b3afad1d0ebc583be05ee6e0f6c5e756596efdcbc83059f6bb593beaa91a490a556e78cde7e6f3821de41e7324057908131f0c7f37e2837a6cc0f1321ce62b93e399b0b4a79062024783a8446c9b9427349d90c7a4d5ba6722bd48628c30d159948f0f93fff844650a00f6bda9b10faed50f3940f38c5968ab767e80bf4ac572c8397842e8efdbbee5939f6a4445813ed3c57c9b1fd9cd7dd4a6dc40d109194058129e7cc3f7e0487fd2f556fffa898904c8866abb30d66d2c1c6bbb3d042ad8fd9fbe3bb093b2141ce2e4c3c7db1f15859f769b3ab8929e852a3fcde1f6dcd25fd8174ffc71c42f7a64996c65dfdb0c12ea543106fbe9a5bdef74604e103706097a66b8adceb20961602b87a2702ec0b193f22756488cb3bda03d988795b2392e1ee0730eb182142534ee7f4c3208c63aeb157e932271bd934ca5fbd56462cffc8a9f3e6b3d99d8e2d8871304111f2d1c93f26e6b5df35219e5e992c51b5df47ef739bb08b44271059c9dc1e1944d7ac8f6c05eb919aa5a6aa7da1c1b90e8f0bbb104652d26d8a8b5e2fff42ff63930635bb12fd1ad614cfd2501bd4acb786378759292bbf8282711c45aba70d535e33b5ce634fd9beb6d7f1d0b1fbd32688186d4e6f8555236544a2661050973b0ecc043c4d63905dd40189755b2359905ef140aba96ceb5de166187fd0f0872f9a90e39cacd0bdf3a9b560c699a0968b3f092f3284f4ded68f2fb90fe02b737a4aef55cda3411ff463924dac13fa10a7b904656337b0c4b94d3107e917335138b4ffd5f1ab7f54292bcc733fd69d3ae4b34e0e08fd1f5a0d305890b9ac16d87cd7fc97e4cf944e25695f0fb619dfeb5e8acae19827707c3f54f0762da943d8dbea354b23cfe5fe09e2afbf9e21c987e46da2468044a3a5cde33d290666d4a3aac527b0a71c905e9219ab03f0c29d6e54d3422c4124d0ea2398f7632bd71ba93209bbaea4fd2a79585c3c21d631f045e57fbfdca0130e43926801072279cc31ec402215ee3e5e757c17e78f261083211705f6dde460d6a5c02bd5131e513ad7d344e7b55aedd78dfd52dfd1f9abcddc0e673e358976b0c71c50ac2a36cbbfcc11ca367ee9b1e452caee62117eef0da47549af53b89c429eb9f3f79acbad5844ff3dde317abbe534ea297792e3513801dc8248d2cb8f9d1a92badeb6af91a299dd29fa42c5d1d227b03d4a747e54c31b9f3d61f3b9ad05155a30261e8c7d6323591c315b165e3fbb683abf854a30dba09b5e5e5966b010bde007c1b491a70218b8080dffaaf21815aa7cdfa0ed109dd9fa5c5cb2e11600e405a3774e45ca56ea2fd3845d134f3d6a020c5b7840735199a45093ebb8c7f8cb2a242525bff4e597d581d1a705584736b7401a21f4f8715d2b6e9f1323abc953dde8e2053e1a53a0c07f892b06289274fe690d42359698dc1c96fc18e1ce600eb76a57aeb872831ef5978b5e05377c02719a4e936572dbab0c175dc8fbcad4b862bfe1207ebd76b3fcd0663eaf52d1c6700987a012336b3e832d6ee2cdfeb82b428e269b0325f92e5b7f3a5cb5fccc139a2bacb72eacb15ef991e9815ed4c8d5f89ac442a0c37d528748aceafd7e37fa4721feb0f523b350c4784d8a6da7fd1b6d18ebce4dd39f9b15660db",
+ "spend_index": [
+ 0,
+ 1,
+ 441925001,
+ 4294967295
+ ],
+ "result": [
+ "61fed38368a342a1336624b783391c389a388c8cdc13dbffd4b6cb1d14d5f663",
+ "5a7ee9baa9110eaa3059128e189c6ae509ac87cf1ff8e1d367c04a2dbb969e57",
+ "b54fa08173a4158b4e4f070ec71a9f6c0ab419375a8973fafe5f60233881d668",
+ "30b58522d3d002c2183b16d31e615a7e236d041534f9348506841732136ea676"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 10,
+ "Witness": true,
+ "Version": -185036123,
+ "scriptSigs": false
+ },
+ "hex_tx": "a592f8f4000106e8bb51a700000000000000000000000000000000000000000000000000000000708d7cf40065e4b9d0c8ef8fb300000000000000000000000000000000000000000000000000000000c71111ef002814037f453325a5000000000000000000000000000000000000000000000000000000001ffe84d400740f76d220e3e8bf0000000000000000000000000000000000000000000000000000000029e6fc760068e41b6d3a60b1f500000000000000000000000000000000000000000000000000000000b93bee93008c720b4adf815472000000000000000000000000000000000000000000000000000000000f7d388900619856160a2508eb4263293469c87e673a485139c7e465bcce5f1fea90e7b138534b906028798e78f92bf2a148c43ed94759ab86113a6be774baee58de044d18b2835257c627292f7b6d561b14377ce45a7b0a12fed1a76edf981cc235366749e396363bde8211ab5b80ee9601d1d433822b04500dd6c32d14e368deedaf2f51a41eb8ed771488d77beaed08a70e41d25f72d5e33bc8cf26a5b023935750e26d1a87063ad1213a796793be36ea06117b39ba7ca3863f5897455a80c2a9cd5f6ff415186855ecc867b986bee4c71d70fd0e64e996b72715c71f9d7032f163c81dcacfaaea94cfdf0b0580941468687583017c3d656772be4b5ac32abaf5858faeb566e3264c009fdca65083a4103ad9c694c683713d6e70186c8749b2fcb35e1eedd7c087bfd5f3409a8266538f1531a52bd0d0cae3c8390022a5a95e85145d4a8b01a1818450b6925f942282b956a64dd577367381090753e13e7cb2eb4c3188b92881270282d6c755063854a620e90d41ba317fd49710fbb2ba7e895e715a544dc09317995d9e498ec7b22f35b3cc100ed5249a3bc0c0a0e73a37057d531bc869310b647e75cbee6f7a85032dfe60c882f84ee1a6bbcf97c5a739292cbc5e0978875d89f6dbfbfb2d29e9d4cc5019a5c07767a583100f8027648e9babc85d50db2e9dfd881326802fcb616b3b5e65f92fbb505951ff066dba1bebf9c6fe78c182950a5ce2c366741b00e42491d025db7af388ce99c304f629e97934aa96c807944eca1a07bd49ee8fba88fa023f99017f418a20fa297647308b556e9e7840724b2643d16785ba345362229af335bc23649c13a19110342169229061ecb8b2a9b232aafe35bf87482e9efbb9909da3fab76ed83f968a898464c6ddc595cf7a7ac802a23f70e6b5efea1a5b3bf0c3c0ab7afbeaf577984126cd9943f922601da4973dab58d17fff67a95551e95c2e62fa13a9b8cea640d6c26a28781db18f5444762975955d52dc16ff4b427603f86d581ab40df1caa10bfcbfc4dc8a416ded825a724af5cc4d3f9c1f7391a187a6ebebf61b8d5c02192dfe9bdfb46ea4818d98cbf73d11958d24949cf6b646038ca369d9768f634332578c67ea500bd6b0e76ba43a072f582613a0ab6ea413da30a1b1f544a1dc4304451dd8e01fe38ce9dbaaa5f372274f16d0ba26f9ed4fba285b341ec86da0bd79ae04455ebd2e94e4a2387d46dca72cebc7f92bf194dfb9ab31182c1d0511288463dfca0545a8ef6c02c600ab0cf51d018d780245adaa303f222098e7839e5c174f1260a9dd3edea1d71ce9012e60f2b7dd66c010b6e75fb7bd5de8b79a853f2834cc827ce248c377ca91973fc6514ebff8eea7188b05b36f5cd36ba6124c36e94ad816afdbf19e32f7d5c0959bb617c70ded54a69e1db94d6d006f88aa9cc5f30ebe39dbdb8ff24ac67284dbefbefc3ed7c1861f4b04169d453e4b6ab7cc6fecc83631b2faef2f11ec45b749c81d5bc69cd40291d68aabdb6fd91df9180070004a03696d7963dada036e07f16e2e737a7b16b1e6f7012d399d59b91f19455339ea675703128911f39dad30e14b82947e3a7d329bd40fa08f2b807e5a1d8e1e521479cbbab88e684a7f1c4328a46c5012bdc7b55008d5e12ca1d0b2e996a4caec0becbf8ca2a1b69d767b610e791071e4c1a338002a383ced4c092b0b67ae2caf2fca7b57a06bdd6ef17d9f587362823695d6105360245294e53d2dfec39d4e29ddb7eac0235ecc41531c0b8a7ec0a7311fe2b6f3e45a0f7c65afa43471c89f0b73cf419d469914720d7ed4a30ad43c7e59b22e4c60265b29a8fd2b5ccf83b31f4eee6fc9935ca18ffeea7b7ece9361a6a353e44988f14e3ae548e61dfc8fb6756c5d5e5349b021820a1a45390b4d81b0aba648ae282da6e7d38f1c6b358c7a310d67dcbaf3febf3b6aa7f7065404c9a1520b2ba52c4d66c309ab1d93f3c29966ea72e779c60a0402fd5a58984ea80b8934b0837281a5c7c821ffa2fe84eb683557c2aa26f113adda1f8bdf6b3dd0f26299795bad6930fabb06292c50f1856ef520f7110fe8307946483ac4ce0a26c80048f4ba48022365925ea34fd6e87373481f83fe30bae83a1ab3a830d23360defe7cd1b26a40aa38ec40f82e22f21233055af6739efb49f6fcc59143a22f0d8c4ba7fb4eb6bf9f9d742ba20c84a2124fd41b5f9988a2579e0b337e17e8cedb9d6b633557961f84005a365da0a71b15b272cc1c3ca14f542b1e0ea0cdd0eea992f5dbbd2776b798c050a383e3d20fbf367656f15cdb45194bb8795619ebcd1345104aa9160392ccfa4cf5d961075f0299bfe063ad6cbd027d64a889ecca40c3ed47dd19f12f5baa5aced2942b80e6704ac877a3018be07c0f7b567017a0b041674e6c0c677f475442353417390080dd4bd88ef7e559afc7f7ade37b3a0b6d00bd296c70be73a74120ec94c0df09f139768c526b1812b25b1ba1889a81b35804c3b6dd591a020b163f35ac2b4e23e325350e7c41724578e2902ead93425874a6a7866afbeb94cc08aaa4dcaf4abc6c2f7faad48afed0c0ce1a46fb61c894954d8ba1a880744943f9648952e10a23b3f694435af62572bfdd43a1346e8a728664280d30354a11530848dfa565984e193bf2f80e5541c5c4ea71b63e731367af2d1d23c88c3d6dccef78ca0e80733260b125affdbc83c062c46cbc9f1187711d73ff98e0cb9e1c6cb2dc7453cb73186a40b63b95d284a326098513dc6ed550c582f94af981c735439f4fa7b52dd9d05d1b0cc4faaaf30ad277d9bba88de0db5f10cf6ea9d407f19f6e5d742967333c80b5043d972d6e3a21b650a54e68118da346fa78f4811d3b4d7891286558d239534e9127bc9e920dfb5da93f949ab693cc848825e076d9f8f7726196b87e133b3e8085b2a6b38c5b1c840d3efc6f512d64c0218ad1faa5c749cb565aee02fd5d0166df4262f22cf93019bcfdf0ae93f18e3afd615f902b0844ad0e168fc77056c0b636109b94d69d12cf284dbb992aace32c9a32c0bbe5ec5380fa143c8c123282a80c543222df4e22bced32c1b7890a5fb2a67efd5027966d6d68e055c43d0c2c0634906feaa9eadb0b2e0fe6d91a5bca320bd8273cc15db9e0f7dba60c6e8bc2b77a1d70825af39fd0052a6e6c8ce373d3b5e71a8b60a3ed1018cd34de29f2cace3d0157fb0fce42ece8624e72d86df89e8ac9eed176f41db7e729e5912cff3cd81ee07916771505a1890b8d7bc997f2ec973aabafa130b2c5be17c28a13cce96b29bc991b088ceab221ee920b84c2a5cd755019628fd205afe3cafbbbcf42ce72a1242535ec9b100d3603fce9dc2e72febc65c03625eaff0e91b76ea8cac0ebf55782ec1f10c7c40cc2659ed91e1e7d3f30b1e3f440ab8fbeeee9d236a116019ce6aecc8c48bf9fe9c03a210762f8639936c71a65662f269acf39426edd58d2aac43a771bc9e246c283fec3607309ac425a1cbf9f8ed292d015ba9622ace377d1b5c6e86d9a11423541caa1c63bb362bf5ada5143523e9610e8d61019005c4b8727dd9d92987a1dce4ccf5fba3ba3490a374e86eb8ae296dc9166f733d87f6923a3eed1230a01dd7f2083f1cb704e0755d1c1a5bd97799c9cebfe1ba928427fc12a0a67ee5dff4b1470bdd431900bbac2b7da6e07f6b29bbf10c704b36bbc79edc4339ad4868c0fe62170882ec0da64384f6935648542befa1f2204414afbfd854141090f51b927a8551fc5e949b35d37c319e812e89de5ebaf2c03e635389a5e37546006abd699a42ca3c6120af0f0a24cdcf60d735849594a6aeb3899a51c37afd9c5684032d22df98124733078f8a1f327ffafa2e9f8a142a8d8df4b9de5b70bf88706e78525cda73e190d6f8ce061353a15fb888cf976abbb993ecf7d7c4a8a066bc0c64610f24aaef64bcbe65220b2069134489eb7562aeb7af7dbbfccb87ad43a363bf2e79ec2b0f7c117fd0bad18668e91c6d98ab2616848f371b54663d3903fd26f5ebe9c63d034beb49ebebcc6c0493c8dd91ccd5e59fc428ae437e65f8790f4b48096e2d381a39f8332cdb77d1996451b4fc356a3380f41a1009b6aa5b22d73993fdb373a7bb25903bc6b608effadfd557c4101e6e9362d77e94f641742d2b0f209f4ae631531bc0b1a0597a166f102b64311b477e9bc44aed12f32751ce27a31e0d8723c9a776a61f30817e6c4a4f8cefc00c1c67f68e93b0d52f5f714968b5485bf4b3b0b53a9660fb8fe1aee1c739cdd558773b369894ffb841f16333fe04133e53957ca1b69ec84a0624bbca7aed95dd752871eb76a371a86a532714a99ff10cd593bee078efafbc1e96dfdb8f79b9529ce2835848b84f2cc370827616fa756cbdf59a22bdac3d7d18a5fbe0408c74b0f37ebc8fc00bc4fc5046fd9105bf8dbd6da4f5b8b6fd569e183b67c397e3cfd8a65713cb44eff2de2842755410381344b9f3a8e23deb6d9ba8898699806185f3d978d56abfea986178ba3269241a922b48e1868767a1ee86ac04b188c1102c11aad73997a4dba08ce0ab3d63d71d7bf04876047b7f286c751addb76ae409c4ea330d6eeccb6f4432acc38a1cc059aaa4c587847ad530b43bd791ac68c29a5e428e93b15a43909456b6fa10292ee5a4c532d7dc5e7554f7b467849a935ffcacf99f8d6fd650111d53e07e199961d5088b46450a9f6ce448a93de8caaf1058f65a6613bbedf7ae9cd22aa28a3140c4cc18b73fa4c3bf92f92561af4c19f1635976d1fc239405b2068328e3431214462385b9bc5c710025f06759758dc3d6ff1b62d4e397c7107e1405d6cbbca13a352ce7e04e918bd6bf4f0fbe9b394673cd98aa55d93eb6d11b649e58a5aa5c223650d1024c94fed3d0b9efd48dd4da24dfdbe5c952c9b1d80e057e3efeb51b609d3e1422898db4a8ec004ff2c38104ba42d3584e0915fe6a2cbcec85ebf8939ab11ba4be91b35ba6ff694dc45d4aa7094a86ada6e5f5a522902f0a134e61b5f5f7daae5936a9c38d85f29df0e1a77323308669ec947f7237ff4053160ba6d170330f726a7b2f59dbc1680d401bc9dc7b29640ba834904d6f1b293f5989f2d65611addb03e539d62c294d184995600f5d369de172fcedbb9ea34ae61b31f4d7832ec575fceec2ea685d272a854507d2185fd25cc96250869d6908901c5c6fd92012ccfbe6ed1a8fac96f7331cd08635e6c3e73338876181d3efee51741760358df9487da9cdccd382dc0567750bd7774bca526b1720246bfd8aa992289459aa5e95ee0b45743ecbe1fa8b302a7e403cf7644e174634e15656c343de781410b2b7dbd0e37c6b93bb709b161159887c287739a57d4ee08b9a11083463a8d344e272b80ad6cdb8626901d5b1b0ce41d73a4b107585d13f28de8f9891a799085c826ed2ad8d7bb78c15e1de032cd25c772e63e9695cc23d4877881f73148cdc8161c287478665eeaaa23113a07887f69efc146ffd7dbdbbf9a3bcadfa7c64fa293f4d535550e8419c8bc4192fb6c5dce42aa6dc9c67c0e967af4438390f0e972371a5216c0253863f34c6c4e631b522ffa1889f4c38017e0b23c3fd63ecdf486ea34f1fe019a40a254277c4ebaef0ba2362e25fbe7f806c7c227085aa6231932cf303a87658fa7a4c001f0d4e46a5edf05972c2bb6bfd2f1501837135e8f8b6c2e079936002ded1a010ea9f171b622d3ff68e234e20274ec550d02acbaf5fbfac2b737a8ac6023ab533dae8ec9bd8401aa0d0b2fba000001fd2f01404141e579ee903e56f1289243287c5dd84e17d7b55a303eb34c2797bcdfd22c36f435bf8812771181ece68d6e5d6243b8668e54b86788aa5649a7e233da4905bc311a5915019b062e61f0cbe3e90a920d2f0affe0dceb8f275ea37b006e3f784c1abda9cb69d750b29bdce86cfe03a649d2f8236846936d3394ee53a8b5a73e4af97ad20fde17b4d63058c012b39b0b0469da5a2d0ce8f7f9c5d4f65f3f8ea0a8fbbb8b4a9f6f156ebc54e2860c82ec59879f3704f25bfee0866f4d68c6dad93119a23f167d21724ed0bb22211f26c055cdabdb3f19a74550bb65f405bb1209b341d0b5b5287eb8a5a2c6c0908b39a4755bd65891ce628fc900df05cbea37713ee7347e24cd8e89c16bbcf87f9226e4007342a2b969acd20e8e49988443fb8edec541aca26f9b7ad5a2e38b385f266abbb711",
+ "spend_index": [
+ 0,
+ 1,
+ 1289772662,
+ 4294967295
+ ],
+ "result": [
+ "c971010563dc437bf26f5b6a07a3113fd9784b8725d9d2188ec91c1f264a52d2",
+ "a38937f3366efcff64e1d6bdb117038a18aa143fbb2e5b86752244913dad4faf",
+ "89e143275f8f32676495cabb322f8fcc10acc1a35b1197c168eb54e1fbb6c982",
+ "85affd74d62d7d0451005be0147e1e1a0b5f9af8a53352b9a0973ae4421abc5e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 7,
+ "Outputs": 10,
+ "Witness": true,
+ "Version": 632683292,
+ "scriptSigs": true
+ },
+ "hex_tx": "1cfbb52500010740e8f8f7000000000000000000000000000000000000000000000000000000002503d248e30e77076ace70e26fcd219b9b6bfb7da2fe31a7fe80640b536b6f84e2946e7d0cb86e3ec469ec52bfb084fa3c79ba3f1a27234354742a68a78b7ef9f8602429e9e7f04490be0dde782835638b16df8dc7735753dfec0b66ad9af204ffc6a7fe4ae94c987117a1b7002f666ff18401727e0943f61b7218d48433deb61571c2df7b4b3166339a78bc8e6a59decbb68af1272b44e4bc4a8c1795fed1f9090c50f78587e90c494b1f6a8e3b3f6cd8eeb23d2390dc0ed7c70ec38d0fe8b33eea242ed0d8f349f8c5dd479d3d21bf4f5b7331b2f662ffdd06d44d17fe30fe8c22e11cfc3e525beec6b625d48b2a9200000000000000000000000000000000000000000000000000000000cc0029c83596530dad7556553e8288c54663c9f586851157d1b7895f5de0cfd012e97f28eb4e1c704b641a5bcaae6ec5cdfb97a4b4b655bc5f6232e2435f8f013a7f00000000000000000000000000000000000000000000000000000000a25ce8dae8d0bd30cc050c5ec668359b7bfff30586601d75650a44148724413213039fdca7c5efe0e9ea35920f8cfd55dee485edf867b21670ec04132cb56109bf31881a792d5c668f476fbc790f1e2869fc256a2d5ade656975f973d90c7dbd89d0b873770407aca7cb1268117a62fa4436934f7ea9495ba52cedf6d3512ab53f9f98f030160e9bed83005f47e366be298218cccff6524f3eb2e082ab64f8762e8202497c5d307f3fd5e36a6ea8ed6afbdff9ebed70578447ef094eb798065cbe67f05182b086e26d08a52a69fe7b289b579e7a4839d49ca250cb05f82bb0374cff7e40866caf731abdf99f9612b4c2f798adb808000000000000000000000000000000000000000000000000000000003646d723007c5c6fed6e889a6c00000000000000000000000000000000000000000000000000000000259275d60b532873914391bcd42b2b4cc3859e21fc8f86ec000000000000000000000000000000000000000000000000000000006554e6f9fdce01cde0bf967002bda3fe15efb88cb1e3eaf33ce78d4d9ba8fb3596f871af10a8a629642cbf2f4554477ebd643352b11bd2aff04071fc580d206ca4a61c1f0f0d95e4a04954363f4c4722eafc091bb96d34f30467c4f1dfa9b11de2d042f028d73f74afe9588f852e196b84d236d0a7fcb26ea5674b1070dc64cbf69cc9afe692232b0758b250eeed4cbdbd687e51876fc4b029b27bbb0ec3c17f64b85ddc5e58972d7e352a5299c1133c94004431b09706bc6a1d036e8b204d7b77895d718d57c5eda7311dac7643d1c2ac235bda874b019f6c83ae637225928bf46bbf54173a5c5612e61d956075c3024511be9f51f08f65a9d83b2f2f2080a036fe744e35e727af51460ce75fa1b5e8d4d502e7143e850921b7520dc6f1b289093c83225618fb6eddbafb041e7236c1fdb8f921bf081802482f717d7ec5eacf0ffdac78eb4dbfc3f34ee84163f2482671f82acb18e7315f08c34967e541d63e279c796a2345b75d4166a0298ac47a2c4ecae9bea1dd47a7f406eac66ca3a42c6a5542c1340f943ff61ea33814174fac06f5341ce7e6a3dddad8b92ee3bd88e78ccb5bd5a7d20c72dba952614f853af114976d00eea017bf408acf76ceb48884903e6f09dcc115fb8149e3198366721fa6a6a9bc854e53a405bae316960000000000000000000000000000000000000000000000000000000045c5aa5ffdb20165f92f6a5c7c09ead853a6d6facd976acd79bfd6f5f0422a051db97502c31654a791f1df0272fcbb102e5fce40805c15c17b0d2d6e2afc3a43e6f780994c4f599b4e203ec6c4703f7a84667bdff6a3e37dab6bb2558217e04b542ba15d12482a280122c3c821765ea73974b6f9328f25525d0d8092e932c685bff1e5dc98acec92f1a5a7a54e64639fd3e2211f7afd9b370310fcb1d8236c5c72493a378e5ccb90124150ef2d36fef47986d64ed1eeedc48bb7c165ac9ae46ac9bd1c7b7e9138cd48fb649affbeec0b85c46b5328eaebde9973a45eba938dde2e73342ee91c14022ee4d605c7ec48fabbfd84ae2a8f1394c44f1c50b5ad4130c7d88c5fec42fb71759670c72230c49cd9be5e3c3010f3345dfae932cf254f00a189edf638b4dd430dfa4297e0ee8ba504f694f59b8b4b3575366869fb949987fe0cdedf3c143a58feee268aec26f507ce5094e6a5e616bd088d94117bba64dc680458cc548fd62d89e48db5d1e8eeeb4ad5616176eef10ca0145833bd9d889ed7d7acea7092984d1e41dc2ee836b1377bf2c28f9d6ea4ce19305e5acb39070b3d1154dfc3e67dbcd9d2c3b81e4f5dfec5e682b1800db327067227066b0a42dff4e340f41924c868d2446d37bf6b0c024a357e127207787f0baffdbd93417605c2d649d8f12b68d24bb1f6e6c104e0ea524e980047184c1beed4f75b8de6a1da57a3c8872a5b7f6bd00a4f9b75bf0522a679ec3dcf3fb02f49cb84b8e689956ad27b6a68265fe0f0ff76b5ffb2afeffc6f241b7374b7acebb4d20252f0fa17f208dd45a644135c5f9561a77ec440b4008910e789152816693ccde8783f1b0af94cc9cefcd840491b33ca75931ea979324136f54edbe30eac853f730a5735ad3e0975c8e75e8f0cf44b7c648e4ca1550989a08cdc9a1239c8f93aa0920d8947f069b0431072f236b7af1ff78b369883c5e4788cb29ff9573d2b259d34cd9b644ca07ef9ed4ab30d65313eefef0b75f4d1f9a56592bb80510804a1b3b25440cfbb02f15c3f8d333411ca73625eda1c72d4b5173335f171fae4b7abf15c064c4c55c42ad8d99647313e8108c951e280a6e08f7212a3f370b7de4b0c99f4a2b9c4c2281105d75fc21057bfa36d817b62dd8977ff4fcb97297b42c63aa12ae3c7deddfa83dd9c16131d5db81ff81b0bc847efe37230355ef89e9a15ee88625d93138634d7251cfa50e801c8ec09da22b3c72bc23bd02e672fc0294484287569d22cea3cc58942cc1b74160e69d587e656f9a7ca7d42b4ac8f19fe8157151ae05503f168960f1375be6801b113bf1b0b11a413e743c2e26272a062b1cd389e531a4ea08c9ab34c52e707d732866e6ebc5a017d8d316a019cdbca19cbae476a412cedf917b72c509b03de852d86a0284e4714f3326aed6379bd7fab762257b7279a4de32b185657a615e8fab2ff3a7ac444ed21bf8c4ae53b281fe33ba3d3e74ca57f8eb54cbccc116d6c7325f82e954d74e33f350143ebec3544853bc87cf5b3227365459b2fac2d291c5d8cad2189a927a65de0325b23bf52ee21cb7857010749a4861e477c6479020f1dbb3d07e4943cb09f916a7cc5c4501d7eaa44a99764127c4c47f9e650e795596aa3c519fbaf3eb332ded4c781fc43c9e16ce1f21b4bde71b16c889ae2d9a907647ad4241e388663e5c06ae9000265d6816dd37467adc1d5a9671bdc5c1f6dec146266012b87e817e5c92bb3732a7c90f1bae3782fa4a61fd0c515a41a4791d051e3598dc30d1fea9a65771f161b4a7ca220defa0cad49fbb1d74a11563d01e0d59b3fc8a2209fd016cd395b05463ca538d972af482a6c81c1ee19be57886ce9d8d41632bb965591f5f0c8d9199d30d320f2deddd21c21d12029c0b0b3de350b40a4679830d0b849c55cab2e840992c9ac04dd915cfa2f3ece904e44575e5559cf403f1003c753f9b9eb6a383fe5e5ca813f23ae7bc0b69e0afa751634d8d46a3344b4e4feb8d89747cb1a06ca8d69dd18e22470ea7b103f37573e8722b4e0182d817ce7e12a0bdd0c33f932a4217eed288c46d697d3a0c466092da8b15677381a771cb6329bb171a42afc1b58f9c04c837dfb42c82debd37d02a4b894532e679c369ef5694b5c9252b0307bcfadf5de0cb6e5ce3b50bb4a7b5aeb2ea37512abe25b078eaa556af334717c86dcc818061401b75ad7428e45a81658af39220989ecb975df9c25601f0b6af3ae30b81ae1e008f506cbc2bd28fe58e8b4bbc0d848405394a9a5dcc8066c748cd82d9d07c654e872395058dd6d7a9cc53ce212c68215ce838a803c92e829f5c6c998078c82a0d3891fc286bfecf071d8bec2da0934f58dfc9c4253d94e1f8e3c774e6461b1050388ba268a404100f6cf2d590f2e59cc29f52451c87c6394cce83c8b04ce1ca5afb63e001bf8b99aff752f9e41b028164f21e610e59b4a6745677fc058bed3b215fcac0176ef4a425762f2b93a02d4673ae6eb51c7b967c154136664576c28c9ef153ef3035f4522cc19d880738d0efc8c30ad75fad6a7e458246a30d6fbac6f86fd911bcf8f031822253bab684da4ff67ae8d7080e90931395f3e61d70cd1db561ec3fa5d0bd046b636b9891e064e7ead4d2745ba78a3b0c09947e0661033b784153f8e3bac5d4535c4b932b492b29d1518a1deb730c1132e2ce4f6e9c9da9126407e0710c8f37d86e4836164cf35a302a412527979fcb1e17e2d56ac2124c7681313d872eb6c09365754e5cdd90b73bb832a4f2165d3801fcb0c4810d37d8f07d337de25220d01f239af918fbd3ebcfc221799323856d6f259f84f33794a149c0f994c1d0f082d217ac2ca4c08271c66f3628fc4d8910c23e2a518d553973078b6159072443955faf3ea16a00cc1a128f73e84ecfab6e7d1eb4a8518764d4a5c12a98cc54fe88288550666495923497a02904a9fb0b5c182fbbb1d9933d33452b2d05895b938bff9cd092488f796a2cd952e3daf40c85e2fe6038870d9edefbe468f1ead00a86b3be9c7fe5a028f5bdd4df57077cc826cdc55b5ca5ff5a61a46182049c7031d6411e3edd9c1ed2bd5976db20355d8a7883271f4b3b62b1d0076cf6413cd209b6c71a1e3dd4f4a0ff7eed310d4685c8b3c5c18e2c929be043acace3e4ce06a0a700fc73ffb004b99f8d3f6f19a037e99322fcc5805d6c9e0af4bda816be0a99b64daed3737d371512ac8ab0674c653b5976c44d2a6752d535d6b0d0699353b098f1a77744aab7507244eebafd5c07f75457d4415e38524eef250fc3e17f63f07c84e52295102f1ad924ece3e12a47087baf0335dae60d09c5818dce4a171763098d80bc6b17f602c148fb8106eb113f8a4624feb32b4f387f5cb9dd784f209cf0b40cd20f691d76ceb68112316ee846c5f295f0b92dc8723a21a62cbb5470bf8c6369e8d83394d12d1b9add0475355fc53c26a3fb8d852a6768ef87cdfbee42304187b1feb352b7983dc505d5b6d16a5b59dcc526e7f4f57ddf8fcafdb3786fa8ef80b829bacae1471564cfd7ca01d7506277f942d32e46453b3505c3bdd33b73fff1e824a04180b2b02fd3201e5a964f58eb9fe6d456d8687365bc025fb61e1416698426779edc304935c7c40b77e734f8a4719a1143506abfae35cc90c015427e5d8e5f711301b13715df9de0ca1aa1c9ec2793becebae862447ee50a1e87d23830d75bd18d669733863f9274bb00c06097d60af40ac4c2c8cce250a9603fc98f773f4db26572da6be8eba111157e170dd56f0095847f278cab301ea14f114d6a9154338e55e80f0e42fa53f7ab912ba0101a76d5184719f6d7b2480933fb036d840d867b1b97bd0eb17e1c0873ba84fb1ffa666e31931a6e1adeb03802e503f7ccbd2be787d762893615cefee231686d4228eb4f04c456a8177005833e5801ba4252ca667c9c731de7c0967667f01659be3cbba0cecd1f1c33609c74b4ddf04347f13d05a9e42990618249f5a73f26c2fea6d3cd6b630872d90a807bd754b5489bdc8ac377edfce91db0e5cca3a94e62cbef5d48855d6d0a74456ba4eebc6059390203cb39a7fd5b6a3d3604169e105d7a3e3c25a2f7cf1b5051381b02eb5240fae7a82e78b7b2b11650405b9e72b0a86fd81019f416ab13d09f757cd171e903464facbe3be563a6d9ed0f9f6bda71d645b87e0a295786affd5b968080fe681e1112ea7864571f1454a0f047773e87b99e366892e5c900ae9c9f4e088ac07f5a00f6da3a38e3d516a94750f3008d9843b5de26623c30148c71edda866fdaf63ee47a28860d4366fda2b9c97aa8df17a239d2bec2f5557ede90cd158a2a9d8900b297245218b1867ca9a4037a59d615a68eb04421726d1ca055f5c2664448ef25e7b0e82f2c6468f8502e5835e1081b0d84b7abf47c7747b6fbb6e981e027c1e9637d231a2fb63b30d21f182693425c3d0cde31be1737e3fb20e95b6a89a872c0a20aeb8fa1258a91911e6f036f40e1a1054f82dfb829448f5abb53e77d15a76dff6dfcd6268afc12efc5d2fa37f355f9a915c4d3098c149abea6b0db3509d8706b5400173bcd11b52c8adc65c0297897367a851b7791c301219047adc20410bb73b8bb98519495d6f91cac3ed14e5f2c4de971470c8439c61a8527be6bbc93a75123875dfcf20ed6eb9b1127bcfb17fe6a7b8c6a7fd1d01b68679e1c45625f3eb18744191f27c381f6d07d154aa5b82211b492b5df98b90a093be6cbec9b53f63bcddad8beeab48643151da8ccdad95da617f9508d99cd4f61619b3a02a3344c3633063bb32809353a63047e426e2d2ed33a076ca893f551e0ff2d912fcd3666601cbbe18db4831c113ca7626c3c3070994a0bebd64465a817e9571ae6cdf4dd0379a3f8b46e84b4c54cd9648640e58c34adfc793493bb28971d20266cd5bd3d2f2fa0fa209ab27a421778c5f78539d64ce7e4f98183573cc31811032d243b87e962a1527bee80bf5abf237c9d78aedfb338b56f9d37b251dd27e5aa10e180fa150a642bfe64b9a12aaef314c726b925cb9ea0c1b89d4545420149e224ab645aa7f91910d6697f8002fc31929c4c5d6824d34d20bfd6f01f6781fcc115c7f7c6fcb7cf0acc72b9ca8792c8e094d19255823afe740706c08863c9030f8b2dc50502833556e0833206b190ea2e22ac8bb0b9d00284c387b32c634ebfb141bcf69caa9f1b6ebcedbb8091173d8b5cb6cbac712cf8efc9bf6678ecf798f5373b4c0161240dad65755eefc28be8ffa48b9797a0332e3a3ee30d1a329ad85e062f0ea33987edb77bfcee2ae6fe719405dbc1b872a3b64652aa8501f10589a0018be1c2a783eca3e7a74b804980f08f77d8e6148691636a259b24f89a67594d127c05e55f33a104f71a6d2f29b0d0e0a5e2a2e23a2a913ac22d89c94dd216517c66b05d2bc7f51230baeea214bcfb5cfe1a1de7c3dd4f40ed42252991210679a602509306a368a1e882324aec1621b2e64603cc7169c0f0190793654c956b24f01934fb159e1ce8e01016ae65cb0643249fd905d05c0cbe8218c96ea8fbd576e48689755d761e7c691dd8098aa106a1810a8362328d8c23f56c342c772bbe521e7493cd74b5e1f087ee90302eca6fdc401b24939258bdf675b60e3cb390e5aab2435d59a0b1039215a337aa8b663651b70ebd041cfdc6a60678996cd47520550868a57694ff7213bb95877da00c12fd1d4469a405022eb1a81ca2f9c90a9631a10a419219072e9807132e9ed063093a50d949cff1b8367e703f9ac009e95367952df582cb1c61a68bfd9ea67048770e3bb3df521633bd5f9d05d8bdc29a35fab8b8989562a089bf8e2bbabb61d8ab678d3cf811b117bccc93457205a5c9aa70f903efc8206ff992c7462b814ce39c534a3c4bf1cbaa61701544e88924039eca613e5e2f3b5f5c1762e493a6f0a2c3af8d6240b32dcd533852132fe486ae07d9eb746b829b5ecdbc547a72b2d22bb926f75a0cec8a85074511e9060be7c931e3e878936abbd6342cc5fa54bdd83517e0cb4c351134f9368704798cb1faed35975aa72c499349b9f35ee9aba2c79934f5da4c4a3f631c16a41e2e672aeb602796c0ea2ed30e1b2e4c42a3c752948b95aa46730fe628e61b5b91a7cc5a76ab8026f7bc24a81095017cb6a752eb4915d5cfcbbeb828827edf21c0d9f1a029ba9a54ae322e73134a9f4160a41a7e230378c6d0bb39c9a83d8f298f121797cd9f3f1f19d40a0cd927d0ed9eb94f2c90cbd50f5c759588da5fd9b014718314f3ddbaf7a75b10210092b5d0976c521b24db0699b8020c0daf9d534b8d4ded49c28dfd3e73b6f669ab564383bcd7674305ab2308088cb59aae588b75929aedc543df0c5ac4d97fa4ed9a3ca48a8fbe7c74b935c8c383a24b4cf71c045b42f163bfebd5a2216b19c6c48e158325b79044ca640c32b8c83b85c3ad5f829563ec1ad84fd131226481aca3783a929936bcd4022f1e9664ac859d7082e938405ec57a940d037fddbb55db2c63bababc89c4946e2e15901396ebaf3a3404a73f8f274c681ca9465dc62a97655b39422562eab306d34ec12c8abebf6204b430477b9588861c3ca764d1521ce9e48e3ea632f4316cfe9891ff2b396fb44f0746ad7f33b94cfdd02aebb0d7ccf46315518a5e432154c9fa733c7049c6c06384272c2820dcd23d64f75649c4ff5575f7a86f8152eb81a9852386e3ded479db614ae321f62ff43646287d16a8dcda99fdaa324da4cec58928600a44c438fc4a762904489aa5ffe55edbca342581c23f97a1f08e17f60f0333a59ae567843813b6ec1fbe23338b11197bf309570bb7fe8f3ac921dda4947416009e1074e03fd9701c043f20920307de99e25e6df3818bd1ec8cdc450950aa4e1f6e3fd832067f83cd611f14e1071d367e1657cf5ebff715f8f8373982504bddec6358338779cd7562a5b7edb35499289fb83db7542327a3fd2bb8cf38d580906b88dbce9243053c29af1e151ebb4478b7263e47111013af7cee1403739d4dfbd1c1ab697eba71cbb3ab8897c1d4f39020868a8cdfcd4f005ef075c362145a5dc8a23639d6fed292e80489b28d64978b94714ee6baf61cf65cb0f8c2ff834d2de8c57505fe19cf4b8ddedf017504e5fc66e023795c6d084025b1478967b3d3a05c37aa1c14d58c5c9fb0257c64179ec664662bae6f9bdc45b7cb87ad0a9ec24144adf1957b32c04cc400b6f3e604946a5ef72a4b5fd0a518f0c315a66837c6055f3e0362e758d4d7478c8e6b0d19fdaba7d07e6604ba962e34ac26c30ebbfd72eca581323028c66465d327345b9ca2306cf3cd07fad775a116428c6c1a1c7f299bf03e92201e4f6ae9677801066ffd8ea4e6576f43257ca0f0b3f085aaed63af068c457efe55c169d4a975518d9752a966c971058d5c4a296248f91a0ba4d8598d59633ccea1be634a67e857f80816c41701bab0af1af996805980470b63838aa2c7ddb90a402eee21e8fcc3a01bb6f58edcf134ac578d7b4cd514ae30204cca56f46ff2ac8c100ff7db6fc74e8a234c0dfed97f5bafd8707fafcb8e67481de7fe894db6ec7e6496dd8b03c0d4a58846c98881e91c1e9f99e612bec3dfb0c820b19e91a28038141ee876929eecc7fc3814e851af12067ef12fdaa01fcf045c59941e5035e20cd11b8ddd40e2aa72cf0f74f3e519e407469a5f6ebac53f44a55289078a00776b487ea0cb3b1cd0d48162a713738a72cf56c0eee32201906fbfdbc113533b4195807db61479d7cbdf32d176642448ef2be97b5f58e65bbdcb6e46bd157a90bd8a28d044bd74f9dfb5d9ce9c85948d752e1dcb587f913d363014ab71f477ff45c0736adcec8300e12e77b0a0c6a224e90b78bd5b708563ed19306e388b9fd7a3ae61097fb9a482c972c5b33e2eee656ee89f6f0e0554efc6da73dcecb70ead0f8d2ac8d1727384c4c51717b6101e94c9f3ec10572f87ddf071dea6be3187653fa2b4e3743689eb64aa02aff507f43dda2d39cbcf715c49bfa640bee3cb8a023596633b2fa3ef9a09e4ef4912e09e492812094117fdb6dbcde7648fef48e92aa9a2a2eb8ca3c15fabbe1e589898189e0f30e9440716073b2e30f9a4b523ecab5d9fff2d605d7655b6c91db20988ae6726d1339f0e285adb03d99c0235ca80442c672d0a0270c41e8f6052430a8480fc1c1a9d730b6e32d7593aa48385e46acd81450df9c0ec9a5c44a35159017604431f9313706540eceb48a0b2d6fb7e89c71e901fd2501b243cb9f954d8b8f8368cf5d79758a8b97576796c5c18d509c95354278a020a0b7673335ffb69860a09db9728c7d1fb1257d8ccd3ac9bce6ce7765b74f8531d53721dcddc07eb7454df4a818575c8149869b7231c4abea270570a67f51139b1ff0a7048fce2477da14ff2b40f3856a21b0926b987f8644f3ce870ef1999ddae736359fe5cf317b104b2bf627b4fdca10a526d4535a9bfdc1c93c86cd096598f1f7e7fccc3e914bca3c41e42b05b14d30cad1db2cb81a88d473c24f7bb40e5bbad7a46dd7a6c8c2e4d0e6ea8d69bbf9586d2874f47e6246bd275a4b424e32fd5dda26504e3fa2b7643237b66eb276d1967cdb81271be91033669629f0cab03569c96d94f3c61afae0dddd035196323e4136c84bab5fa6dbed8af35ad08829e2f4ca51f13c7802fd8f019762865a2701fd9a62ee13d102ed51bf14c4dd249272ad2c2b11cfff639edb559bd3accd2eb1a4461f7b0faabcffe72b0563607ae8dee319aeb9f34dac34d1c8c39e37baa5df56d0b0f1c5ebf9d11f4b837bf6f5b0eaa12c2e2a2589296edbb27632035d3a42bf185baa32a8f9efae6abc8785c0ff09fbed29dd7fac7a095fdc1561cf4ef06c8352bee42ea5558224d7886552a7686fdbebb57b9f3640bb96ff50795d3fb5dc8bd5b11e6ecdfd29226548586bae3863a4aadc69dec312b7137213556a28f7d5309d89f38964659605fbd7f633406ad66fd2e64a036957c75cafd0abc7afae86bf79e75f714285b66c9d57a056a8d2d3578745204a868cc7bfd65b56c659f7a8b5bedbdd79ef91dd5ad566377e5428c0b01942dbfaea35a26f452910e416acc84bd12fb521c5f14e16da9a944b28063693e8308f28d5e7b6bbcf7125d07d47ca367479a38ce7d166dd3d297e9edaeb8aa21dc6ad26162ea6e16292c81bd1bdfb06605ccd09500c6cc561f889b804305fbdc3f3b87d2bd1aeecb5483f466444e5d4473bf8d7cb57ea5a78ccf8eb54c41bf8db67afabe1988fad2e59c0b3e95c47480486e0635a1d79fc76b81c8a32e85326f960d48c6acf73023adc95a02e6f2189d3d9a9c713b0524eb58682d1d2ba39b3cb40ca7fe36ee3daf2edf56f07759744c7ebc4faecd3285394a113cd0dde20bc2aa01fd1c364af98ddedfc694435ac994903d08a80632480061ad16cb3660eec48dd652a99fc112793956ff7c17c53c062b1aeaf5cf0f26a7eb89e2b068e5bfc98246edea3fa2ed35b22341a3fb9c5a81222dfcdda883a9e1c47d231a7411127fe47292ae20109aa869b0500dabc3528d36a7f6750c539386ea71da0889ff6a6c1c6fceffe7854f0ea482cdba6c99e7b199c33fef2da395c3db679789ad78c4989bf03c9811cd54ff754d46bb000146374d108098e05fdaabfbecbcd8a662f97a347366449b5cfadcb90dbdb80da54f49aae02f26736bb439669981af2775a974c624e25e0432ffc7d737871b7aadebc8a5c76baf84d4210df11bda86e44545116d0ea1a7a0cba02fdc2621a41e95108cab01d83b2e87092a030c38eb68203f9c76cb955907dea684fb9b2ead2358474cfd649f915baba237c113d57a568a72db98e905d17356aa97d24b439a84fee8e3907847f5028b9bdf66606d339dcc3ceced74d810217192475cb58145fd6d90f60036040f1cd87ce89d1f264efa049a6198ed2e900fb6d359012366088e2c5e34d80de53dcfc2233e9fda09f5ce6ba451d9a70b292fee607851644570041662666314a20493fe1e9483f729965fb58f8202f838901f36e6aada07b08aaca45e5",
+ "spend_index": [
+ 0,
+ 1,
+ 1123610827,
+ 4294967295
+ ],
+ "result": [
+ "cecc808d192a9f822f3d0fe65f9b06406c53acb64a6cd783b406585b643a21a9",
+ "099a679b991f97f847309a96f0bc71e33f2bd4c06f4e31dbcb1a58583b778476",
+ "43f91b8025baec1f25dc121a3099b787babce80802b1737cd8188c26c17eb777",
+ "d40d554dbb960ad52858d382ad44b4eb7ec6f917be4da8f24b00bd7a5eb53738"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": -1199693507,
+ "scriptSigs": false
+ },
+ "hex_tx": "3d217eb8000102869733b100000000000000000000000000000000000000000000000000000000c7186b0500b5165934b34ff67d000000000000000000000000000000000000000000000000000000009c073fec004e976226044f06990221d7b31cc816fd9aecc340fd2a4478e48f1a24573435b5e58fec618c86f9ef5b28f90c63ce7d250099ab463a98bc1dfab993f8b53b1c0dd69d51b2b0d44f1b27beda090ba650e025f7def2ef392f9e889636b6519a52724a14118f77b49cd4b43008caf5dd9543aab138e336a85467d0be24f4308f004569a61fd2817e43c1222ec3273fb0b9898e095a77cef35afbb7fc9b567d7e02124ae96d15398a81ac1e673aff6294d79e17c0c04e47ae18e80ade55c80305dac6592bfe465468741566f126ffa73850db4086d43c3d645a0b670bb1e87f00c8a6509a1ee76d9a4bfe91f51a36e5f3491b2387df1a0573a15ea3044ea534c4330c0f4627fa6a167099b2e53d17c2fa95d0643b5270685e3e0516d95725fb2cc3f7219163830e6e14b4258177cc8c9bddaa05c09549320b2465f471dc6c094bc06ddde5dacb8721aad1a3ac46eab1abb5e5b0facd59f0d8598d6ffd21c9596c73d7cc0328ee01ec7da03e815f87fcf3c5b4cd684bd6a83fd112887f38a3bed1e0bf2f8461b07f459a3e8c763431a1913993ce4679d32ef1fbaa70965a1caf20e5152e7b2d21a90ba3c79fffc713a2cd12c8d706091319157784b3c9fcc1c9d9dcc488822f5d1e955f210eaf46d02caa7b654d23ffd346c33411fe812078a535c7e4ef152a7219c039b631399ba8717b5379c528724bf0daa87e5e2795f38759cec0a9a6a9d8850fbaafc9be8eca828094ba93c72734d4ce99fc6ea5d990d0cea219c78c19ef246c8087f15785b4bb8b747411c95b1f00d1be2355cf509f1a3208916a851ff87e7417d559f7225f5793384ef30ae6a5f8e625d2915ac23fe4a884c12e0cfadecb350b7b6712859b4c0ec05b38fe28ef1450862009e0420de3c68579c8f870ab50417b7fb2d7a9f9b17e8dad1e16b220d8fd52c56ce35cf715b848984c8558e7c479d0b10708e74fc19f43a79df102f4c2f13f4e5d3a344b65eaa525ea0d52df29877b53dd78d116e1834fd7131f93a160c740072ee12b42132c663887360cbe49b6fce6301d2ed6055406bd794b68c70b1b1507ad14b41e0681198d76d38773592c6fa9c4bb334fb361400c266e3b6b9c939ab7ed6bbd0c5b6c56b43ba0419da478a34800a85a236524fdf386f9e3cced8cc9e220dfd0d60ced5c93638c1a7ab9cf7713080114d2aa6baacdff3edef871bf11cef706dea1c3250c0040d9d7ee",
+ "spend_index": [
+ 0,
+ 1,
+ 4223522144,
+ 4294967295
+ ],
+ "result": [
+ "8d9a8c73db734fa3fc183e185040fb3baa67be526f03b54f5289c32abf2b43e1",
+ "dd2096b3b9dd56a759f368b1e43d0c69c86bbc583eba22bdb69bf0f43fd96fa1",
+ "df608c08ec965201c2a83de9f2034cc59b52867b780ccc276fec845dfe59c25b",
+ "95633cc720202a26d62f9f827fa159c88599567e810863b9021e344c12416912"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": -1735281,
+ "scriptSigs": true
+ },
+ "hex_tx": "8f85e5ff000104ffc381310000000000000000000000000000000000000000000000000000000028d09d5afd6201ee54e6f3450342d4c5bb74215ba323767a92077b9f5f7e658bafa016578cfefb60990a08cf221b1e790ee35cc98b50b81fef4bab14a25a29865a250bd5a29abeefe0e1d4b87098beeaa9a54aef8cc00e512824baa5a3c7b6f3b9271cf99da5b946b73f048d67e6cd2bf8ef4a215f94ce86d5376ef4024e11fb258ca5ae1e4296f6456bf39d1cd9b5be23fcbe336bec2c683504ddbd48e2788d423fceefa4601da5d73d9053c0a9e25165339347f1f7e308b9afebf23a65a436b411601c08eaa3002c741ab2b05739ff95ef7e78adb65137b302ce37d8a86bdefe20577359fb4b4c7b3d21c4f7fb9bfacd140d849727558107f7dd8cc49b2d46b37d6e35d6b0c3a4f0d59599a6c65402734c57daa79fe0d4e3c143f8908bdc625d210897c9eb94d93f6eb929dffecfb2ade04ed4855d64994bd7954f424a1c627dff832bc101f99b74acaa50763dd4272d74c9e52e750dda5ecabdc1eb6948d78f87d1735e14f929da1108ce59ff8737e400000000000000000000000000000000000000000000000000000000320cdbc203ead0cacad7b06225f5844900000000000000000000000000000000000000000000000000000000bb5043d788c687a07d2027be6229e44e58d5d12060794ba4ae66bf50a20f75b9f83a634c80a70ccce7650de8fc42762ca9702027aa6968dd093a0ec75d20affaa898e9c1fab64720f09f22a5f5f737e06997e8fd5de8de5d22568d8fb38767f34188dad7c60dcf725ee60c5070b741f14ef7655d44684751ed6e22170aa5b26e324d3bd2908547bd953255e19fd77ffdb244a7f6d100000000000000000000000000000000000000000000000000000000d9fe45da005a210d4b011ec587ee33a3f378c8bf915d96596c5561538659382ed8c9925d717143ce297c3edce55d077b04e066f0dd33c04814ff65e091796355a7571e15e3e299ad1565cbd54f313aba50cc9b83d04b8eb639c78a8141ed1a602050f15c063ccab4bf412c6dc361be36716928d073a7e0e6425fef880904bf6ce3777db0218bb936e466840f1cd30a57b2909d485040e34663c58fb3d29368151caa4c61ed8b759b3d2581c4a1c710c94cc0e535fbdd9c73d2f543a0caf927a9e7c1e05c9820d304312732fb1649a6d4dc4b9d3ccfbce3e48ccce902d4954f49430f625aa8262e289b19ee1cb08a9a1e25b987521ccc4d2461c36be71f5720027f33b42e688009eccd0ea247bd580759c7f8372797a9a2c400a22141a749cae3dc3dc492a0eb83ebf51d62fff490cde1aaa28dfe481d065384b60c98d01998a8b61ed3663b6e0b4d461cc2ce2c8537093b70dd22d5bdd235836e8561561bbd35f941257ee8381bec20e7572389e73091d73ccf67b6a51ea55dbab446795afe1b619a85a26e7dbaa5e50e382055e0acbfbf10d6dbb2a9a95e1a537de9e7aa49ebf77a24675a7e19071a6fa30535a8ac100e9b8a7c896e72913872b1fc11b9167de507b00291020d18c9ac897f9bff461130f2093e0602332afec99e78556834e36134c29cd87780c21bd1503a3eec4a778a12d2a041ac45116683f0cbacac9f06c91a51150fac9d89d3de0501eda7cdd5dea795a0b9d6a9b0654597ed2c63c3019ebfec1dfd02b4193e1bed92d0dfc044496ba50d7c082d1e4af5d1b9d3759e2a8395cca838cd4fb19211b5833202fd1d015de2bce81ef7a464a58b1bfdfead64af9a18256e9d29045b1355baaccc915e8340942649c6c06a8a5ae0c2185ff641343e673b08750ec4f66bca04a4f5fc31ea4268ba26281738d1a5ed7bb3a0e10e3286dd8894582e06d130b4e2e8283bc80b0d0eee98a38eaba530463ebbd4c66682c7cfdc1e48f3188fed7434a4649c50c88b61b589b73944585965132393e5c2c3eb803b1f7139b0756378353c7b2dad385d16502ccece41654d7e33836c030bc00c5912cd5d59bc58df1b9e9d42b7e1693840399b715cd2b257a8778a29076822cf737ca5ef490d70bae95ef821e37c5b1ac993d87f3bf5d77a8324fd7b7398859672fd9e3045ad90f1dfa74cf1cfbb935eb8674838e431c547b7418740371ad173b1c06ba7c007c1c258f8376bfd0c01cf95133eff377bcddc3dcc18e3fe408941d48e3d8ab940797e37e500ffb7a8e701f197983d99c3ccc8b7deef5ba474a30ec5a2c54a4bc0b038bfe91f7cc523a1f977670cec06e500c42519b1c280bd8527c6a97a23772fa8248833e9499b9aef387e836e9bfe5ab77c0d7bd27e049e4ba1db6c0976ff2e624059ae9ba82656a7cc95c563e6027f88efd28f513a145908196236e795d1081eab8591ca98c9a6c8c4f7c0d26c759a844ab3dcafc2dc8c3cd16dc340a2b9167c50049839fa9b24564c1e6bdf2ba8b122515f1923b057362e09685fe4e6e72fab2ab7c78c36fbfb06ed4217fced8d2435a53b24cc625e9ab9916271f367c84dd812787bfb3f5894c1f10e32868e41b6f4205bc78401e81f6ba376baa4d80ef2e39fd4ff591c942262a765b350f0af63b2c62af1d9baf08b4465d1bf2fba18604dd42dc19ea6ee72245cfc9c20d05647755f59bfde7ed324eca0ca9c44cfb29cc5c77b13c7034e5958217c09f23722bec9ab2f6e0a8962b9980e92e12a473ed8fd86f263f690c13d2a52acd5ddfa770674c4b0a31cb05bc216475913c6e7bcfcb7ca29fc5be402f59b4d1e82413bf56d1715a830ba9830dbd43c24cbbeab79ea0237c24b916dc4336162ab2257a2d5599a70e53cfcc5e193ea2cb36619ed612f5d74e91bb267084573d1522a35c97b78752124706f587b2fffd8a0d7704628003708def1",
+ "spend_index": [
+ 0,
+ 1,
+ 2131463707,
+ 4294967295
+ ],
+ "result": [
+ "4fe13a1cbbe51a9d65bda87f260152b4d574eef0e4d0300270e316072665e23b",
+ "a851f99ab09182aa209c3f4fd664792fd0b92cc84c31bb9516e62576788d4eec",
+ "deaf1eff3294114ce43e1aec0c88cc9cb3fc241ce513bf074e38b96540aa30d2",
+ "03f5bab0971c67b25b3a88311a1bbd1b2a0fe26152e6a937f3f259d4df7459fd"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": 1733870626,
+ "scriptSigs": false
+ },
+ "hex_tx": "22c458670001096f7212f50000000000000000000000000000000000000000000000000000000062a1048c005edf053e8aeff6cb00000000000000000000000000000000000000000000000000000000dac108e300e5d783739466929a000000000000000000000000000000000000000000000000000000002de0905c00777de5af16a35187000000000000000000000000000000000000000000000000000000002afde50b00d1b9cc304ccbd8ac000000000000000000000000000000000000000000000000000000003a56fd7600f01c0d056e9eb32000000000000000000000000000000000000000000000000000000000e1c4a348003ecda43595b67527000000000000000000000000000000000000000000000000000000008ad4f82d000f390b1df02c0ffa0000000000000000000000000000000000000000000000000000000073b185d200b715cbad589ed0c40000000000000000000000000000000000000000000000000000000099d22a0a00a5a351710493b498540927de59c8f7af8f30d26d6c728b59f6187e0301c522d3dbd8c291d8cfd66ce0c06d1f7732db576902539dd2700663fea2169b834fd33ff931c4a9481952c6a54b70864cf6d4a70ac6f3768f165299bfc2f6deea322f58b3cd8f4c87886cb7341b4b7ca4dd8ddc02f233f13b7c1f8d439d81f6c9bba322a0620eda5e7520c92dfb0e3df4104c37281c4987e360e666bd99ebfd2f40f961d37a098437835258215d2fbcf11888768155988b6a0bb4228a946032c2532dbd887c4136482adf7e361d0d5e4d78f16463769d7f050c423835ad76036c7dc8d0e2a83d8c7bd26c66d65b2084560ec8d55abd5ab63177b7731cfa9c638f2eb3b3503331c861c69a517baf8cd002638b337de905f218e4284768b790557a0775271e062280092e7e5e8d2005126edd91089c2907ec5ec0dfbdf333a956552090e47479385a04c853d24b4d1a859f4a09c8cf72b26ce6a886e4ab2411be5b997651d584f966dd4726af6945559989b33043f327278cdee1f5c3b623fc2b872f82281d6d67ae2fbeca6aea5c9b2a22b7a99e8a532b15831a5f0b1f791dfc4c951ebbea55e4a6a75710b1e05c29e4ae0270c888c573e1a4db07136b031b33af99a812d2ed300ff87240e7b2fc0cda7bfa0c2cb9f6a79d5855080771b44df1cf6cecd7452970cedab9690f97527e4c184517dbb01f029626599ebd9b6a876d80504ac0e9dd175617f716c0e107a1a4e9e0a7a992642e31416c97eb89ebb13afddc61d61d0f5f7bf863a8016d46b48c996f0c4633a7f6280a516bb89238946fb76bc19e6615d2c74ac90babf5a5060313b39edc9ea6017836335eabe3e6f530cdc94bd671f2a418c148a69bae6c9b836bc1b3636f2b78fc7aac56836256078dd3878c7ec8f5135e734df6838a803b49e8e5cd9b2b4c8b1aaccf8469dad80b8ad8c9830d9522c5b7d093e6e3fad572b6a9dd7c3e2b81acd1118880c6762e14fb0897e08df8246088750bb9c0435ba4ba6a15d31b833d1dac5a26dd155aac95e5f7915758db1f314c4d485da9277051904a861b0cbdabc0b9fea084038ec9cf8e379d5df3f22ebefef3ee3940190728b5872b467e40a554e21a8c53ad16357296f2c0dcc1dedcff1f0c5e1f2ea070b093d326dba8ead52968dec413b22b422c07c0c1e5efc0cd601ebb4955d65704fd5a0185f186b4e771955f422f4cf3ed6e25ad78805884225a74782592d039004e57618384c597837e76fe0b4f2f8ad5522834d5b5c34fe76369e4dfad831145924b4caccade3bb236cf6a74fc53d1a9d8bc6917b98f12d4abdc132b22e058c68c4fa9f23fe94033012bdd75b1587c896211f1a1453e95a83dda6e5400d1f0a638a146ef6512058161bc585df8f3e8ebd1df87241b3a10ae802fa1e84d584b6d08f7802177e5ed5b5e6a5c92bdac2bab36a5bf20a5f41fcdea3102e0dc6f765da80f26546fcb1507c5ca0831c79cfdacd3aeeabb0ea9476c1b0502c27032c4aba7402b0851d56fb4330645ff6db91b55129617c84a1f0e461d66428603eedf0280b4060f8432d2d98446d8384693c6ad6fd7e86af5a8cd2cd5594689bb2c7405901adbdcfee95fa4bf559f3be9dddd16aeef7f24b3ea637b1923e78861ddea7a7e3dfedac523c10892b7d8a0aa54d242754382ec4aafdd3afbeadf01150a1755354af291dc6e4d5afdb2010b6b8a618ee68fe294d6604b4c2f97a6c633f1446adf96cbe7761c1b8625ad056932fe99c7e73181edd37ab3113dc1a9220f03879274e5d2e103a8df16ba3b617a47378e000a2e2cc6f924b739286e55519cf6f676e3055efa644e2f7ca6c9785f36c05fa620062cd5f3db3afbe31586b65302cd13b0348edfb5dbefa8ebbd4744df86090c5fd59fff5ac4e16b0b1ff5cb88e1771a4093a1b2e27022f59e4809885b0cc2ec371d394dbb9e4e3e2a8a6c8b1d0c43bf392707fd532dc552ee05f071186922a1f4601e0e06e54235e3ea632b35cb398ca8e75406500f978da6e3380c82689ca48d571ef39387fa56a9c73add03eb17bc9205fce7984b86d4f6087b6d34b6c1b13d7f2808180ed8bc8fefa836da42c94dd1f831b333952d16d06305c8521ccc93c99cd2b610992b11a9d62cfb1b32e0e6325eca20f63beb24aa06aa0c5a3d5d0ee2ca3c0853692289faaa18572054745e4416f786231556a2e9318306c17a10f20b9de8b8a6d4d4461eaf41d458ec6162f55db880efa9e205fa62d52cc29af68aaaa1786fd7fd0547f8144e2d58ac931c1edc5f33b518206f6cf35ce96db6bbafc9434582d5b36e28e0925e991cfd6e019554bf4d69db646e3271b99624f611d9b1eb2d21c4e21c989ca28bf9692197ae94ea3b3c7c2e78b7349c2032008f138cc3f2746b6d572ad4f15bd73753e10dd359d31a86a1df75863699546dffe13c2a3a38c9561636c2dd67a2343d8edf6a90a87d51be488ca2c149d19c1d916d657d4b1ed32ef48ce82049eb9dae9e041fdc10c8024ae0b5454f8e1f92881fc8de84e7a52bda9362d315e3cf2c83855b12f39cbaa05c0bc6302d20480f6004a66765668e98bcb65df066270a81648efe375c7a0cb77138622c136da8856e6b124085ea56ffe06a8be180c8975193ed254ce94ab43f159c90b1cfe762e6c8b5fc0577cae3b8bb01ce9ab7d1a7787e13988c53a732e9be3ff5e87145fd3f983ea8a788b3097a94ed7ccd75f6c5182ca64ba92875e4a82c41fde6df1a724ee348b51d8fa415b4f150222629205be4019e0da9d2bacd21e382b57150d9cb11e11bc9c2ce5ab97968b05b4d19841ffa03cfeefa9dd6505832a92e972bd917afde03e4000387fec5ac1ca2d8b3ac2a2c271753bbbd3ba654a0b82d3fbdad9bc7be71459740e6e6320f3ba073c567e7b8e611398308b5d8b626e2f6c02933eaa09286abf9cefb2085a7f2848b902f9903b2256f2f806d353ada1f098df1107346b4d394ead153f271295877c83e9c41d0dd78e675652e42b085c8095e9a9de8f473b47354e57fd8b0cad264f637fd13014c2d744babcbed7c0c578bc1566c5ed637d8e0f624c79209d53a930cebc2e32402b7e0b0b1fb5c6d4b7284553191b8dc387f763f17d3e85fc2157b40c625572cd39f04a33a7b3c087d034c1926486e20b9d42d1e0b73735957ec0d1d3f0356c91f3e26415e97e4dfcd005f7192c3e6665d070e1d830f60ec6e180e575593c4f4837b390bf0e13a7a82e504e6d41dfe74a576b92b0951697cc733544b76b9d5c4a55d134dc84ae1fda4156694e6b6c336c46e2d242de862d1f0d702e1b55a5a4e01434b200f872e95bc97baaf1805fa72c186ecceb1ffef5dacfcb7365941b24d594fc7d7b53291a478315829bda5c482e218bfef52845c57e90eb0bf2fe30329fdbfb06ed257f63a8e173ac1422c4dd658b5e8069776e55f486e01fdc801145af5a25424e31f35169b218004ecda01b83c4405824b5bd3da11542f0532e84e1697a76461ee5e6d1ab09d9cd80b0db5fe2c6b81ba508bec14ba638884a949005bd464769fae70759ac0ac5427bc8b60a299035596e76f14f7bf63fa7b621aab900b9f66f99971ab5a60059b761728c4f669023a8b9f2098909515bd83dcc06bc7b2482fa39cc0c68ac0774f8644bb6946f64468753d06918e4c52f29ad8ac6eee95ae6abd22a702e80d902c888235f7225634883a47bed302c7f401d476a33e720fefb7d168b656999e2ac698aa87c5e8273277b3c1f42fb5c948be7c2aae2e6aaae98e159e21aac7ce52625a7e6905213dc5117be4c54ac3797fd18c4912d1b6e3c4e71d689de23f77467eed4023325d5c437f6d09ef57c63f8378caf30c156685253529dd7277f9ae03874343a12ca699b998eb8a37b5c3c903c582fd6adc9db5e6896d1b5f31b4cc0865d02e371634246164a0da11c3f22f002db813af2056783bcffd14c97eb2b1411794c9e9b22c4a5a11a4bdd7c3df303b8127df65a5e027d6e58e44a4b988a4c351c899d09533b702b85deff28f1cd8075d039cbed8e4fc61853ae823494f388adfaa021e35a7323782f27781d87408321c6649ea3158f2c66332893900017493d18dc5883869c3fd0abb16b34ca6b899078648b8d371d69a2411efec50ec4acfda6261d73bd2a2091a22e3d4afd678487e69fb18a5a94088715d5bc504ddc157b739d6d3253f7a64c62ee97626e33820d2d90335bbbb09cec8d2ef05db06bd952fadd5198e788e17a1e5bccdba514eb975aab10004fd6b013a9a44cf9cb743d0c315faf6ead2f541bb0ca8f592abd875fb9c99736fc9c1890e74ad624d50026389fac8e91541c7209ef10ff8f53d3435d208a3f1fd866dba4c3df7643a1b5fe43f030523d239af63a932f2a0d92f969c9930c218a57e1735e84748d7e83464463898891a4f380bd1d21f7c508baccccd48a559dd2ff04d7ac1b8088a50cfbae0a6dfa18b673a80b70fba0514265473579ad60714d4b058d3ef31fde93e2cd9b8db8b008d4cc5a1b6fdd5c07ce54f88c179e3ffcd9ba45a5aaccc18fa63fd82c4c8adca2e0d23fc3c5118470bd23fe22edcc45b4494e1a9133a24f0b053a1ae10a9d9000eb191a6f7d7374f934dd7b806bb1b9ef4ff2cc2d0cdf41e2c207e93ad2590b1326b089226e82d573dc96f97bcf35391353f5c10b2c246f31d3b12b3444e133dd84da02eef00ff83383c74463018e0c5f4498fac8c325691e78f3d914283c0db2f9a26b4736e5c902cc06ebe623146baad65e812a66138a9f36486b51467c75ca0a7a191a849a3e1bef14c784d08ecfacc10eeca5e3ad4b3948fdb4c7f68f800422b05f9ab85ff9e5658b863830e8a31800b7a1c8e8a2dd8da6aca55f6f53e7c3bbba823817f4a3c8553f503bcfb80d49cf8ef1b744fc16dde83d8f3de9318bb7688dca09850b9578973d4c51d7779d98e8dee78f6c51bd29f0e811650032e9301e567717df8759d3c0d36e1f2cfc811cef4ac71c71834091693d778d2bb7553a1699348c2a5bd7102c9e96759d6392cdd149e0d25db6f43f601ae86c6858ad71ee9f0ec3db6e647d0fda369ae28db01cd957a7d02cd1d215c0c12a7fa52e1d03cd5c661cebcc40d15bf382204cc5cb2c22fdad68561dd3d2b47f2a98b553f97f79e572d59ff7230866a9bfd7201b32437c819d65a1776e982dc23a99078cf39af67a4ba9b750993d2fd1b2e2fb5cd2325cc226d0d6eb8939a4d09931f6b6409820f85c5e2664bdaeff43b02db7a1eafb67478afb5799222937bfa7ee7a876fc2704778c8fda58b156649e13584d572f3a2232eba727e8e94f408fafa6dfe8dfc317812cc8a1ceddf3c0bd39ae7bf89c84c4cdb8337c98e228dece59e42996d6ff71c615aef4680e82f894bfd62ecbc9e237ee4f4c19f0710f601ca64a0fb86cdf55dc307019a095a8dd8231a311583d2afef7c23812d612bd85d23cdb2cfd8e94e16bf597060341b91496ea2700b637c892b92f0d36aa22706f2df9b2e666cb8dfa5f756594d35952fb512dde04819859eab4b520576d586d0f609cf3dd7a0e67804363acadf85f7bb4ac33e86df9957f753fabc917b61e866638e339c0c055edf4cc46fe778de5cf995fe2dba574eaac60b0aef801344900727b1a3307383d6043b2b682ce861f0f1adf698502c8b8ec7bb3c9af285784c133935c5cd0378000974cb616",
+ "spend_index": [
+ 0,
+ 1,
+ 3288593228,
+ 4294967295
+ ],
+ "result": [
+ "d8ce2e1d4f993d80b93d9956f3c15a5f89316530af085a0cea683f01676c8284",
+ "9c67e9fc5bda459813093f8fa21ab952e96e72e3a04d05d067a39c6a5738da4d",
+ "76e1652b9b48ba4f0a01fac838c9760e726099c5f203b5446e532c36e5a9f317",
+ "e7f5256e07be8a1ed57e7cbcfe588fdf1b70c576bc3b7bd5078571839449583c"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": 1754886582,
+ "scriptSigs": true
+ },
+ "hex_tx": "b6719968000104bfe09d86000000000000000000000000000000000000000000000000000000007f415c3b3901b4da5201d6d25f5bb507eb28f25ac0a45e1c60ae59ab6f230ee9e0a8038f669b452ea61c6300b1c5d6e851a96c59427dba1b39c05b38ddbabd990f7e7c0dffd0000000000000000000000000000000000000000000000000000000008c09425cfd3301a8d5e0e291373c1bff507382bae5d6ce1833d8c15e877c107334468aeb6b72c9a09ba11e1aa7d5ef9a9376c6b601742dd04aecf8cedd88994cf42d95812057bb26afc5885a524233543ec555cdd77fe16042d5a6c69d98acfdbf4844fc81133a3414da7024624645b22dc8b56bbd6ec6f34845ad665b16dcbc427f6217d400e07ca77cdf48f2d15282c49f97d92f953c720be235df4c7636d930f72e1d0a1148479de8f7a5034e7ccc2497481ce01c3b0458a3817b0d49cdd68c37ea42cdc4765b361036c9d28cc5e072d1520a417695b9e985dcf00557c1bdb3a1da9ea1810615b005991b10b0dc9cf2aedf0d12ef16b9a89519657cc7e1ca1e24a91d4a0d7bfaea19730a69f10aba757c78c6867e6df21948da8b4590ccdc0299cb73b154b05f408de71db58aba399dbb6bf518e4b10f4ab3a6fcdd55c71b0b05000000000000000000000000000000000000000000000000000000001f993e63fdc7019615afd82fc2b3cd8d062fe3a9e8d8f1fb9b45227251f0f361bb87d276fb98e6f8eca5b3e8caecfc94843582c12214534508bb33f0b2ccd9ef4015da7d972166e41681dabfda8f05c14a0fee0bbd0e6835f5765abad828d3fae2254140ab076ce76dfc627bd5b153b504554504dc5a48432978d289abceef32604e5f1088ea47e296b194e03aae8fac44192915c0462bbf683c1f3502acf15e172c9cffa008d43c6293c5a1f18888f83eaba45ed9f28f7c5510e35dc950c73b67e3e97a2cc30834b2692a3de7d7a24aca97e383feb184e541dc79894b45111a6ef85c86874bdc2034c454e2128af84dd6c4ec09261a43606715ff15de4fad8f61000285ac67bf240d11db76a7944a56630bb18502ddde8c10ceef385764c0586d9ea9f70335cc4efc13f4a90ab313c5a5d1d485c4ded28ae1a63c6840cc8414b83a7ed7d7f794f10df610fdd96a28a3a6884318511efc718eb4b78b0f7552834e088cffabb2cd6de26d651d28a399e747b306eff114f535a0a6cb2e5c50020adbf40637af5aef705c0b1f990037c42e16cb22b397c25d69aa18b20271bc57785ba78d90454c54e6f5091bcc3ae3e254f7324cf5128895783ee7dd0830d58ef45b72e6f80e66e10cf626c23b2e4317edaf120c32450300000000000000000000000000000000000000000000000000000000302cffc34037ca29fbfc7254ef74677d5a0a1dd9edab14430248dee41ee135aa1adc5c3defa628b4eb451fd3de45c412cbabed345de0194b1ef856258b38750bbc7af5dd6811f8e4ec01254685e44c321255c8d6e63d6596548a2c1ae46ee488cd601b57cc34a0821c5c2c70a42629fb17491eab9f15cac1c984d88b1750cccd424e699d5bd38deab6ae973b3caded32bb66aa079bd71f41d12f0c2a631fe211951e1b73be1314386a27249a8f99b476cb681859a7dde3fb7eb39944f4e85968dde8619369aa60e7055c37d2fc5ee61d24d72379bd5db7c9772919356190c8e741042444f242a8e07621e4eea66558e2ce2bdcb835351af05aaefd0baa7b3f74ec2784ab58177fd464a41fe27b54f5c43e045a641682afe78c922502fd7901615845961828f878d854b0f3bc851849456fb0f4b7b4cc5121cab42bcc29c0df4f30b0acfa923a3dafe00ced04bb8673326bf01f386e11c38842786cf06898a15b3b3aff0d5f1d30048ba3dedb31620a58d4cab0174022709e4bc16c815597e6626cfb5291144e3ef992c440233c01cfcb740208f8c68cd8b033f9ee0ed268b7f2d66c0c43f426d9061977495fffd9e34e381c5ff8c7a5310f62b0e44a1ca60435b7f2e3ec142786488556433fdedcdd0bd27496c16e6469ce237e77f2539e0b44ae38a31bd0c489eb9478a282d345acd3e88dab18176e0358af9dafebbd1031e301cae77f14deaf7e2f5e89e968c5c26992660caba67d396449f002cf6445bd52464ed7463e7c2d91d562ab19573b9ecbaa20c513b3b9bfea47b270361f7495dcb01f8cc48a64e12a2f26efd92a4fc1bb5003f6f1b3c96200fafa180f0c1b45b7f1e42fcb729ebd618f7371aafbb383a0a25aec4b8bd11b06531274bb0b99e69e79f651c4aebd6bd7dcd84d87b78b9cb90f28ff907ffbb04efda801e9e298a6283a0d04e9e2b97156ec63a089cac2d886754a842258b3baa9493235b3a5b152b67eaa1c205762d856a0adcd0228d15b40b27c28b4cc6d425fb63b814548b33f8c14644fa9ae59e696bf2987d3a9beae13e80df0c7a1374d8e02d98505fc0653280d6626b212747b5f6674d5fed865b1ea7717f5038e60ae2184d7c38f33a2f1d09256af36006d2f2b8bd7884aed92cbc3e59f88918833a22ed5f8e58af8ef4867c972cd3c1e2fcadcbae449366e597aa42aaf25a1a784a51429046f15bf93c3ab45c7c204e27979b06b921d9bbf158ad15da955425da5f284364150113e4f0f8e984c0d395f20e3b68cdd74a16da57138af2b2b3afea6d5266f1d454465b0a1bd5c99baa8ba28bd0faa8c5a2148b9502d178bc6323a5139211a8e45ca8e17f29c7bbf60e31ecb6ee0f40a833ce368fe76b1226b9a891d025067e52454fdc01d4e15d250d446c9798497111514505dd550ecc1a85e34e4fbe3ee8a36d745c734366ca4ff4332f30f999bb25b75e5a0e6c974afc939745a19e2959fe53332455e3cb177e2266b5b06d7ebae7061f60ac0b8a63a9e2b85dd8b03448407355210ce040ecf4d04ea4257840216c12750535b705938afe6682631872b2f5b5a7fe16bc033a3e51dc8624b8358678113639c8cfed90221b5bab71ed59aac7fda49e8bca12e2798c4f8254e392469a4c707aeb88318108786cef333bff1cc28587d50bde563fab00803bb994522291cb5f6be0734f1a60115e409f695b5ee95a7f672fe89c9798d0e54efc764f09d4fd5d4d76c8d572a94752576c715506b959bf6a97efb4d5816144dd361759626064939eed3ba9f109949f10324297a193ccd0b96c54469a2d5bd03f2802fbcc7f6dec6e41d7232d5faa01b410515ba93b4cee9dadddb096ee7ed26acdcbe2df7d9a09183a7fdf1017ad94f7f5adea6c118d07a1bb4bfe665f56e662b4296c9a45761c3ef964fa68d0ff2acc99b93767bdb84bed5daeecfb876535104cc7d03f8d633a1852dcc5bac2e8a3da14a25e0f2e3ece3fe258fa509ea5736277465c73980dc05284082d2760b4d28e7daf6220fed54dc0ad6569a4388c4e158451755e1da8778b4c719e24e3de8bae3e4a500d025fd7e44890f40e20b2e81e046e97fb4d6cf7d4c0594a507b72f921f1ecc51e526e26931a074e4c886855a60794dbdfbd5347ceb68f920b4dc09dfa95e6937ee50057d176a93107dd79c62fb984c54c0313e0ddb793f1205cc303e2b5cf49508da7d722aa39817377f0100cac0fbaf528ea92ee2ff9a6404a82c246cb64fd512599696f9ca54453b5c289fe2a8c9f47ff06562f6f8022798cd2ab96d80b67663de6926ffe8a167fbf502d75e2cc3762d6f5ea430df86b3a4c092178c8d93d8a17d81d6a3816fddcd7b853dbd6a73ccbaf947046776499c379b32aa61624c4333ec102b6cb9727db72a05b1073ea3fa25c58e7a584b834d843108da493e5ac12852291bf79051fff738d190dc574f734e8d2c02964b26a6e72e79a80ce30fc01307a625f65ff9327611167647f78653b76b52b895c04de7c57c45dc5ab5bd0056ac11ea5b69fccbb8d4230b19e375889a24e0af12e15ecc637ec3f64308029eb1811791cd1e45e8c08dfde401906a55cf1fb1728fbb8678b23892b8106767fd88c6d4daac475d2049602af4c88fc1c0fa35699833f3f1964584106b6eec40035706348da0b8bf80ec902d43b59c9222c4c47b0e2cc583da3782a2a1ca203d549e7a41ae3ace15efce1039d719159630e33c1a58e9b70acb623f836894ed630e56bb1c5f0d53a7c4e5a0cbaf2b135a7563d8c2bc01b109bb7fbb0d7e31c1c1e02975c20d56ac788884602096f119c66a2582c5ccb3b40ac018bf54870398899b1c0f2c8539db367de94dd59d9a477eb59632323e3cae0aa8a3862c02dff0671b774a73ceb065b003b26727bc34a419d3215a9851e606a99f6f67e87681c520c9ab64a357c4193f2992152bd21c82bd7342a9e67671205d58c277973840aa9dc248cfdef8582db39e89b722fd7952469b135728f599f04f50135e9dbf670ce1471ba455af11e9815a644bad4b082a2f0ccb720f160e5a7c99d5708b9cd1100708523679aab25b8df9edd7f3e2b463f2e665f46dfb711b92acc4a2d9ac889273dac6de5b49cf49fa6b861ade01354a090e40e510ef9bc0d3d5f0e81b041d10bc3f44d8c55687ae1b934115739012b8e5986c7986f58706eb34b57cd06dbb081fca17fd012e03435aa7e6cf3ca87323b27ee006ffa1189315d9949d10963107fb2e60fa71bc028d63129abbcbba529195e6dae830736f2e54cf82b5179fc31a0a184aa367f41f288a9fb1cd67dc824ed5872339f1cd62a70e09e900bfb2bc33e6c98f3be2f2c79d514eca0e3d906e4703840612e628e00999e31d49cb77fd535f897bae838bbb82d52ac656b4d14a8c28a360ff99e0c5fe4664690eb148f021b76d34d1451dddf5283e37e53ffdde58628d5f7fba4596ea7ed5de41e558fc1dbb54f59b560f889699763bcd879581915987a283c9b6f48ad6341e960e43012914836d6fd66ea9c40151f26f8940d85644aff50a5f409a54175664954fa9d403d0aa827463fd7044c9462cfe8d06b67db7b5e431e704259c9a2ac37404522d53a018c597cea2c65e33a8c95703887741cd40cef467786c70f9c5ec7abe118931a31a9700119f7ec36cdfcc2a642d6d1eb83192c5c1613bdfb2d23640b962d2ac942064fd357bc65d26a0e5e12b3f176ee2b380b69a5e23794c8858c8eea1a263a8dd65b2c5662850fec717c73c47131851d8e63a342540c395d89d390a1ee7d64d2bb9deb7b8115383a3fad5c9e75f8eacf5a95c310df332e95f39b8192fc4899cfdbe19ae9ca2e0fb037220c94a802745c77f8bd7aa44f78ed2e36ad3fde0fa5965a7bf2ee842f29792bc6941d3092a0749e15359b67792ed5a92eb56057c355349b9034860b82d718f0c0fd677167bd1b2c5e1d47d78e858b22c4f564470e36fa0910193c2b5f64e51a257405334a7554074469ddca9adbb18cf8b75d397c9e73935744410cae8a5b467e3aaa091bdfb57400e3e19a716a29184a48ef3eb050211fd1d0194dff49d0bac4810fea61271d1a7ca7b37aad8a2c1c490558a88bcaeefe462561f59d4d9801aa08b5c69f7eaf563e5b33329348699504ea7227648996c260c74be8cf8d3714cdc06eb743181882330e74e9c421dd820f7d8d2cfa3d5631ae76e6e09620144981ab39e1de4a1612d535f5b373cd618855790e360eea543d2e38b32929cdfa1452149a4228822fc3db30a28132d3502a90802253c9a2e98f4a03c48df241ccf9d1e5bcea45eb6210c2a6f36510b27d516588b7853b22e587776658004372ef9f4eda5e7dee2eca8468bbabfc6ceda592b756eca20d78c3a68f2c0343221be7fa178120107c6a02f112c88526eba614511752d63319749240f937bf2132ce0d7bd340eec501bbd4e8ee4fa7b6da799b38ce0d6ff3f7baa4e046dca81c5c794b25fb0352b63fd9778b35b21425ff6fe3853a88752acdd8b4fa577492b2ae07fb235e8557ce58e87936945a0aa580d784bf8be5e5e0cb7aa5adf3b6872b1497d61167956422b7e05446da6c407cef83d6459251eea4fd1d6f5afc503fa1ad9b8d00218270a238556fde801f36785ae45760a44e3b192fd7767afc2a961cb684b3e8ae7746e7553183c943068357103bccdd1bfa6546fbb74a02d103b58085ff12c40efe2a83537f34393e7b42ca0f641dc5e3485bda65a599b89f5a29d0ebaf8c63f31f356bdfed202c8101740fd87c770783917b0dfcf49a08901aa4860b036c978cafc0be58f7c8e4ccbd7cb70025b6b4e65cab10ec424c7fe165d3b74aeffc7ce13196dce6d9e204e141fee977ecfc7dbf25b2db6a0eb965e15428c2df3fa8feb9366b9c1a7da05f16884fd38665fd6727833e50c64ad2eaa76d86b1c136733e8830b2dc669bd032d22eda3664204b72f81ce4e20184d5f36acaf45b9bece856c34143e296cc9a58ffb3cfd6baf84d0f5bb8d3a152d3bb828feb85317c550a7bbc176a6da8e9580303ac189917a95a144d2437577727284016e8201db43c22e12918bbf741e62d7e9a4c7b5d6f5a88305a6b7be34498707158eb8670a246b30e8a01c8246f2ea410e9fac6e05d77e6e288a9b2ecea55d460c9e7b2cf922a1df2bad4ceaf64fc56dc8ee3f2bd208dca08af340d7d081ac6d00c94132b161104f337278259867539d23cfff7a199702d26d13aa10ced33d53bbe0a144ac9398c1246f7913f867f4dff717abefe0d9357b49395b5a0e560d50c728dd080b90942f8076869c8258de963f3a42a0cb5753ad0da3fd92010c1a9f703bb8c985668faeed360be26a08efe15b5704089cb3cdbdf189334e35fa9fc0980d8500b09f27e826ae0e3e10d3c265b4873568a23f28da2224eb56af4538fe6ae09697171af15639020005d2ad0fd9127b2720cc48f87e04b8109079988d9a1a3dccfe6436ecbb217f1310dd88f6682ba35d13fe3da0bdd495377db25875b17628f4c286fd0b2a1098ce8aeeb0a3d649fdb912b3bd62dbff1986d481746cfd86894aadc6c6dbbda7f5a53286e933eb93228c932c0d4bd3b305ef1e0af76db8f6d2a3914418cbd51e045d34623a4c9b32ed5742f9d78e618de740cf0aa7f09714ea0d97eb039e55ec1859459d89758a30ba7a195dd3bbe3f9602cb8f00ada6436a70d53b23d054c942af87339230f5aca168debd7c91ba671b5aee55052a858eff633a91b2dd8abc86642f723f5cbe910e3314ecc58ca561d2713970a10bde27b27766c3ea121dd5879dedd1a51f0907cd7df219938bfc415a8bc818997b66d96b138d5a28a91be44625e39f742cb0610e54e14fc4363e81e2c1b6c6fe2eddc3c8307059200097b0338cf6172f14fbd2f615af97839a2cb00f9d1df4b1afa867173a86456de48e544a8c1fa136356f45957ee3e82e80daa2952e50d44c37d33cd890fb8bd07a6c85471cf49b5764b18286dee4f590934d4407f6dff9caab986ce96e05fbde069c6fccc88b53a2482a9b0d28a0bb512e8ac87b7aadfd3065dc10b64651564eeee94fe8ee82fec118dab7cabc15cb2ea5af2f12a6eb7a3d223f777ce7afa9377ee4e4bb511754eee876aaf1476481405342c5a795757e05e6c9452eda7b56f4711023e69822ca8047b5e4e",
+ "spend_index": [
+ 0,
+ 1,
+ 2456065750,
+ 4294967295
+ ],
+ "result": [
+ "c82d09e378448c2347aa8b02314eac9cfa4c796916807ebb845ce1c028126a6a",
+ "ed6848e169de1f42c18dcc704df0c25f7b0f4827f9bfa9873e5964f6df654a6a",
+ "df757ba39fb4d09ab4b637e8dd3354131b705e9059886c6b3bb2bced658ab523",
+ "61cffdb2f37ce69bc6c6e8231ec05be879b0d916c970b54bbeb61cee67f8864a"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 10,
+ "Witness": true,
+ "Version": 1850961967,
+ "scriptSigs": false
+ },
+ "hex_tx": "2f70536e000109f85f992f0000000000000000000000000000000000000000000000000000000044335c0500eec64bf50c1476b20000000000000000000000000000000000000000000000000000000042bdb17500a5bbf1a7c9a55fb300000000000000000000000000000000000000000000000000000000a518288000ae1db2440108c938000000000000000000000000000000000000000000000000000000002560ec6c00ea6b2056e540a2ac0000000000000000000000000000000000000000000000000000000025c2635b000aeae0aa3ec6cf47000000000000000000000000000000000000000000000000000000009dd2a48f00cef4d6b234bd3bf9000000000000000000000000000000000000000000000000000000006099e415002c6e9c1e2120f3e000000000000000000000000000000000000000000000000000000000aaa3a8be00c3405a7e384ea1af0000000000000000000000000000000000000000000000000000000011ebf86f005d74bab90a03966bc38b140670c83394993b41faa192bcc2bbf00e8c84cfe3e2280e40cf1918e7330a675f8ed6bff8c9c645949a01eb2e877b3d20648c4740742fae4b364dba1ed09c2eb9b16cdb40cfc03ccb3346256365923f08b6e3971563460fdbede483a37fe322f85983fe0e80ec9fa1dc674321ded07cb0b7e8053e1f6fa324e70b962914517800a1332dbe56ff58acf7b170cb5345bab32984a78cb3ecb0e48cfe65bfbc0e3416ee22c581fc3976b01d2f43abc52d14d6b3137d4f33c1840b336edc071ee3b86ad436d20f848dc6f7bb36652edbf78e8d655767c8df722b085dfb5d15b04373cba8eba2d0cc3cca8ba3359d2005c45587848dd008627aa4b5e2ad12ef5c6810d4c759f8a566dbfd20e19549cda73ffdc82398a215e1835c2813f551df4b79a06908c8a8e0ad5c8ea7f9ae7d3bda24fe46228edc32a9d71145bcdd916f6159169f0f2e3c9395cdc4d88f0643ff15896612ee1ec12d3e9bea09e3b4edb8bf30a0afdb95a33ec4b806a747cccfc217b87ed3d710f2a37193b24595f1a86a4c7ec7c411f18a3d29b3bbbf0ce1fde4445f0c1d539a78ede20f28bbf4d7726f5b5122f43d70432ac8e66bfe2c61106a330842df487463980ca9530c934e2d76a1fb08fca7c97bf7dd8ccce16e1df9a48a380467c6daffbe488dff8620049a2d58f40a4e3814ce4a23798677fbe0b7cc459049a4e08e03cf28b1aede25dada2c93b55fac1288bc14f3d0e86bb8aa242446e5df3bdd068c2892dca2e7c1de634d79dd045a2c8041205c07287c45ec6587172612c09df05dbcc67c72efa72f74890237b7e4be92aeb7e1930de7e56e587e907a5ea9b8f63276530a64927070491cca1f7f8c15e216163cefa25f4957bd0c6d0e1a8718bc44e303c843293aab1ab86efce72ddebce679fb9127d3c3297f40b7cb621e7e32d7c3938509298b5c93d7578628e46004592970b554d6e7c646928e071e6d64f645c7e473dbe2fab2cdda498945171be258ebf8f5e87c6de412479f85dbb30d130a19002090678792191d41c72d52787f3f60b78feeb415ac7bb76611ee22ce49473a6b3bcb4788e2da9c4fb90fb794e0af9dbffa4ad566d338f6df6e5c0bdb325a3956ba076d4825e4040d0373f5a40fdc648f73ae33baba93cbadb1243d71b946bf5d7bbf32f1972d1c4aea869489a2741b7807c8c805a16f5ad540b6ec1553b9a499128f911c41718d2118f7b563ccf55ebacc740d8b349b5a720a388d8126df9b2d97d8038b9a8c810a9f51713a0a84d9085325b8be5ac6cb4e3b02a14b99ed71b73532e59d4a55e5df1f036d880c594f2404c307d04de8feeee4ee26106288ba82b6de60a87c08b75778de94422562d8905bbfa09c2e8f61e2cd1ebda6ccd60425d66a2be59f83f48f1be9eedb5d8d4bc3671361d3898232734cbf87685ecbe3d5f49e768db834328704978c8e75ce1dc780cd5921eee0feb6e6e3d7d19e842269c22dc8ba860c6ca2ffe1ca6cd2fba9f5ff7b6a08c1ca4ff6f6824fc969b24aa5794d1fb8d91c893ff5cf878dafe7ab0897dbb7c16e1ab3a26311b16bb4f09bd93c8882a1c3a7df054171813ec7ad8d5a744261c6048fdf1bb1d3ccdf80e306021d35f58a51ae1d21b980f21f6642ee562db6ff57480b7c752929fc429455e698edb79f256ae09afd3e3e3fdad5a2bde732e86f942bb022fc93bc6e4dfa38dbad3db45ed411f3043c64a8f4e9ed3ca9925e5d8dd5673f6e51469f7f9eddb3b01e3a9827c51c18abb2f358e5a0e0a8ad82452d7fc851633f813ce1d77d2794d2ce74ae2a97710d80ff41198d054981b9b1fef2eafe5bb66e71d7c0dc7b1c8f016c65a55483dbf2c9e587b924e2bf0b43afc36c854a4d1717000ca36a667e1efe33fba38f91ae3c39b0267c6e65181d80ef636767a63cc16f64768db995dff66a4e3945e3dea78ecc54babd5a0d5b449ecd761577cd3f55e0b81305e3cd67562b6ce6067ebe33af3aa1a07cb0a8faaee604f5639af21acdf9ce454a3d4cc6a464bdbf2508ee9c561cf2f00e2511f0453702c9afdf888d8c4b182bbadb4ad45042c3ecaa3c3ec88f24d00678351eccf9d38f2c4e48239ccf94c6f2a00c6c2fd1ed3dc0c9b40150d4e5a0d3974c8baeb040d9e2c267c6007e1f3522b3524cbcbfbe73119630abb7b8058953fa6f1dbaa9373494804a21cc84b6e1359e6a6726a25c2659a89aea05571f0f60e9e011f33b4a66cca44addc19227ac0fa01fb3905b37d34f116785060ea25f2b1c828e5da49f8883fffc4c81ea3906fbdece5ae3be2469ed2bea57f870f3cf9b0402de22bdfe1823b21a61c1b356dda7beed30bfc3b6011aaafd2b063504d7c858b49394c7d6a470bb1cb76cc89fe94b6c26cdd13611cf699022e5f6f4e2e1aa0a5d9616b904f939c024d560b653e9e7f7207734bcbf1aa2633d161c811df4c88ca27bddaf1f6c80ec96b6187b7807ea3e63d80e0bdea17a2c2bc3c7c23df2b423ba99bbca5f567aff27651cd76987c6f3857e197ac68fef1342cfaeb45408aadd7a47693c14516ed88eee4101d6b1f986139ac0b04fc0467ebb13de1fd45261fa3a72b8ef9cd1f770240e81ea5946c7a3b5594f2d6ef955af638ea0717dcb0424fd9491827382cbb19191ab5d60e87ea53947499f33ef753004b57e59c810eb763b90c6c78416f2eab8902fec49a2d4b553338dbd7e50430a0ba38f8d1ce8c07ba23fa036b0641ab7c26f9c6a6636a3e01809ad4ec629d616c2ee3a468d2160e1fc9851d9b232e366a417634c998a3455f9b5802308332b83e9ed5eb8de216e6349a727720694248619822e0b53302d06b4e2fb3e04a13d2629f5d992319713a5a4a71f9bca80b213592e1ef0a506537ac4ccd84b4f54acffd9d187dad2d7748630c420a55d024499ec1a1cdff7d70aec883e08654c2688e4dc68eef97b774c0af5235111590212cbfcc8ccad71d504757e347d41ae8e5223753368e4aafc12d8233410b1a0381cdce6980045ad74aad209731dde0b53d7c8b8b7d85633405149a62f8bbef4d247f139ca57adc10413c1f5f363fcd18b6d10d45d1f6ff0812a868ca1cffe4a2382b7482ba11d72993a98fa68795838d017d6dd3431346c92e44437d0cd7d336082022ac155d9b8edccba7cacdc3dd51e2ec90e80467a4a23e7abb19e89ae5d99ad66eb3cd024301c10ef387828d1fdbe95a6a987c721aba65f6e8eb0e417f8ace678c7b0261efb99f2572d1a089ebe6de2226480c264b5b9378199f82425fb21fe768ef465bb135a2b3adcc72f732b17cf2b7374f38cf36ccec54b92c905e49c359406c87d1554fecc9c76301ce3a4364ad5184d8ca399609c12716eed4239ceceb9f79c3ee9fcc960c85037fd7001f218dfb4201c5fd81f35cd1b9cd5b12be52d69a070593b7f0f6c07fcc824fe9c2641bacdea9b8f056e02173b4302ede936084d0a2265da131be4a760f8c9777387e3270dbe16864478f15cd1058a02b7dcfd7ba9724a121ea665f1530d725c75591175cf907f30710cb62196b6dc19c10580a2a04232352975bf4f9d2df87029b089f01dc421138a2fb9b52859f3688b4eea3349ea6209b9c23c455c11c7c7c16c13d6afdc01dd4ef7c705253274f7a8dd005bd5292c45830f77320352b44f5d965c07bc3ef8005f047b670dfb25f2410d41c8d3a946e939349dbe26229e5c45b8f090db8d7f555583841bdd029148e65b6e178ba4cc2f663a9cd7be81bf2080fa468cc57539704decbb4c9b66b90b5f336abc975cd0897ce3d63eeb97ea6dff6dcb16efc99bb3426a0cf5503d9cb305231b1b7e06391e403d46678f7397049f56e5ba3ca3667b1d128236aed8089b3835098f9f0e5fd2e345c756b6d42f8517db441f592d1a1130da0506f3ce4a7525cde8d07c028557323b40194c4e5c652670bdfadcd7c7bf69180dcdbae7a3f5e5e75dbe9b1dd44453337fc9f1ca71265ac6f6b46607ec90b0e0c174f18327c7493c9ec89b6d41f9c8421a16199cf6e21cf3c200d17a3916eed78b642b2738ee2ea5318582d106ff55932713f90e40edbbca83fbabf015483a0b590d2fad17666a5b005191d0568f8532b26600e3ce1ac76b5d09b79c044c21aa78c6eaf6549035d77f3098a1b93c9ecae5b71adabbae9fae038b9b93cd9e241adca0ff5cb79077c3a35c52100b3909eba72da0b33d028dcfbc741fd6d747b9bbaff07f57e878c11adc874e0c5cc998c7808ae18069ff512bf7a3c4c446ea1f46927e91358c11a37982603f68f35bdc7e745f9c1b09d63435be5646c127e3c5ac10c6896e029049a7c23cce42e42bda087fc701a2d557a37c634e05f495c870be70c8ae154b53015c0447d198b9a1a6a0e658762d5e79c7bcb77b4bbf68667b20b5282179523965dfba42ddd87ffa4bd1c7830af752c831f4ab8b90030fff792411835015bdbb4c5331bc6e401747bb7a6942d54721eac39a404ac7afe75daffda519432aa89d511ee638d7244eee5bfaaa071f4dfa4ede03fd0701fb945082d31238e1d44c9c2d6d97e2aa5727798743c9a40da6e1272a461dc6bea8d0603fa35b269dd61d007f87065b598ca89d8b1226969c32d387da0610fa6fb410f5166b8bffe9d89fa98d6a75b4cd53922c8cc803c195a298d7983467b818a5a988fd1d5ac4ed797da0f2b412ad5b4256ef1bd36255e1fb2279c4c5241cd9ba165c3a6f41c1b965331ecb3674d61b53488ed6e165d0aa851582a9aba9af23d8827b6e5270b028f2e01c9d06e65a7e9ff731969be02bd1dedf4d9b257582dff87182e3b5c6afe36a76960687906b7795fea759861fd65e5f7274535b13067f18b535cd5fe05946dc0d56673e42bbda15bac7c653f1f605a38ac0b82a35f878858542a7d8bdabb3d64b9bb6b7278568a6ca81962afe21b8e0d6748b3df548e3511c246c7d348b90297cbb4225bd1d6abee7bd0da73e79ba09a05a3cf1a9524f1774f6d4a767c21fa2944eb5605f28db18fa3a78e6700f4b9e178271d09d74f9aacdebea26d1d9d9a02323ce72dceeda95340d5bdcfdceda1a78c7e5ae3f08244c826a8c3ec5110785d1097f4e6c525f61afed882f3f17689c14993c2970ad57db6d08d5a927c4eef41afd7730825f292ddacead1db33c48fae178e8fac562b39b5270c4bb513a9474f23a2fbeb758999a5a8ee3b28c0192d908861a00c53af214843d65731b190919835e49d5fb61abb8faa69cd2dd732df1798e6e7100c2cfe41d1a0a61c86838009d7e72d2ed8902de3e4d691f4eb1cb207516f86cfceee6317595df37601d7446ded069b5e128748b9f4eec83d37ef824629fc6d3d1be1d08acc91765918da6f5350c5568320155c9d490fd1390f6d2cd80740896c2537d8f4b10883d295db035ed6b5c1915523aa1445d175379a22616632f54ee4ff1c74703152884d906997df9ef3284951cda8a225c0c4ddd60174f71bebf3d68866b43277afc02fdea0119e43b0f5b995e3bd061691a7782d37ebabbe6f55645039d85ae6aac891bfc5fd44a389a99bd403716e14f2676e8be1308a5b341c04dff01b231eee21fa47576fe0a208b6166f23934db7af97ac638efd93bdfe3bdd89882cdb05f261e0f8cd1177b1ebf6846fa157c586483403e8ff72ecb917e06699b94b5c8b7debb525b450a9c5c18188ffbad5a7459b459151e8a717be46863a77a09850ccb83fd04343fcae6b38a6145b92a57064a3f3ef00c0441ef2d401b76ebe25b53c7a274086c65f8f9d876849e4e34f7bea927daecb57396ed2c9d0d127e8a9fb8f26f1eedf1aa47f83a599e7ec38a8c9f68b0608a9b3617e740017fad3ee95f284d6cd486bd291f64710c8d1591cbc6d79105748f229a7b75470bfe177b164c4d69e359c79c249da9c8b77970f68ee21e335621134595a705b373c376679a5af132a3c34144e47f8f65ec8800b5744c11455e376b5719067e4bb143fe610540cb2bfa6993a892439f8f60dea02872ae1e1c84b5114284b85d0809e30cf8564b8e6082bc4acd8fe0d6cf8520f9108d44c468b0fe90e5138be027061af7ae5b003edbeabbc71c887f7283657e5ffc4eb244bb0a87e82d45434e9e738012493eddab9c1a515e7964250eec0a31393ec4e1f04f302b0d5b52c5ba189b09be8fc3ec9c77e1d9044753abbdc2472fd55889945893183a578a98e582bdedb667c652e1523ce1b4b39d17522cb092e54b9e85cee4a898817e09e6be76c893a99d6260b8befe99f47bcb84248b0682ec4e648db712762d5332f465a8c17b48f52b02b3f9ad34b289cb46456bd22a31c9ed0077844c73853d9485418d348f91c2b72f7e7e6acf86dd0bcd6ae480b5be027f44a2314501aeb46bcb874106b7f1b1e67fd394b203d5e80604fdc8015e38b5f452a13177c96ea1d8dbb09f24e77a75f581e44d6804cbdc6e11fcfe9db27cd719498f59c3c593a3cf5c90ca7cf69ecda45849fe5e42ea09b344e4018fe14e8bb6e1a690e8f9f70d0c90ce8cc0d409dd5c5c3a9e377e01bf13d7f7108a74f27619a8c2ffcf243eee19b4f80f2d8c7a69682551e95da57b6d4fa6cc98641ee863b69a0b3b939bca49162a4b78f69c43c87390709547ebd58a4e1c7b9060952c333026883473984e64682bebfe1d5fc0395e97d3fd9784029dadfda634ab9606a663c2efca19c8c7dc3c45ca6fe4162a4b354c056ac468a65d62b17c0694471bce90db75d471ad38dfdef1b119ed49dec8351f9f8abd790793fd8bee2c7163bba5ffbcca3ca462bdc6ffda7413be2da0dc8017a08909591dbbdc255f62eabb39527fe21de79a8318b93feff109d941a93f1608768365eef42974f3ba832ea06a99c23f9151bd29a4f8011f6a813549e3a2225980dd99865d7a2c174cb50bde4bb67c34fe2ea5b91f2921ac2f02f8181b1140c9f280d137b4787c1b47282c413877ce7c30d38c06889851d3ea5e13a0a5a07b3aa4f1949f9b4e59340a260a7a8331859663aac5e75eb3d579df201e967ee6e69940ed719f24d8bc4ac4d289f0cbad1ae8285069917b8a8f1e2dac42a4a8460b5cf96768fc1f18d0c6551f77c5c530d346c0a2c5b9eb4daa0c12b8a2d1f599e9e0d50620af8e88c924461b388fb5a48269f026a7d7d85b0bee6b1db1f9f9b97bb51ae2fc53e76443a235212a0f901d29f4a01dcda61e32b3153a9d59a4837824cc8f6df6298fbc352f29c962282907d6782443f989ca5db3f5fe46bb80a759efb916c3e8b173fd1c01df03e1edb77a8984e4cc3a8d3d1ea3e7557b599264bd775bfd8a95b57c9a8db115712bcdaf73aa8794d61d3c93e328b4c141c30ab877837d8dac20883e9920e63f99dce69f9a39b47cdc4fab37caecf1f004c70f949320d0ff1502b9c933d6c5c821aaf2e8451a2c84e2e3ba448960531a5cf0a74711f021e5dbb406144755bb01f8f8150ea4af9ed8459ebeaaff6e0c622710f1e5294df0eb77387e312e16de21a6eb4581d6a030b3a6500f4eba9eaff5ff987d824b1d544e6c19a102d8c1d987323de8923671e111aac7997632f702265622bdc77253ebe8a021e7fbd92445a3c3ec72af0013275625e5354cc8b2f1d5fe2d134714f23c6dcf89b2ec2ff2512ea30c847f4182a36d464370557a54c322957404eca9aa27bbf94c50fd2a017cfbde7175b96a6e7b1d9ddfa38773c4ece20005ded28ec04b2e36f8bdad2eef76b566122273f81adae4da7562221c198ef2e7718fe7b453fcaca3082dc7023d4fd9ca49af0597559a157d28d1af720de30c05aa6bd41a02ac0e2abe46146f4e244c1238e522197c3130187a89b3252d4463272479be53f195f5dc4ae7aaa2198ecaddc12999860317056fa2d40323c15f3d127a6e24d3882b40b54f7dffc2dc5c1a58e1e70215f9941f18150674a12c704cd3440330dbfdac013a5eae77f1f160c7c0df60b938dafc8abe82f0cbc9916183b9a014f8205af5d06b9deeb7e698979834dfdd9a93bb62a829c02533bcfc57e0f23f29ca7cefa2ffa34454816571c336bb50284b426078faee677f4ed67e5f67fb3eccaca9234e7071755447b91b786c694ff647f5a45f8802be1135d28bf851dabe3584dc499d4ad1f4e0053ce41186ff37693e46c0e218cf4f4e43754983e246213c24c2e64c48004dd2bb96d4f00e5bb937399f57a28ddeeec97fc5e104d3d0e50e7bc58c8dddef00bf90de90215c514a625ac308abb9053e1cd9189e37a52e03e0c06b981679ae07659a4e61492fc5e34ac51822ee927bbe3d660362d20b14feb6f452f3dfd1579faf884c51db2737f4ce64afe841069b23ac721a851f24ec37620fa96a493ac06842d9544f7f67c77fcf23f0483730fdb901248e6f589347b5d7634040ba889aa39fea76ab845e18d40273e9e7c3a5cea74c3cff610bfb14b79683d51b4de6cd888145c69f3bbf013667d7457b9f8065617c3de4acef80126d9c17a4f23fb96691d399bc152fc89d7f75a44b8b8854300ee28e02ac0a1fd77103caae47763268a92b437fef204728fbba0790f62bf345797f2686262b8c3e29af8ddbb76d908c8084e05f53893290308c9bdede17bb82d9bc4b43fce3ac7cd855825a1f0338d0ca28a047f8309f184823aff0690d9d34ee0ec0d25cb98f7de154f83dbcf2b1ce5af5876f6ca657717439812b6fbff35b5e5f5716dd31079a3104977a9aaab30ffb1bc9f655f65a48c882f86949c45d7fb39f7bfb14953a042ada8d9c0c5e50eb54f365fbc3ae91529697bcb8585dd490bf47a2f69270df66a9d5e3c9285a963554a16b4eae811051a2a80009de0b239b080f5aad76192d5c62209c07d3c56e7f432aa1782b82afaa0b38e8680fb33eaee7d762e7c28a21e30a02f3b0caf31f48f476c53d5ea179b16f211c5ec187a3c98fcbb511d764d99861c1727dee1e21fbcaf7c84227bf7731995e0a1ef9cbfd258c582a7ae19cb52a6ef046f035a54911591542125d1f6c4b2f5ec60442eec120ae41b37d02c075d891de1ad3b2e2cab012d685d566bd06cd06d36783e954e78e183c88945ccec4c6189364a66402c7a45f255e37e66292e18ea1186ba3d413fd7a01b8b42f6c952a5015341cad5df625e47225ff316637c3678106789fa1c3c49a2f3972b6534bdbd913756a20e25ea03b960408ff617fd5f4599dd53c63427236fcfebb6ac7805c8737d33c2b09f72ec2110e82791ea303c3b608b5b13eb15771c9051cd9da70ffd41cdc535681aecacfd88a1be42c04dfd3b2803387940e91b800275714c591d40055f26b3eb6b942bff7c347c49b51f565a9588ce6655480d621378214a1d1cd4a6567451ca003603d1217eba5a3be9376f48d7b1bc96eb21b18c326d56f802c45f52bffc7cd9a40adea9c94f8b795563c177f281b8ea13e453e84cf816fd31a96dc59b8dab3a0c1acff6e6e28be2b2c15c1c89d2dd3bb1a92593539d5279d881306720588f9eb73c9541b248a5e34b96b445f59d8f4e971b1c0d33949bbafeb991e157f57e233d24bd153ad167c2eda39901a1f19b00891218b808242203653dc6d204f81c2423a89ce2d05fa82cd302508f45006f0fc490dc255e74a4232530bc19ebf241764f68b8901c0944f7e141a643e9cfd1201946f96c5efd4a09b7fdbddce6a0a2869c1079fd447f4180c10b0161909047c4493338f3368f7f21cbadefb080fe3bb27ccc9d91509581a1e1ca5fc0fafdcafecbb69a93d40354d8925cb7a46767eed6bd1c277be8bc36ac6c9b79523db6cb834bf1852e3b0a35b3561e7eba16598c3e3fd9eab7abb2f39d8a4f564e17b54f483a305580a9e3f879c3792a685d7c62c923c932ef008c756c4342d467f29e5948ca51f6bac2331cfaa5a05ac94d077c53f0c95fbac8224fc90b5b8d6e011bd776a9f081e95f97db77d60b01741aedada47ff51b9c318e639db6c668dea90d1ba709c48471ce1470c931646fd1d64c6b59b175a6107144ae7193796f480327c9538f239896e4a475ec30a29a98d0c2c940284dbfd2801b4604c746bd9685a0ff9091184bfcd1872745f26264db828c9d705f26df8f733c58879e3b8fe128511668b6dca673983e377eab0f9e44036b8c16353ffde6baff9a148209cf0b86fb74d54cd613d89dcf375c70bf1ddabe97fe855fdd49a768703e20b84e1d15fbd85b221cffd6894cdbda6f21cc0ea6b72e2adbed8023286d1aba504677fb0ff3b1eadb6549aaa84c00285c62abb9f8bdfc0f69c169278c22885fc6bb6ee5c8805bbbeee11472a971317b3c51a27ffe13c87c38b880c166b6c10b856c4d406355f32f557c7b5ca2404cf665699930bac5c7850bd026616d7ae02cc65035e602abb4f40e0ef971f7c3e11b91791273974426cc13d2b981f213d3cd37923ef2f6d75249eaea1c8079bfc6212f4bdc9d5578dbbc1c38471f306c6c90a5803e65f090302aca9fa8826c786e9cd9c5bc78626ba51011c6d2a741ac307e4f9af332faa5c81aa4fff22b6215e85409091187e41dcb551c8d62ec6725f686857529af9a214853f069429cfc5ee0528bfa9faa710ceaf4c0933e83d1cb16354be246d5dd563960a1cf03b3603c24eec5d64649fbb69587903f06c9d99caca7ae5ccba4698417e6fd17bee08237cf8de87709acca4615f31d7c1455633c527cc25371d2997adc65584343de41053f4f23db27992fd00013f69c079874a9fc74307d9f25b863c4dc660a000b8750a875f61c7be16862d8e004c77302a03c292bec3f7e8cb904cbeee85f35ebfb998aed94b41910046c0a959b82719a1fa17bae366e60ccd76fb622ee089431e865d2efea277f170bb203f9e3dcc1de6999e6adc51b93ba9d6aa48102051f1acefecab1ca71b4419964b639c3d07c0f13fcb88a21ec6306d41a78161e24e8ffd910424a313f89224d6dcff75394b51711945bd5087239214c21dd8f22fda18a1d7189626b75a388b454a7ba8061854c44e824c30e45bc25e0e70e9e47d43d8fe594f333d254610d9781dbd4fc1366e7b28dbd1903e6f9de267c8aacb99d311d325e612918adb813c0a863ae8fa772f",
+ "spend_index": [
+ 0,
+ 1,
+ 3276246661,
+ 4294967295
+ ],
+ "result": [
+ "827214062735032eccfb319cd4d6b28b02bcdd985d6396b5df909dfa96a81f21",
+ "6631ada9d609bcf0cd52644496784a814c9e6c79382ff72681d1cc48749f770a",
+ "b06d98da0a034ae6cb6e4525d057bfd85ef972c253713fd615dcd84e4bdc6cdb",
+ "cd150c050a63027a78fafad232300fd1e9fe894d46bd0dd41c8594399e032cf9"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 8,
+ "Witness": true,
+ "Version": 540583660,
+ "scriptSigs": true
+ },
+ "hex_tx": "eca6382000010a1b2959370000000000000000000000000000000000000000000000000000000058eb05befd5e017416f0a12365fa7a467985513ad60df24f5884a0c5eb5c40c0c006ddd6a7ef321ae6bec85275ef9a5157ddb8cd9b1c4bf1a918ecf553bf01542a3909e266cb4b223ce3f144d145f26da57bbe750253a496d74a60d184fccfb7301dc703a3d418550c50a31b9155a2d58071fb7b79a1ec9c20bf6d8007ab34697179069394ac08f42e30a3ea70f74579bfd7a183826971be9f7684a970368cffea328b678e9858486d41e8a9b5fadd2e3ee0f46a7da925992c345679e934f918a3d7818ca84790e9c0775f876dcf258935cf476fc7df4fc127380fe218b1d6fb0c91abf43a2b60269003c3da5358785b7a3f39b16a213b31040d68078c974c292b0fd3e597c18ef397e44d15962c7285fcc107987fb173e9de70304889bd6f7f0def8e99a93c949495e4e08b7435b424ce55ae705706dcbec5eff75ffb025a09586e28552f4ea2b5e581940bed77e82932f0af834d9544d8fa62787f64c3e06263cf9062f93381b20f6642af6200000000000000000000000000000000000000000000000000000000899dd342313c445d60085fdd920549a80fe1a8a076cf71f12fe9c2d8ec62de672955765ff1be6ceb495b7162687f718a4abf41b06c3ba73cb19378418ba90000000000000000000000000000000000000000000000000000000013708f5e701addb97535fda831e8ee5bb8e6ba211ccc496fdf34813b15159c09cbb57ecf39cf1f251dc1a95798957698f0432d3f4caa636cab418ce6f04bad622fe714a283e38e178a8be62c83f4e92dcc829b0695851c08eeb98990aa3ebff22eb59f9363468b8eb0036f7266d6a2018a0a82a1e419a47142189b9654000000000000000000000000000000000000000000000000000000001539f2b8e5148b502f3b0fd8500c36adc49725b119e1dd5ecb3ed6435473d648b66adaf502681169af50887e28a0c608218a832b2126c193e4739ee8174fb751b3c985fa10b8fcd8a795b73b1ddad338e7d47245c78113caf2e40985085b89a7ab7a6626d8b0c991b3307c4192fea89278ec121fa6959f9ce84f5ac16493564eb43b7422e6bcd30d6e3ed61da77453529014a8f169908a47c2389e0b8b238daa8c464dbbe2c18f05faf933157340eeeac36204b5890d6012d58d43246094616c475abbc006ca307cd29220606cfe258870a2ca4b80b711dd02c5913efeb24c7ce465f0d1c2bb67bfa42cac8bf3efa6b4504b00000000000000000000000000000000000000000000000000000000dfabed5f40a981079a2ef0b439503ba5c642b2292823242c3e42fde01e048262438c59e53a7f6840b34e3365fbdaadadc96129dd8d82fcc280a253b8998557259f4969949232a6ea5e37c310d700000000000000000000000000000000000000000000000000000000fe227dbd10923aa7ddaeec15337a8a025546993d83230bcce566316fc20000000000000000000000000000000000000000000000000000000014ba700f00f2bd0796adf9ad84000000000000000000000000000000000000000000000000000000002578775617c09ea50d01624ac11d4324cc923091e3749ec4d85050c5763877dd198398a50000000000000000000000000000000000000000000000000000000006f28e9e009bbda5a458555b77000000000000000000000000000000000000000000000000000000001a0878dbb130b621cc86fc6307746f66767524d3715b546bdaaebcb43c655a0463443213672fb137d4a269528037611000fb24aa0eeba1cef92a197bec1bde6170969688b3427e0c35715b97250fe3d7009606b39c730beb3b5b771aa3b1ec49fe6db398af5ef121e24328e9723fe2e673b91bf16be49a61ffda09c8192269355541e0306ded74620a80c54060ec16b38752be1b6e119ec9c6778bca4b9b8283481a22a67ce32f486790c1014eaa4328b6d6b95bc5ca4a4bab26085c8a8a9c89047b4bc8bea712a0530956d1c54a2acfc3004eece4887722ec632fd669c1e9a6de47a139b2c32bf4c0ae8a0fe867afed261adf40b2eaa67023b0e50bb099463a1903b5acc86e57908e72248744b11efb4e044f4bf12eba2c255335ad9e2f19719d21b340fb298eaa5c0529772f9fd3f03e2c9e831c2617f237597c3dcc19622c40b0cd80d4633671bb9cbaa53a29730c2a7c102d00fbbccfaf728462b5a361db72e9e837145e0113fb8ae94e62d66ab5c5b27eeef73b8d1ad5896520a8d7ebf63fc99eac362a465b38e43ebf1ed0b86bbaccbf16c829a5374ec8ffad944092058b857af89b79672f71d3420e0695e400857b6b25bcedc31e3efc5fa648d4e6026d6b184f90ca8d5a67d350e849d0da3fb8e4e205ed8b7aab2470a9415a7a4e89a15bce147d063c53f69b47ffa2527a4c4e4d5bf505589474a798b9d708d50bcd26ba315bcea192a97940704d4c13947262dbcef9a3546da9be116b990e93d32aed1049a1e66f62c28c70cf0a570e79fe8467178d7c6664ed39066cf263519321d73930a63d4f85e4cc7481685a12cdc90b77d21b22e49091d2eb33cce3ecc974c66a0b0b2ec88ea628e076980aa17a99d0abf941a9c4e980ed588ecede7a33659df5f9268c0954fd82c8451679c88ef6eb7f4a8ffb49796146560750b0cf58e6fd00dc917474447af20039283cc37b6a4f85fcae3553cb110d10c052367099a20e59d25a7f6e0f0f373158c458ee9282302c549c4c48f0c261b3b1114c279bc6912dd5bf91ccd05710abe7b80750bcf9482062cef48532aa866200d5c62bf93497e97cb978036de1f3e76098ccae2368b6f872702ddd3a852f6cd13917479cb9bd1c6312cc09855a7ad5b16c0682489dc1ec8317f146c8bb52533e9b04cedf3427db2961f25e9a5b0607426e68f5acea2a9f20d7416d89c1eba5467a7141962d4d8b168b7756774729993f5f4ce1bcfc06711141dfa5bd44884562759a4ba1741b3dc216fb937d945c30bfdea11569398c095669ca7206ca8c1aef50580fdf6453c3d30c2de20afa05de9aa82086631d8d7edf225a342c6caafc59efe071e6f24ea027299633b6edf0204d5cd6b59d32da9c8095239ef698917db2d56b06e5f8f8e3994cea95de12c2abfe5783d72104a1c6c581fce3b89bf6bc419ca607c1938bcd2462310672c8dcacb0b8d2cb4183854589a20e32f6e81dcba5303ab663e924fdac9f9d8b9fad9736cf24893a401a75b33db2ca045c329b8a17afe8205ba61d6d27935c15274497b4485fa5a7d6c348b2303649c4e3df992942fa416f1b883e6e704331e1cfaf08796cf4b33c2895499041b365f52d9ee1299a90811aa06c2797eb74691e5fd1b38470c4da04e5dfbf153b2a84cab6f34033af85aa8485d1155e005096bc599586471913c9c894c16b83c8dedf8de6e7c9be350302edb6d7bd3302794cdcf415b0afd5db683089530a4b23b47292ac2bc8b4c1ffc48096aeb92462b6c4066cd6b31cc03213dfccf1936d072877687866aead5366e3bf33afb28d954e168c0f0fd9feb0c569f97baffc260d6a82a50177e6569ab96208023c0005773c3c391680f3ea4a46627541a3d4564a59ace01e4a4e56cb62a5c057f15b4608ec83b71b375c6df25ca3d8c975313a7a5ca6cc942aacbf1c4fc52677f7ad28fe9792b7e60d83a9dc4dc26afc70cf6aebf12b5357d014ce0ea09bb5d8f658389a68f35c34a577450ff1a11916e5896090dcf0c7c83136d5bd2ae45f572fa29f717b87a2cec448c8e7e937cd20f625c350c8cced19594e84212a81ab3f9fee28df481022922b278a277e84011b6d178a3ac145789a017fb6bc5878286d37dd9763ba8526b3c0a90cd99a9c37b965ab39b7df931ecd8cd40c40e5595b3afbbcaf2f4e05232cf1767185fe6e9abae7737581a06a360b7d5f2067ad6766c304b5744ca283f5034407cb93167ceb875b4355cc352dd9f02289dd8463ddc1e2e1f31ac4e065fa3eb9f570019fc29a0b5584133710cff01560b484b7c99bb7104ce2dfea25e01fd0a2a41a5c9728caa92c497cf52d5bd04b509518c8090348aac975d2f4674edf90bdd3f5d923e40ebb3848b11c93eca74105874b80169b79406f04d33fcd625ec4119912f8108f40f0936fbc9600d6a669a3094a35f1ade8296624df65d4c94168887bf1c3c80eca6c70e68162f567856f5be14e0ab8dd80a534030e475b20a00cf157a69314b71706e8f40e6e1ccc1162d5a243ad37214ec186a6552e11853af4277bc8aa4a87532ba47163b690425072dc211693fba20ee91fae2100c85e4cdbf042ebba8fb560cb1b2853b74ac7d17f2b16a2f57c0e33c10d244a7101db2eb346c84419dcf70f7bad2fd7a5c6f6aebb45953fdd40d86e537189b591e42dce0ecf67c37b2f66e218d26c7f1756c28e914cc652f8f38f4bc96bb04985ed55713086d15d3bc67313edf497be1863d6455d998c7ba6710123af616b194f910fac6559650777058d3d85fbb828bf537bc1defd59bf50d21242116995421235049686b68a173cde85475835082b0a39dc515fa935c67876c233901d6967449c166b7251074671f706e3039e1f58877dc2049a9a0ccbbb5cf1934b6b0b18e22aa570254978bd8877c2ee99e758d1fe5bad4e60c2232c71556b6507d401fd990191a7f99349034b90cd3cc58bc4537b41d5231e14330a993c734ec8848d6907a0bc2acb7dea06ee8cee593e984b07451e29ff45b4685c0c71e84471ecd1da4f1d4065cf9fb5e8a755e07e701267e2b2acf361831f3c04d836369fc7dc8d75acabccb83bf78687da52a6fb91da04e6a66853b3995120664d74f5eccb64e739b1339ee0d6b898b415cfdf41edd5966c71d2d2fa910f4369301d874475aa535112277f2df606125b8b932da903f4d92d818f31591b48ba8d1e90cca8ea989ee563262c63e799a1f3f85f03cb82566f6474990282f39634a7df688664482e6a18e05d751e56b4874d90208b9d2fc07672fdb16b1eb8640fdf679096312da8603dbc68f1d9f705cbe156f503da93d2606ee80cff3befce1831d6bb7ad20408dc7f2dd634fff562c660711d8ea945ad551f5d667f225724141425bff0b550cd925e36869c989b205a41421b7752bd2ea8ed286f33224e701d6bced64dc97e660ed89eea434676f8749bfd428f30ee7c4dfd2d9dfff48761452418c4135cfcc2bc1c071693236c4b6c974591e76f48cd71651a7d9e6d91a99afd38e2e804fd6501403161f01b785885b809146a5594de87ebef0eedf391a9ca80828910b77d08f26f47cda7911b0814be41116670401ccc9a4c920a990fa00610ba84affc18a06b0ca3b2121c8db48c00b841ed858d113afcbb460e7c218dc579bc6854e86610983436e26952241a4b20d9c7b90ee1dabf1c5702eb46fbfa1b0070f3830066d8e9f1899def0cd7a5063c5c3f5ac3b5713d11a1c4c5df1514cae85844dc781d0708352da70e61df9d0e5076e5a6ccd42112f0b91b4599214952db80accd5d46e1796e3851c9e9cf9510e1f0fa273ac037a8ef7439546a763369c9e539f1e8193157ba9653daa58f99376b37f485915a6da91651768e94e3cb9fe8cc7b6a395c133c230b18d5d5e03fdf4230b06a5a8c73e012792152df55d84930855a4f7dead408e2ee2880fcab4a8805082f1ad8e085f4b5290db413fe63f6ea3c6404adf76f1bf44478ee83118af2a93b5f2a0de313157ffdfad9ca22e3dbaaf932c573a570a8d807b13807fd750102e0538f3001a0e78c73b4cd7d051213a868700134cccbedf1a2f642270d15dc890e6c043eda2d013cfbfd5a962480bd7ca757fea13d19a8a3fc14aef6ffcb326d7616426a5c6406f8bd8a760bc12509fa508a3592cbc82c729823d2f1cf0451c34026fe937e396ec41eeb93b2a656353d5492116acf5f29fd09c09f6edd9cccd15e731b990e611c323c6421226f6f1d3c4f2b234d217821646b02b8455b052048d65fa43201d7503f7905932696bb748798e6546ba9833e1a9441dc17b25a1acbdd9199f7ea0a80a9ea101124d47a0552ead5dfb30a6822245133f13ea992b04a34bd877c4dc5f2ae7a1ad26349dafc21bb37b5b9a6e273ede1eb7cb2b3901956f8aa25f289889c4e837f334d3c892535756baf9775ce67479f0d0114612e2910d2be874acb8ad30dfc4fce3c0f5093e7cf1815cff422452c16c2cc302d35ed0c3a90df9a39e3dd5dd42f3c7ebbf5bcc369b2a9da6c145f18b10128af116773cda9e4af067e2f5302c21c5daabf4b89bb02fcd2e5fd680198ca14acf5ed677ede8fbf224af0c26958fc93e90243aee7b8f678f029259bd89a6023d1be5c7aa4fe9a91030ba4aa78eac12ae36be61255145add8390dc901fa478ad9876e489900a7a2e6150927c32bc3161a8e7ea455b9e2d7279898d0c7b18349fe400ae7c481608f80d7c7c9d7f5341e41f16d1830f453dc07d951ca85ba4197f70e893bccaaa31c75a72c7bf5b0241c39910399c93ca6f1e8dcc95c41b5050ed7a5c89f2429315c181c672698e3b269aa894bd7f862107c76f0706593f2c403c53a6b22ce88caee9ae628d9a8f3efe59a6defeb93ca8cf40cb12a8586b8ece2fb625fa0d97c8ad742383c074f4d93c5dd489b27481f521f5b2fe7011588a71a1f0d43c9f128ca37396d31e65eeff3c612a5b210a1fc6bac607f56fe053ce5397647618ea8598c22ce4533f9b36ade39f520e0ce48c6fae61365873755303a3310d9292cd747e72609518f9b014161784c0502ffd9d198c1966c3fc95bc8443806b026cf2a6fd5001f6c7247dcdd6f46294ebe370717b4283802a01300e57f071dba14cf2bab2cbd55fc57798463ab50d0b411be5c675f02187e735ec8d759fb9cbf05e3a47d7e028ac70edb2c26c0b3b3e11742b23b4675e4a59c35c1fbbea3f9d10b8c4a92a06a071c6bc244e4ba2c246dba5a9d7bc54a2300df6c9b1b7ad188ad190140d86411b861812887000cebdcd995ccb93863371d3d8fafc77509c77335c5f91ee36da919c0e6e0ec564edc275cc5c63ec525cdc06a286c67a8f5993c8fc4feb87f3aeec61b4aaad5e6cf21ff1607b40bf0895e192c0e2e3fdffb5159b53ee2fbf64c0b2427f9fc2d468d289a78f4b52bb35eb98f385d9834a6331c8ea11fc37cdb9d6bb55701d0d52fb48d87e7d7bba0ffd17ddbcae4c8cdd7e3dc399030eba771d5136aa4d63aacf0df8978fc955b778252894e3e6c8c0214f89d4d64c8e5ed77603df7d0ac8608bd8cd7e0e9eecb51390c00a03eeda91417a187f916bb403fd91472f912c53d99c36dc217cec8fa487f7e758da52cf76266d4914bb3b098ce47b415b45a9c972607bb9286442a2de5b800db31c5985728dafa867c68e13f0d46881fb2c8f4776f369fc29b59d7e2b9a402b8ec63264ef6bab1798464814b377fd41ae85a4ad92ce7287eb57f2b9e5ff60b0dd2be159ce653e2f2359ad9c0ff0a606ca37da3ea43e8f5ae9c5347a385ff3379539a4abd6e4ad417eb18f73dd7c2be40170d3b92688280a28e3545f65c97440bebc4e7fb1e79fb2bb9ca666a62ce464e75552bd6b2273c7af7f4a8a1db6df2509fa555d48dc60eb3c332834ad23e62911bdacca0da95910db378c7f0231b6742c488d9cd986667f6b424cca40f646c778e7c0fdb3190609f0d6d2eb4c1d816f1bb244daeda4a109315b40d3bb41d297739e0c4abd41c518b8a6d8697a22b7d51be1b820bfe085e48eb71ac8fecb0f97cccce09bc4553c178568d1e08b8db653d35fd81ab3ad51854c8447e62c79f6a254ed65b61c9b677a37f674c40542a7a6347bd876db7e862c579789be482f2f63cfbc25cf7ade74351cac7eb49d6672556c4defa01fee9bc5abfb27956298c5fdec016ad62f9669de7650791af753320e7e4c2cbae887422c57826409263a7303977def46a0f93c766f8bba5bae9b78bfc44bcb331f4ce2c244b106c54667418bdb651d636ff6d4097e1dd4b9da01e9356ce4f9e8f5efbdd017b80a44ae7481be1482776d5e354e20e6b87034e85ceb2b60a4c036601e6b76f25170ed5cebd184d99d8f3b52016333ea5ec9ce2b11c984ade37ae1290ea48c105f64499fe5ced928a10ee54096ac29c9a46138b31fd7ebfb616cf9919e29d7958b635299817e2a6ba0ac4de2f68c358d01ebe2b00cf836c4925fa5b88bbac5e8521affcf2c8b0c4753c93fb23081e43aa162075db6e97ac327367b0967f30426efd6e11ccff6c9f10652489362a9261ab97603c52201d0c5ac75bfc7efeaf34a8044d22eae8efa46952baa6095acd3aa3ed8e93a82dcc2ad9ca16c68bc78d97fa7850607ddcf41b4ffe13a9361df48beb0cddd380457699ae1f30097167343378c01f739bb56547643671ea9e76058396e83b14970fb2df267a8dbad6cae5a5c4552c6276ca84ee93a221adc1de879014e2d5cf8d3e5d4c8859feff2967696ae0efcdb570fb2f2fea3460b3adc335d2ac666ab75bbace0570dc3aa0faec0de808df6b355ddc9e8b6a7e282dd09d47390e4deb7c3c5f6424c069567ade23e2f73335a3b4919704d14c0354a13e968f8c7c62e0dc23802fd3a018e66397d222b7ed9640899095ca33db4bd5f77b01ea123b78a2d2cd0839a2529e20faa40547f30ebd35d136bb470119914fcb9f2d67df668c4474cd290839379caa49a135556b1044fd92e5b190fdf870ed019e817bba3df8f442154fc0dc6ef6eca0c2a537a418703f68ae2ed9bf945ebe6228a4b2fb7cb4de379bcb0019e7e00c8f47fd83614f71ac3964f96dc505d549ce5099ecf519f394876012859a922d641cfb874b80cca867c51dc4a993ce3a41ec6eb77c4be3628f8b95a0d4850d2ead8ff37b2c8f65c4fd518d9db0050e56048021bbaf8841f0d1553a514114e39be9e635de258f2ab3d1cb4f4b03785f0be9bd3bb35a924a8b6a813c087a938faecf8d421e1a2eaa30dca1e1de99ea6fcef7eb7134dbbbffb43472f2391f35741cd16e2dd7bbef51989e2c827a997c763339cf6f7b68ccd5653c5fd2c01841752a81c856ad4f1d16a97877cd5bc22d9b92250bc741b255d71b6c802a6bb697a4cc303f274ff0136e613d72d20f0da7609a05e448315e15443eb95459d46d348a40a526d3b579d8e03beff7e4dbe07d729a69aa4736119d6f38f45cc64e487e2840a1e7ed1cdc26caa44d1822a80933d0f2586e92cc540444799fb2fff9c42b1b460dbde0c812569f4f9dd001f513a47fb2d4934e914283f37dd3ec40ac45f6c3c81700eb990296245e0a75d647824d46a4c747cb63a8a0d167a7edf292c44a90481a08a49cab2c7fefd413e7a95cf49798b23a2367b7a23f47945eb562fe373c6b3117500c6db2c557a16dbcf0e24f8ad2d5a75c005e14c2e8d420fd682c2867571d7142a7cd460c1339dbe6acef70f55fc70689c8b0b5d235c7d9619f3f8c98f871960786c2ecfc79b02fdb7016dc578fc7076681fc7dbdd54f3391e563af31515bd4097606460678dfe38bde0aee6fc74b7ce15a0d0cc6b1326d935b00279af62ccdec1c45cc1fb5f4cfdfef8e94354e391c47a00e160dc5fffe1eacdf728437a1c1f9837fb6abf1572b653464f1e7d13484c36bcd4131b5f46eff4d7d9ffebcb0ae4f95ca07de8d448649150273309ee4841293b3028bd7a41388bfe7a8b6e3750771f8977fb8a4a525799505ea70a40a8d04fc77a65d1a8b687dff1ae1e718273436fe07c01611437cc0da3a9d78ca631a2ea61e10261b2c328a714ebc2a6344449509c4bd30cdcad5b35c5ce431fffff438dea481bb623b6362758a25ead121d3f0189bbb2c0873c249a7e9d4790e8b67a7d02b4654cc495a6bf4e82e05d9aa40411b4b222d89a4ddd91d03c8259fbdb30700c7fccf71f8ee0a84b87c96b6130349a230b56cda052a118dcd25c97560111fb1a1923aae332307e29170f3e3f0f6f708758237caa52cf887ab6d868990e8efff3b193e58e32631a68927b44acfb5ef69e8f3f54a274b1b50a213bb911e32998e39fae27c6d8a21ed160eedc7996f000c182d3f9860764512c5cdac8158bc04f365fc83b3e8aad9ea5b29ffeed3a6426fd32014198cfc593a8fceb45f35d4522b1a40c35d1797d583ab683453b696169f51b7cc66010ec636141d3a079e5ba1e45d4dd927396262ad604c91226f1703f4fffcb5bbb6f9dd102cbfba053159c1d697d529cd3b135fb0c45b9bfa9d7a0d21f2a999c02111de9126921401ea2433c857810c587a6e6045eb3c585048c0d1017ac1ab316e73ab14c0fae2a90b8d0885371b25d2b4a4363780b73ac28f7303096c1a7a0b447695a49acd43916c41720016ba7c28b722b1b60b3801049c9d95fa2abb11961d532dc8afd1bdda644e45c08741e4729052200b2bb830f66fe0d2b5ac4ec7cbb1e74f06ec89e8a2d2790bb46051c66477bae3dfb3e78b486a26ee6bc120ab39bf162bb0cefc18b22b388308af39ead97a9c26224934d0805d5f0e4c89502076a5cc2b0cfa586823223dc2465f8fa946104fd35012432cf5a954253ee24d33d0711048d520d4d6049e1a2ef952ea5a45e892ae556561592fbc037569b56d9161bcef7855df6c4b61df9df42189b7337e8559b03bd0057a0271ba6cba36a93338d3a74df074b56c919415540cdf3e14ca306ec593b374ffdd54ec5c7b43081ff93ebf877df74d8c93951013b32a31036e3a2b2ca3ab313248ebeea7c63d03bddc7ac1b004026961da722a6ddae8f1385c6b0b070d2a728c6fc378cede984b2dc75521dad85f6e4f5e8ffeb854ab2ff2b185bae7fc034cf039c3be08c8e4a82eac1e776471daac51d3017147252512810a1c643f71a5fb170c7ab15ddcdcd7effa49e9fb51be624da65385ea8829016d97f2e32b833ca639f7b65a4913c85f51bc099e605006102d52c9a3318e997dd8c0d703d51f0dd0ac5204ffdf0af1cd506690552be501dc67d4f93b2b04c5a7b41852944773eb0dd368cfdc5348ac25807ce2ff6c369be85fbc80c34cefacd046055e8024b04b866d8c13512f0a32927d4ee1418715ee16fa271afebe484ae13cbc54b08c194a7f59672f097a54073edc26ad506df819494a3e2b8412bb553b430aee57ec5af7af3898b936054867a3b8858592b22edcd015f8c6e82789b3de3b43476aeb18a271006e55aa7bf9fade88ab41038d8d78501fdf474e9eeb6d8d4bfa7efe7c8378a33031b1911674935976e5975935b4894da051e38b239395f69d161dd13d9a2f20151f1a74c369243093e527b348cf6844a3d70bc7a7b5d4e4a1fed3fe05afc417bd1f7a69b955a087508e06495cc39e0052f90fd0e7ce08d1ad17cf47875f12accbe1c5437d32d914e4f5a00dfe4037c966b697387820e658392ab4fef9a4f16a7ce96c26c8a2653fa6c0c6dda5e9a9737cb01be70e99f1b04fd8501eec86a30165049082f9c7c0d2471f47af1b0f993543bdc3819bae2efe30b02e62cb4e808ca022696c85f3531d5bd869fc2d29e77415bc623026aaff0a590435b186a557ea26cf2325c4b78f381f8b3d9efcf900fb59a7d1a27f2461130ab30a651a3a80a3b75fe03ed2ccaed5ad089ad9b30a4fa8347e5aba26de02d86f6d78615e97079d8ee54b64ecd23f5d1dc899b3788a8ccdff2ba77600806c231051c16c0d8a4bdde4da2ff34ce6581887600665aae4a275b2d6a73b72f5fe71ef7a3c8479ee0964df412bc1d9cf1c51153371acad1a66cd75bfa0da9b787a10df89453e350a0bb6a5db94cc040e5ee878ee05c2e79620d0a7308472ecef9d695403c8a6ad6e7475aa1e1c3575ab6c2a058b080f3408831c5b7a748c2a6d38e82c2fa8119ebfd09722fcee42451d27a7989d84673e0ad119387425206fb536a1b40aa854a5f8ce70b453fdac63b49a855586b646720e29f7999bc65de20da89a7c4e33f0aa0c8d35bfbc96bdab180e55d8ee1445c0395f6dc3282244573acbb29b06abf19d13a01485aa07fc1d90b3e6256e75c91d77fe950f207dfc7841ffb261df8e8aa35ee38cc642cbdb1c6f4ca18a5085a81192fa4fddc857d2d24ecae4e8107392d8cef006900f67eda7200a0c01a1cee45ea0cc93d81b53e5159dcb87e7576daa90569297c73d4a75132871611c399adbed987383e9f45712f8f0b026d8241c0c810546fa81397449b3e930bf2c604d16fdab584b4a01062ab3b7e7d80d0d69dd6dc07c9255650666083d57aa8b99ae2be43641f6ec6d0371e6a65c6bae641ef43e228e6bc010d171cbae9a951237b17b75e2851777cf8ce40a18c0abc114dde6733b9ed4e15eaa6a7fa65f5872f97909986c887cbd7b8b21df66b5b76b5c11a9d79d572127d9f77b87c589be1234d00932d91e05f36a87f5f6b105001b83a2d3f9f2ca6697a4798aa0bffcdad22f553c2b71ed186a249fd77df788b51bd1da5bce6591110fa5ad953dd24596c7a111b044d7150d27755f0935145e239113e7c71304600004d519da8",
+ "spend_index": [
+ 0,
+ 1,
+ 2308355850,
+ 4294967295
+ ],
+ "result": [
+ "241962a137765351217d9ef8c911be846612adf3f60c4e6abe9e516f9368efa4",
+ "902f0a031bc46def0bb073cf755834f92bd3cc883e79a3081d5f1499058d2945",
+ "fc9b00664a458bcc4e9d3c915f076f6fda75e00bf928bcacf7f1970d8f236068",
+ "914a0b3690fd8c9e420babebd7f72782bcadd114292b323871e9c909039a046f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 2,
+ "Witness": true,
+ "Version": 512812821,
+ "scriptSigs": false
+ },
+ "hex_tx": "15e7901e0001024a0793a800000000000000000000000000000000000000000000000000000000e46dfcf20003395607149b029e0000000000000000000000000000000000000000000000000000000070a5d5fa00352252f8023ad76c595589ba51c8def3f6fa9b8e0fc3116656d3059d39b7bd8de921d39fa1fd4bb67d447eb67325b5790855dfcdba5d4bc505ff9e793422a619d4561c30313625fb687f6e66ae2d8cd9f79f9232a660db6e4235973e74a0c71d6762709f55255a9771abecdf909a0bbec7ac4dce3e30116e2b0597f56a2749237ae4be0c7264d1d7e2519e799d4147e1056cc9ff602bb174e576dfa07922a33bcce25ad81528004776abe7601891a8133cbc67513b74d4ee4ca8f2a8b8f474ea5a081d62f40b29a385884633e500455b2fa0a445b3afeb390ac9ccbd0b6fc869ad7a66189972db43728f269ee1f60c08fcb15dcc77c95595598f09c187d53586a2342e1c2296988a4ecc0e7bc9899de252a960a8e0f0f6d0cd3e4dd64d63fc80a7dcd2c218786496b42f5cb9b06cc42f0dc9fe99656b83e0e1851446d481864e3d5ad0c4f9a506e58be09ef02c5152c80497d7656b5b878ea523d58dbdbbf526001279d339cd868b1386560c9b3caf22f09037d6e3005c0e0f89850b11e71253e6d69b5a9f8157bf5c6ebe32ddbb7f3592c2fc4dc2cec13670faac1516f1f61f9b83f97fa634b701fd2901af28d0d6af102ccb678e7091497ff5df19db99f80545e839597da96f2d45d0044c09fe069bc9d6b3187a4b566fd7adb1194d7a1a38dcd310e1abbed51a0393bfc4cbd2f2f50fef07b684bd6724d974c9ef13622b8c92a37c78c4c73c991f041daed55c6b579779233937cbf07c8c71af8e467079a91cc8eebdeba802ced5c3f07d8c5bd49a1ed9b7060032e2b8344d8d11b1ef57702bf61a3a0a90c0051c55e1002531ad86cbbfa73dd029fb0a378c452e5979059400b5a254e73585c46073ba570cddab3c945186183b69993cdad1efe8c8c5b6e0f5495ac446185a669afa53466c3cec852703ee14530d493104aa2cd46d28347789a64321bda4869d77f42a72b213c9d8bc478f41f7b826f98180b5d3d0bf5a0138961adbee8de726a18652b90693afa5e70e330e015f4715c2700eec9759586d17bfe29115ed0b4f1d985b55fc70433ce410ddddbbe851f7b9ab0a700c881eddd74fd9b535debf7044ab164876ac2b0752da7f798c6b5a906b814ea3a87354b1bca9d57e864caf4cb4e05a957e09b825ae1456a9e9607b49e6",
+ "spend_index": [
+ 0,
+ 1,
+ 2378452061,
+ 4294967295
+ ],
+ "result": [
+ "f3e2c3e73cee226c724bcfeafe2e180f662a29f7b2e546aad385f4464aa90075",
+ "4baea604d850efc9d770ef491e5c32b0eeb260c1f869c91c3f9ea955db773cde",
+ "eab6991e813e0da4acd7ee0b43034b85111c9525fde3d76e8f5a88c45c443fae",
+ "f775ddaa1ff9358095533c708e1fb1d4b59a62c4a4408f8da20a8c1e35474f3f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": -34418595,
+ "scriptSigs": true
+ },
+ "hex_tx": "5dd0f2fd000105dea0b0b400000000000000000000000000000000000000000000000000000000d7b8be27aa0467d1c01b3e20179df275af2b2be933d594b3f1ee3012b531f19fba4b8206c2c4831f55cbc3056ded051abdb0951bb3bf86434780a6641286ed94c0fe40b0bfe008644bdf90526e0acfd68ea6dba7157712a29e9333aac123338f5c0e42d8c7e35bc1023a2c38374b251de13d77da8c6084ef2baaf0e41fcc000a2e2c2eb4ad7f0643b5905d0dbc8244cb35939068eca8fa3032e3589e88303f65bf21fe992673b1ae1df292b397bf0db1eacfa09d65cc0000000000000000000000000000000000000000000000000000000000631b7567fd75011fb4b9126b828c61a96b5fb508b52800529ecfbae4d802020d68194fa39bfa732e996d430004f87c18ac56575f6bb65f50cec46a7c545719d4c52aa4e7bc9ae5c97b1abe8d8f4934d846b5ba81f8a1ddf643bca6f695f8eafbdd1f844fe03ce4ac8aafdba6433895f7af87f297c1e75892f48e44bfbbe69874379ed157ea5e4ac63a21b6f5d054a44273f3ebbe4d8ffc69883cf7cbb70d3cc91a60660e6dbef32068b3ef11c09824d4b6502da46f3c0e26d48a6df4c94209729691dbd3a42fccba99755f076301cd3855cd2f5944fa43536c56935a4681a6437a6ae7816752986e280b215fbd37a020c1f1486cc217b89a60d71f9b92c79e7a254711f70190dde6465b2d9b7b513988af7d982afb5ecfac13eaf75a7207121e4445b7453347761d44d5d8f351519a0a36c9b3a54f8ea8df077c3e1c49ce6d382e45f8b7fb99832cc531727d6e22ea4c47cdbba7b4621e00bb7095d23417fb0a26f9126ff5d15dd1c9ac15f00bd92739d86f9e2585abe9d2b9f6b45ae79f4a27b323dc1b000000000000000000000000000000000000000000000000000000002bc0d170fd5001bf3b7ae454bd083802e76cff30780326bdc6315708705027731894c62789c6ed32e6b63a2ee135e0da4790f3dd6e314c1f422db3d62c34a40c3c92b8e9434782e01f6550bd48e63de7f410bfe49264e8dabebd9022a9870b99f1c9409724388896e14de887a475a1fd2e6f8f44a9df2b5383a3b771d5ecc8a912f2f6ac8991fbf70ee0a3e9730d93bb65ac9eba4ede14f10aaf5334fb3a8bebf5d749168d2b3505aa629a32f09085ae05662e3be6b40ca9692b6c298febd38185e3fa40ac227a2687687f99324f5af277f5b8b6aced53036fd6db237ff1940360c2a6a6390f30c230d0071124ecf0021058b3743c3ce19bee9479dbb3b93af8573a05d6f470798c967b741c77215d1804b45c85961b3da943a6716c0f2d26e92998d848a94e04c77896d39e38ddf4192e0205683d1a15b20361302099c36e04325073459e9e10741dba07b5b8a1d441e667cbc4a8cbff1eb456f1ba401bd000000000000000000000000000000000000000000000000000000000118e4304fd0001a0492948a31ca464437f8b51dd653e5a8d27b3a3cae80ce3a237b0b08664120a8d0054f7284c27e2e09ee5f29f2098d83a1974e07867446f436446c99381a2f8b671e2836c64ab761dc907f4fd6a6031cd9e8deed2103ef187e94a3e52e6fe8584dd0a1fabfe13d164d2969172029336bb9117cba93fb531d0a6149ede0a1c230c389e71b1a0e3d4210d57abb36dd43245c8938a413d6849dfbfcb23518aea00eccf19bc491043684094ba550ca3571ac254d951ee7fc9189bbf64c4e05389326110de944837cb6016682aa23becc69e523418600f2fe4df6f1a84c5dd836032aa8e18b15f2603aac0f243a4768a8a53901dd9027985a6b14077f036712b13b1a61f44fb31eca4d0000000000000000000000000000000000000000000000000000000003b2e502c00ff64cd4c04673bb7df80bf5560c8d0b6f3d54862ae8092b5897be0c7cbbe4cbf1ce9fc0748f41108429cd61f8758bd1ddf191f967200d5c381e6a4acb3cf174dda433be118f9c5a4cde60970b7645a2b1cbe9db9b25980c5f80583d79f3a13bcb05adf6fc22dbc5e005cf57190b75230146f43e78653c41d0206abb9119c1c4f54943e161204cf71088176778286d9827a438f322c86581c3a6db004e1b5bcedfe48fd1a8da4442284a44c5cfb436b624c008e95633c4d36220f0959f31c037cd2ec3e70c70e1dc82779ccd2cfcff99fc40cb26451aac681606667757255c8ee0950071f736d4957b49d3e03b3ab6a65e136cf117bbb081d7678a4465e66a5c3fcdbcad3fe98d32d21c68c97400190ba19320e0f8154bb9a9d98b577973cb2b97f83a26f4f86ff82634c544d9854da78508a158ef6937a7a1bb80081365e7e18005c786a84bc69028aaef5cbc0f7b0a3af1aaef8c296e1e246f4e46c15780f51fe90d85e02db41ecd99e4c4b17950998f9d498552f006409c67d475627adda71ee723e1b9bc7d31a08c609ac8199cd2797d0f71134fec05c4518cbedeca0438fbb4374c57580218a0f50daa487bc2dc80bb9c1eb6c80bce8a9cef47409d6e3452b06c34901b1bc4f804abb3b4f0be46ea6514649696dbbbc481f949e688c81ae5317f70d3fe56166784b124714a1c4dc07a1202478c9ebadfee8a00e8e0891a954ee20d284838b5b8c3b26759a752704912bda1815748492dd7f706448cc744a89206fedacf7ef1b447a89a62f2cc944694d2e11513cceea6c66f973c320a6deeeeb85322113f45cba56eedd5acd67596d2e68c26ccb3073b896ce0f51b068b061b29bc9bdd1af51e967de89654884060b5c79ea98464ea137dbdf33a8223e7cc89dcb64ec22aea7e3ba608cdf4a0384351ae4da6b53dc1a6f8b1a1e15b27c8badb706540299c41a6bdd45a568519bc794d169a4008123da165c0eb7b40cf8bf96b1a3f9c025d73da7711b450ea122f480895a66552be9bd8832dd6f4e90676f5ff8da0735b2fd2a04954422c93fe2f25654b353951be53ee09378e1c0c9e157a126b727da271ed2fe66c5f00ab2c073494e0856eb6d2467fb4dfadaf1cea808a0fb6305ae498d1f935482acb505e369f81a6d0832fdfdef02a18df3b753668ec450835e7a90c7c45b03e293eb0f3fee544af59b1e641e588de3c7f44c03a15ed347d45dfc9045ebaa72859eb6a2195db9d6c8784941df9086ab7744571552dcd4bd1a401ba0db2a89d69ca1c0338597fc7fb4723f6e001729f65306a7a96214a4cb3a78c4071221d8fe75d6544d63bfb34c6f6555399f5be39945ddaf7898537f79b73b51b2e6378de128223a99ebe3784606150134f8c1d2c06c274ffde7a3e0dd53088160a7868332d628e319577699738a9303d71c552603b78478400daa3399d7024ce23a910857da0da88d0b43ed425b8adb81f478ebca71c9c1aad7483a2605df1f38a61bf627f66b81e914f02d66fe31df7fa86e7e5f0871214c4fbfe12e60b9eeb9651a84403ee77b326df29ecfe15af0cf8ea6b4efa286373d95c5dd33d7f9dc5dab83382a10545e4309af493ec64b2493db4ad7fd38d6e7e4a47a15cc775bf3bc473bd23730809aa8f6b2432537b19d60379e64baef1975e763b41c2e8e2b1bc333e07380703410ec08c907af0913e1e1f6dfb3ff95d1ccab1e00d0f97cf04532faeb62b8aad7df53fe0d03bc21d9718f1c0e57203b789f49182c50199b6a4919683c4e6974b7e0c09cf3112f483991a5622653b2852de7546e81078b54c104065443c33a76c09e95c1dc1617b97249020cfd2e01a02a27775cd019c4d21eebccf3738d066749a4cb2b6fc08347f7758d9e3a9c7ae3a6e12b963cf83b1fd672c129719211c3fc7a8f2ba62f1adc20cf4b18c53423f002d5f59cd3bd723eb49a2372aaa32a9cf8f12220c8ccd090dd85f9813862306e5a21e47392832fb6cd969ccabcd940e8891500e8f576c235bfba2df8f7b7b089a77e9eaba55f0ef696f7db6d5cde3be41a7a9c72053db92f57b29eaa77724b2525b6255c833e668fee16af35a57cc0da04070d63f2ce39bef0d42311628ab1f43ee4aca178783246182890d4c4215aa34ba506f6c941ea938b956da76a66536baeda46a86de0150b6b7862df3e3e214b00af8f1354ac5c8eb6a21c3e7619203219e698ba3e728764a1736e242a84f93062039732f3625b557fc97ebca48cc21c721de585cf5f998967e421567b04fd9a01614adde856ae46ca685ba073ce97551a4ed879c3982bb8a0c4c4c19758cc2164831a346639d34906771e573954500700c925b2f6a51298d79e789d6480d798fb7c853652937ce105d5c3a49d26934839955210780e919ef4774f96cee6980d407b0fd44b3f13b9ee4f5bd6db93de9587db2c15f0273d95a10d7840295cf4141d08f018fa727a75134929ae41fced1955f654d1bbc29469e3618bfeaf2e1745fe3925e3e1271e3940d67c96f03b21befbc20d1714dddf0c2ab5626645da21bdc47befe70ea38b4f804a9fcfa42be3120ab1ee9c94b2dbd40b651115d5f3357db7ac3cddb0b6397a6e4c86af2118674b0a284f29a95e7d2a51be7f51518550e6ba6a24634a69ff7892c00e0b605df08087c6404ff450b54158d4400989db051cb2f581e5166554cbf9480f9c26701ab4ede8339fba5eac8d41ebabdafe80bcf4aa9a4b474706a6ff39c994bf02286c6b4c1d22ea790aaaee2e5117ae58b34065c3cefe32a8d8c35fc44a52ee602bbaa28f681d04de9a824186080b078596fb0c8e1eabb7c01cf5f8ac9281c4c2a9bf5242f72cafda2c807788c702fdf301d976807e557699b6504139779edeac170108ea49bdd01365da1f0dd02ad17bad83ad390a598af18a5742eec870192009541cc4c740ce87f434c853fed03530ffa2c0fe254091469cad1ad0d3bf64485ba651f8f3395d75394a6b6e3d18a7b349869c68296154dbfb63adcf5a78d4e5ba7fe5fd04b7f3e8df84dbcd1ebe242d93e95a91a628410f42a1da12890ca5724e9d02a290ef2b4a132173f7961eba3653889e9a77c231291c34504a2b41f4eba0dcd7be74c8cf01101bf8edbf1d35a3cbbb964ec39b6c450b662aa056310397518737d28bd7b8f2ea919bfb1191df5bd7b7debda7789b51fb106fe52ef13a1199021407615d04c6e5ec748f930d24abe34e056cbbfe3d0644923cb114325207a72db54fd1da854d13330b58994ec176f0a22295893976258cf18b267ab3f0901783ccef446a50d8b1d579e5a9a2230d774c859bca4beca090a8a80f633833f82545acf797756e171337b9dfc938a4ebe6555bf3eacd84c3735e9b5b1fbaf4ed99d2d689ec0215ea5d9789a25d1a3d59473f9a3abd1aaf652bb5439c98331383cc0fe88ad63ac15d38ba5de539dddff619490ea1835503dd292a3f5d6439de6920c9f5b2e6cfcfa29beddd6f2725dd51e0f454ece859f783db160effcea252e14f6c5c05653e5b5425cd66643afef1df2bce5da42d1a2a68bb57fa1f9e11cbb2a8a89a96a4b6f22a0f93b417e0f211a77343a385378534923a783820d6f0df5513e0d3d25631fa3a827d3b2386a861f03d6589991c5104360511b5fa70ff8ed3af7621eb33a0e164d26a91c4833b2671c09db0da7c6485ba895601fed6b5a12379db12a4b85380fe047ab5bbae82c1c95810fd2bcc0669846b173824ac5df7b032f4fdff539939f9be2bb4be31c61dde7fabd7527178eee36cde414eb21b1df81ce8df8012388b7a08fd7101655a6d4bb9beb590b9055a7a39ac3980d19e8d0508f17fafc121ddc590971577988389f980b6794514f6d376276ecc41de2d1d22550596f044e1e094f32b5928bc045072b62547c5715ec3f5d3de18ef8a28232b98653e3a170154e90307b0f672cc23c678c4346cf270c4c31f1be14980b013a8fabb17570b18dddef48d28ddbaea98ff2421bef9ad0ef3b0b63265a65dfef5ee7bdce736fa61306ce38c969071983d5a7c0a7930e1c0776a52bae2caa03939e322ecef0fcf10e2edd26c92178fcbcac25db90bb33ac0f9ded141c753e46ef02876d50548cc3bcd03dae3ef6e5139df0e95b38c2ebe69751ff2b87e098903cd9921348bf7db8408b7a4e3989f3714a1bb4d88dba4dcf868813db4fb367f3c89bcd7131fc857b2fe7b745dce2b334a27e85d329aa0ba0ec710f6786e1341b7cecfcb0feaef3f974edc80f45bd08a8c1c23a6dc28f59390696f4baeeff9b4fb11ada633dcfd7fd2d00e7f2a8b09eaa2695b66e91e9e015be81cbaddcd5fae04fdea01957892707e0dd5b1dcec761df13fc5689d4a3a1c88c4a532aee371f11373257bc0e5340e0eec96e3c9ea5838da777edbccf467f043bec8d5206511511bfb9894a2fd731dfd5865b0db1f44577000da3a138eae24b5f9f8cbd0f68b88c22f8163ac44ff4bf60358d91cb985b90342316b372696a993cfe91d7cda2f3d1e86c9dec095ca4c2d85e5ff3fbeffb0ab82f0412980175a46b5a7acf773868762d61a614991cefd7d066aeba33d5e2f980912b3fb7d6a609757beeb5a6c2b8690a21449796103d21d20722312e75aaaa02d0b78f2a61147f853c28a7eccab5908c0578d0837d4f72720eb67d0fa9b26fd614ce56f69f574aa5c21d63de4d18384c0812c94b4d4d31d4f7262166bb8b602e400d4ce7d97505f44b0cc387c913e76cfd07c4d301a5f9a9c8491f3094e72e96cb682b914f767a83994f329e45b101a3a09446d8d6eccadb46d2bbadc5520cb0b8daba7c147ca18b65183da689dad812d1e3a19b853129de72d0937f95163ecfc32d5d0dfe99d9b9b5a70883c80db0a15caeb7990d58942391b4e516410e4436eae55b7b21c982c61413e5c14f3fb674fcc78c5997f0d84f962d597784d4d5727dd67031a80b6cc6535a9179040a0b4cec004a82bb0301589f22f158cbcd696eee7620679a5dee4c7b1fb19f94088d563bae0cf3c91cc8ce4cd7cd3ba654220a8125a46d72481a80298792386c1358973672a8fa065ac8a9db4c12a11d50995f69cfe5d09c4b7b1aab94d176c6f1fc6fa4c8d7213dd9c480ec3c485939d0cb623aa615849e2b5098fe561a4dfdf72dcfedfd93b2eb83f597242a707b52543c74f24c5fde9012aefece7564f60f70653e47a8afb3dfeb5e59d917b10be274ab0679da1d0efb01bca06e7467d59b759b9097deb74d92a3fda1e344855f09cd781c34ae1678201e45128d3f61c4cbcfa7a6b0b73961e65c8d7d7d6135d7eab3d9887d153a1866a62fe31063ccae983615d585853825d9b699325f167f150afe9f180182efb7fefd203beb9912812f787b73732791128f2b989e6a0a97d8b16c0caac0deeec65aa3c67efada1e3ea75a72baf5433e8e306e1c21d6c88556d23e4439d25aae69355aec9c990bf4b3d6763dfec018fa206b82ef2a42acc7cdab33da1977053dc6461901b8f4c6751f949e9a5bd38ad97ec95a2907c879226b0d7259dd9a215c092633a85d97034efde15a55c671b3439831a0a364601fc636d81c0c8cc8472fe916d47138577e373d2407527ff4b969cc24505da541a17adf94c1c87d21a6f3e96192fa1148561297c8d7046a88608b15549c0049512622983fbff9c605fd61d0ac016b124315e6303963ad5068283ece43573a27a31b5a76e227230801cb9c1d313d1c512e6d9c8422b367708818e6de2606540c3427921eaa51a15035e5b2c0d468bfbbdb11ebafeffd5f9f71e6cf78d4b24f6c82d8cbd83d81a145e666c4eda94a6fe8250cb7e76fff2669282ae0fe912fe6288eac3edd39af98ce67503d5cd159fc6cba2d1e5b8a698fd4b01ff61b99a491a17f05299167c6feb67f18c2832fe3265719cbc746e4ee8e81a7b41926bf00bf2cd53c50b55f332e19f957af790c83cdddbf46679e9b0c5ee2b3edc15ee209954e968bdf1d89ffb00332552de9a0c9ba40bebdeb96dad7d259dd833d76db01cad7644d661063bd8acc07135a829b91193fe9cf57e19d5694d89a976ed58dd81e5468dc44172ce77ca5383984f63a2e01cfb03069909510b604fea16df0f85e9ae6fb5253fa26bf95d8c362e3f5a8a63f89b89a4f343c08a49a626177c330af5e6dd57efde3b8a48b79a510df3f884fa74f5b0c567ac044ee3549c204f7cbda420d326eb408d3463a0beaf65a43c7c463cd6a5410632e0b00b483fc24f005e9abdb38e2292f08bcf55679e9e2e249aff0829c85bdb15386ffc98bcf62872f8da83d5a998de9d0d5c415b8f628ced24f3c6d4b35f4e01de471eb6ed449900de544dad8450b6930001fdf301f19627e2e6ba4611cd1160cd88212ade6eb28e59ddb0006797e189c7dc0ec2a532fe25f9b94fc5a7499cee0c17df82e13b5feca55e7d2906b21f72f10bbb38d846cbd3e546a7c0e8deda3ab0cb7e66c4c4ca17c2c94bac37b0df07adf949709a84c053eb30e67a2fe40a68e7195431dd7b05f78442652d219dc6e24aa3812e25829b5243b4cef9ca45d17d125f2ac2ccf9d1a48f65e1e116bb0f3bc94687d7b7722edd8db62fe28def0eb98918bdb4adda6954f62bd0ad3171f775f34a083a987c2e155633b6b5e1c2aad0c7983cba44879f024ea1c9518fd0a87182cf6bf2cbc2998f9d44446a0c20b640cab5027e70cf3a2824f217c9bdf5646b62286ffbf3bc97862a997fd105682085b7e6dc5a9059a060449e323719fe2961513ffbe08cf7dc043fbd1d1379839d7af98114b2c8d4841f00091a3aea14198e12d2eb551c049138e8a90f9298e22f4fcfc205460adf412228814288e47e54ecb30bd4bb82ec50d04dded7755888343fad7e0e105711ea1be72cf304f592fc4d5269dfeb4599d10a5ad38413cd9e522b5cd2fc139a59dddad0a95bbb6e41ad759aeafd9301e06e551bca8eb12985cb65a7df8a279ca6571a7e3598fe4823c7fcba8fe50e42f4f9723e678cc9ac04fd6086939b1b438c188bb3e9e716e6b66b3b1b1196aad184ea9dc926b26d5b654cb6363c5d8123cf5991546fe711",
+ "spend_index": [
+ 0,
+ 1,
+ 1543102608,
+ 4294967295
+ ],
+ "result": [
+ "5b2b6e29a48f11326cad1fc011abeee3774099b11784271eaccc608924846a64",
+ "b9ae761287f0265fa9c7ec44ad48613bfaa37d60ab947f7221319b40359bf38c",
+ "6b37a42dfdd073178aaf1edff909c6fd6480841fa506127c46bd89b5f45d2d00",
+ "32b1edbd1a8238185d53ff008f0cba145afd7ee4361191ee9dbe4a72ec5cb56d"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": 93911642,
+ "scriptSigs": false
+ },
+ "hex_tx": "5afa9805000105e269c23f00000000000000000000000000000000000000000000000000000000ccb851b3003ea045578f9bb2ab0000000000000000000000000000000000000000000000000000000036af826a005f3048a22f7bea790000000000000000000000000000000000000000000000000000000062d6b1bc00100e8501cad609ab000000000000000000000000000000000000000000000000000000001bbfd9b90074538b74935bf13e00000000000000000000000000000000000000000000000000000000e49985d400b3f878a004504771dfe41d9601c86ae4ccb7cfb7170446c8d7bc7142c0a69726e6f4f9f06c296bf0046dabe419538b539ca518332da907925bcc504a40c2bde6d685bed6013f46eb7419a4ba2528e4160396ada59aba43dac62ff7aa7be8cbd88451fdd2bd461bdf48d220065db522399cd7e0e9d74a60a2fb2df85ea8669f5642f00c9d916689aff0cafe0839209a5d9921f332178a31bc13ba7d25f35b36f1754bf35809a1a724e21f34e2d630ae8d3331b59963e18ff39208aae9d1e03908dc28e10e29c0f7199701d9adf990955ee722429611a408dc6ba1e46f2a14c80eb28e7d1b6dac273d9b34d6223c39e27fa92dd0b8cb032f9dab9081aaf84be41e51f43ebef13312c5765fce0b2aa69da06fb557c2ef30cc1b0325c73c91aaaa9137e46f5b70a857aadc94569480bb08a2ae7a1edbad52e5c2ab4a78d6904481dd661864e8d4b0a95cf41aaa52d952ac6bcdab61883a4ff31d31166ed91716ea0589982f0393c3ec484d9ccc714feac5038ac6a19bd38f0239bffa61b73074ee8ad53576ba9411e2cbac7c5bee4e7e02d9fffc8123e2446627888949f09df9ccc831ba1892f2cd2db67412f14920cb61c86aee7a7441dc81daba76e6f0ee845f044c349184a4f8a2fd88d4f8654c35ae3795f03e581653ee61a0a02b9e7148b48a39faa2c9f7330f77d56c4fa36974aa5d8e1be5c3868dfbdaae17ebb6b3cde463c2af6ace5dc7018b5d131bfeb359477e0a5b6b31200568ca848ebec938bb931aabc8ee98c926c9b5e444c1ef84e3eb9786479f0144c46c7b155007256e0702ce07f1d74fe6c9aec817d34ce162ab03bbed13e03c8368ee6b25b42a295412d94c1b6dfdce8a4afb0c56f1126a3c9cab1d94e7a7916aac0a896813e3d2edf41245c8ac7cf83beee8a6c7abf3a179a62ab5f8fd89a05653052d0e3ee3e1b71dddefc8ec41b4bff07038943d5c0d9fef44a56d2ad7878c9d48a05e61d5ce5d619fd2a267e8a21d5bc88ca910c19c272ff5468835fcf10d866191a95095c9a14985903fd9e761a8a18fccfecaa0fe9182b0abc84ab4b355d22b47e49333f4d8ce8021eecc07cf84b27bfd0255c1c68b76d646de5a9c7da90d17386532e7a592d62713386154b5333a7ea6ff3ca08cebd203d125a0d42471eed75babd4e194f763bf19fdc5df9373eb00480a033521035e94c36c0a13a0d3a2316ea4261fb4bf3a34dc2f2139fdce8822b088943f4f8130b16a1f727ce9a2c179a877770b315e9ab587fdd501fa396128de67602e34d9a1334abfa3aae0e3eec17e123a98f26bb0b7e24823166459ce44b1f654ba4e7c45c0cb60aa4bdff01adf81a3d56b04988fc48760d676ddd3899d4f56827562252f939951f658b05c9cad596af9f17d75d58a2d5f1a34c60402757566353bfb45c6bb31582d07f411b6ec725a6ed47fda76be854ffe12a604ef251b5697d545f4a3fae379e2dda1a9e296d7204bddaf801b6069eeacb02d744b1406342821c164dd8b1edce60111160a08a85ace46d8bf6c5759473b3503b029b9eb0349cf56ccec33355729915f39b17a62f75781f586aa18b1036ca53c34804a3fa2ae5de9ad699fb9507381f7d0aa78a4cfd637394a7e6d6da6ef5bf03e1a7fd4ac1eb848e563d50b03fec50e82db44729a4e0564140552623f84dbc64e59f70fa37cbfb0f1430ecd2a3a730edfad8c3aaa11d97256e48c845de4a696f4be2d8ad0d513588defc78145e5394e20e78aaffe1443c2b7778a281fee4ea351aa6cb304149c7c776849e46bc0937388fa22e6d09e03f69d4e9441c67acd816557da4b61029c132b4b90a38e714ba0111c0c6296f7c8ca1a93cdf62e15ccc7d8a572aa5ce40a5e1c4f927ee4cb1096bff11d031a01c37ce0129c9a53eed44b6bf2d509142e512d429701b2fe83838a149359e8fd9301f3c6766880deda87f1997feb38d28c3c097077b5e5eb9743e6e36b9a04cba38c5095665ca77c3785cc4b682c62006b8c192d696a6961423770a79446669d9b87dbc6f3fb299369e7d3886283fad9a338126dad2826e1a3db01ab27d0dc6554111618f94970583acb30de6a37c38c34dd19c86d4f42a0947f01989be98e8d5d3fc533367d394076f02155803ca7bb8b654ec7badba872b747a043a3ee2391dd1d0147a56130bef21366048570022ff120441dd753392a10d4fa83cff9501346bdc815b4ee57ed8c08f04195857727763db23fe9a4e2212c3358143122691a98fe48e7744edcfe24a3183b4bd1fa3f20fcf880ebc9c942013d741078e29195f063777542ccaeb9737bb4a5ca1f6c7fe137b20dda3c292b4332140ce4892ff2c8c2060c932e7ec1864a4e1709201ec364055cae57ad9f47b69667c564998e89378cc2dc09369e9a9221a4975314b5a79e9709aadeb39af5344081659a73a03176c72ea9e42cfb60e16c904e474ceb5aa92959f2d5b75950217c9df9045aabddc2a1b0b0d21cba4d3d372805cf7a5e1a939a98f77101fdce01bad33e99f5b7beeef3c4833bc10ea933feb47782bd340b3cf6d3c21bf590415bc51530b7e132d661d9d7dcd6af66612d9b4157cc9023149a2fb948cfcd0ec74a5ca914f5dafa335984ca628f17bb46855ccdccdd058c611e9b6d926c6063f326a00bafe8cecfad1fdd2d42bb125e6c4e6bae218dcff59d33db4dd97c73e7e2179487fc04ff5c84886c645056495e64957aee87202c23c5e8228466291294dc6fd231b71c667bb83209b054e7eec4fd1091cf27698d7c45f7c4b5f57f6eb5378b4f85e051dcd800a71b69d0901b59efcef0036615bc1d2041cad428c4210c1108d2d616c94b3a34c950952e40a8cf6543c4b083cab9186e921317530d13efd18fcbef67448103bfb76674338d72269bff3977b5a65dc5f65455db12ceca39ec4019da9726e959fee6fd8a6ae79c76fe0583e54ba349b378e37436a0f66ffd09760caf056ef37e5fc4c1d86f64cb964cffea5c58b6bd2c019d4bdf7ac0658877e6f8cdbc2a48650b9857fbf1bed33f77ee9b8b3d7af95425db12b7f9ff35181a4425958313722c1a75a86feef228ee2649abbdc3e643179b212d14c381fcb29883e179e8e41826e06af3faa9fb13aa6b647f9ef16ccb6a734a536fcee05b881bfe35113291922f2e87f3ba6e4b76a0023aad951851d10807c12089223cf326736357ba6b28dbaee80b1a45d1b50a149c2627d37da01cc740ace6f287cd114b4720a7acadfb64c3fdc50645fdd1018db5d8b39f86de6e35d42fca912d865eaad758e6dcfa45ec03578424aaa39e998fe11ae3f2684be3fc2cc0d6dc4753f3e3661bae67f3fcd6b1812716f207edd2803c5a9ab742e062dafa9d31704175873cc24e2a1c6248f3b62e5b234a11a0de984d64c47557d866b006bac7793fbcd62d8fc6f0a007a70bf8ec9c82228906a9e42ef23634454ef7c0171cdbef163a98c6a748d669db1c3097c703a4119ac4a38c2279f1406a134660967ddf88be127f7c0f8f777914d12967c9e1ebd0597efcf415652cf19a04b889dcbb4551d47b225a36c082654de9f7687a5ddb8ec614c0ec204c4f58c9c969a2195b97eb97f2b4376dce0d0d3ab0d7ea5f82324ca45fb82b488a2920dbc408589150acf31f5cf7afa6ae6c9691e828ea391670582ce68e05bd2043be3b1774710188c7ec657c799f6e4c782ef995c23cdded2cc438679e580133d438cabde6a7f00462a7cfc8600f516d39910c616e495d1c93794c6c1bba2594f325c1c3d8e94ede812cd6add68cd84846dd2e6ab8c2274a882789fbf578eccc830057d51bc900c3efb36f3bdc9b0840290c4ab1f3661e734410a56183a5a96813ae98324ee5febeb8a071209bf87c78188e753dabf641ebd692154656f9ad51d6c4f7755f673f17725768e967dc01fdae012ec92ec285a8d6e7e81bc5e6c1fe449eaa227926d57ae47ebe8ca4f27751ec5311069c2e66ea19f1b5d98bc35f35cd4e259a85ca38bf578d3620e04361bc8e44e1c5b5d6c8c5c786adf6727cd8fac29d8077feb49b402e846796cda828b06cf91e19e9f4bbf4b0365f0ba055f96ad4add4363bd290dc759fbf7c8889294d5580816a7baa01aa7e7c2d6ad71a7c8776d0c906c4dc06dbeed18f133e20c22505676446db35764cf518814dc0cdb9fa2756e44f9e25598a3792882c7281da949315b1f651e9f615867b6c516c5942a4e147ba2e0c06a21dd9fff4d1e224c8750b75544234d6d189b0c7f5fa270d0e7f35c8b736f430e0d5293898f9bb5d388fbd1cc1fef5fbe5c276b113ab8b436ebcf4ae9c6832119504ce5cd8d5b504bca91c10ec512cfe0c9b0b5da04fe9ce7a9fae1609023cfb571143bf95dff1becc292ce2d895ac19df295806c466b96944bc602be9574bf29b13e5e65d2852a1a61e75b80baf53ddeb95cdc8668ad9a28e7a2896e28e5d0231f1c7bcb1ca11bb2e0d091766ee47a0a7352cfaf4303ba2503bdb4a4e8fdcf608d38d6b29571aa8dddb7f02cede4272e29fd8f9cea210d968c503fd32015a7d38417c57ce3b1d4fdfc328ac96b67af3381e526d38e6c502b045cebea35272bda912cef033ebb8642f93de209de673feda40822d4f24edc8b79bbb29e68b989e3b0b27021039126abc5e6cf8451fa8b367fb290f4eb2917fdc27f2cd931db0f19e963bfb17303b9bed8e91164700614afc164a02e8bc3ef5583929fd9995dee226f28445eeb189b0c25ee6f8c23e52549fb7f3fb3662d89955158ce25eb6d650f58ca5b66e851d9bae53a8b3cc6f5c8bc40fe177774bbf4d0da3b17ee74f616756de54cd9c7481916e8279b9b68ed50a6083bc08ec5b4abf994839997b233e989c7d594bdb4ce15b19f4323d8b0fa750bc1711cfe2e4acedd1939a0c5e8a4ecae95fcd791b7f2a74503898a67f4b27da167d83d09c41aeb0a68404166714858899a8bc35d72e7c6ee98a6928f3a585ee8ca67b3c937b020cd49fe029ebda9e21bc57b4a29258bfb611ee44b1b217387e5d3adbb4a8c86fe1ad935e9277e762f0dd74e90f6357152e28ac243e5d2f43afa52e923ff5a9966fdbe2d4092e803644f90864206bfecb96c99fd7cbb16e6a0aa84be2a33660b869ffd470fc21764f9d8f38f26eb348eafff5ce13685b98380d1423dee4b5809ab8693d9a3dfcd70b4cc42fdf37e4abca5db00ad3cf61418a656b09e4a0c8c3fea0dd41091834f22430033f4cf1379c7ace6966eeb165e0347a9cd3aed5810d532fdd736eee8b4f4c87cee2e87530cf708262c6ad4225669dee6ce02968fb7f03c860f0f0ed946c605360bbc4e65a7cab2c134bc15bfd65d1023fa7e1f27cbd32a7147787e770bf5282a68b111c10631e1abf4381fc1211731a4c6b6bf54b3fefe4792f17e6a7d3438fa7dff58dbafaade9c34b2ac5c10c536a2f4b438eb9ee1d801433949cfb44d12ff8ed14264448b814cfd89b2cb0a39336e1558276243fea9fc3",
+ "spend_index": [
+ 0,
+ 1,
+ 2559694887,
+ 4294967295
+ ],
+ "result": [
+ "96fb3611b3f78e908f7d83ad1b1c1bb715a7df79eac25c4cd26bf6b3d86ac5cf",
+ "6ff033d5539ae2d14bfd8fea0e0fb6a7e93cd08986b6e1e280b41355fe17e447",
+ "e9f5a3b36f423710c6a5129175c3833f12833f58465514a72e1248e085ae2537",
+ "e256c842b390333db3bce1ffaf711d4da880566e07d174797c25ab5a4224784f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 1,
+ "Outputs": 6,
+ "Witness": true,
+ "Version": -2006323668,
+ "scriptSigs": true
+ },
+ "hex_tx": "2cee6988000101e90702690000000000000000000000000000000000000000000000000000000088d88eb3fd430138ed6055729b96a415fc37d0c94dbb2dabd050a388700764d5d5018466a45455ac5bc5173ccc9300ba1b4ec66e713b27dd9eb7055465dced488ab83dfc762a9871338e0eb2ebc2cef93de3626e52ad88db0774afb632e51b71bdab859dbc740887e1a9d3fdce12cb18854505db1bf7f4ee153f21acfa6c305c421893374908263fb3e7c6f5297b36b8a7684d2ac49196d32e9dd484eafb6f45d02ed13d5d30b2c48b03c0658ea25af364447dbf7c2c76f28f650f220d2f859d2279416d2661434b75b834b5bd09829ce8748dd6b7233f30d5cb064fdc420fe48217669ef48160586a19ecc3ad97d6e9de4f5f80c9aec4b60d10fcfbb08778f69a978c3768a5c3771b82960c733cbcf6b09eee9e793a5c9eea0c57cff7157e0232c26719a9045697fd9f25d81f9b31d803fcc9857e57ad9e55cca9f71204ba39d651a796a8737e7711eb0bef9fc90657c472509a7d4531c81328efeae5f22623e3aada3a7b6eec583b25f88c219f51168c59b1836824155ab2c159b3c97237a9ae12351db57fb562dd838ad79fe49ffccc55aa2031398a903dad86b0feaaf3f412e7031ca99b29a1d9bae48be733f54259eb121ab374c79e4fcc7c39bdacaf8104b555edaa420dc28b4fe802e10f364e62232f0150b209b5d2482a8971bd4e422440f77658e77535e77a8d0f51a6303e5650115bf02afbe0e620aa148b00e37db3514763a854eb2bacc8379572a0b9aaa8f77d1ac80be0e192fbc9310bbb3c852b01f593fed5fc1dc8ed44137e8d50f34fc88f4de5026fc9ad62c7ad7b92460fa74eba35071f3e93173df1d66ada44dedfdef4bbda06b746b7169b2682e5e556f9781a87c5d878b9ac6b79009f10d6af63f85c3c6e88d2b96408751ca1d5de40f5de149c362528b6deff838052dc627189ff5a9626f795e2f7c0b99927fa1c714e7150390ca2bdf64998812576e822e02865855558d004da9e17c35daa41f998054fc529097d591dafc255bd1328f0557fd3b53dd7fb35a728f47a24cde169bba46f35fa4c162aa8b7799d5a1f857516efdf7ef5db967f263ac897089877f0f96d5846026feaacad0022ffb69d5225c66d6181e336cbee778d5f20cc161092d6c28594096bd1acece57916f6abd1941befaf44835f0e63d59ec1d9321158885738c7f0eca5a969f7ed43d593207627b6b9ce623a57b68a4fc2fb27d8291232b9ae3afb98f8f94a4d5b721632ce4dd762a9402cf8a911c46f73ed804717c4bc31b99e7c48f1d6c4b3c08fa8e54ac68676b110df189fe931e0b05943ab0edfdf3dbf2a4e649a8e3f76bad327e22eef49403719fe07ec40f5c95abaff404fc3db21baf2c7455e7bfc369e26c87ae646dbb033b2b1fa657aa3cb8352b3bf46835f44a03529e92439e3d5069141f44dd98bea9cc8234d64f0ad0b321d4c4960fc269d1dcb9135d7ebb2205f5e33ee33b6b2bb201410b3e38992a00a4f9ce5e06d065769779ec2bd47558bf9b7689fac920d0ff1b1824c1edda6d3b28ef8ae00c42f1a67531d713eab9a1bc44412c8a3cd9c521a44060133ae80b863243621bcc7217dcefcc28267c4d0698823bb61a0fec8f468a87266b57677129117da7c5e662a8140c142dc45aae2683094a033fb8c140990a28aaaf03d7a47f93410c82b2d036c2b272df21215a172010b819362ed6b220292d8d8ebf707571a022e2704350dd68eabc833a7b666c99709874a3312843321d632f047f8d411873a3019205cd749824ab6cefa0cdb5cdd537e978cec566d3e1539ac2cb35799b2c4f29b127f3d4e58deb5942353731b3c730dc86ad91b074bb27cfcccc3f5da1c78ca28dfd15e83410e23f5aa08ad4976bd478328e61534fbe3eca40c73d484e2317c596ac5e6d503314ef76a7d1845035c84683f557e59e8ec80167caadf608d7aa21e0c2434fce3f525f69253760c66536e05c8ea5153002c90a8eec3872fa5f9369881d3fd0d212fb0e3d18ce3fa726cdaafa261db618faa8aa8478a3c3f8070fe033778641bf86240df7062263142151b7dc4c662954775d83d673129dc54d4b229f4b9ea84c32b6d4b296d461126625b8639641da1da91e66f9ff08ce6d1f8980325d67ca57088e96b57a9859954a9afb39f4b6354c4ccb96ab2f72d2a744c9dba822cc3595cad1bfb685683a76adea64a472f37f1a7a998570aecebf629b60197571b6224343f60eee90e27220e08eff57172d0870e4ac72a6a03fd2b01dbb959a12d229e8fcc06a9b36214bacd96a0e06bdb208533a23dc4b90f2c7f92c0e5adc6c8901ec64d6639905c6aa38544f0b1371702f490678b6ad225a977ee7f6059fc6049c5780c99fde6837d4468f242da97a5a1f780d28f39d05e72249f6a8ced5a3ef41ad22780e1785c8988465c0e0b65bde6a873008b112f98fec76f5219845360ee6cd41c1e01458bf073513c6d09dcb7ea09d52fe2773f1dd7ed12bbf00e76bf6c96f68266d2d98181c55da440c1dd2af58fc5ce9ad78a2aed3dfb055da9ac4a8893b232b334e8963800059ae80a18bb082d69b4a50228281d36c9a22ea2488e9467de7d53eedc659e4715ea994433e4e1e858cb567211132bdf6dec0983cc5b24e41e09932333bf393ed818932e7093679804aac34a2c8e97d4bd445671c58c2c786c862e09fdc601703aa3eeefc83e891d93b698d865cb00b2e82ad852780b2ab1c0203aca2cb158c4701a0c9c29015efabe1d06ff17f52fb193c93cadeb1d1ec01a229c61aad2904338844ee7b469a2187adea212c4b4fd277ebaafa572d490bea72d2b0f27cff9075fded06c6750e3c030d5614d37d9b2b8b48811779ec1e281cbc7905c26ce112ed38d4090fa48979df1ff4d3adb5c38019127ae6e5366ead7d2fbac722f08546f82582d56a9f79407962031446250efe088bef4538e43d5586a3e92f4239d8a425e2d476c9e67f9d949517ba6eb0f603bbc78f4b36eda40a68015b7f206aabf0e05a6be5c3d63cbe07d08a89fad2edf17372aa4fc5dede966bed7947f481d6655a273e9e22d145bfbb21f7177bff75a7a5748440b1b7d848c06eaa584806c3ff5c999563924c4c5cf2512f320d4a918915139ee87cb2f77289dba349a1a3194ffbad6ba06947e0d6afbd8c419a9621653809853365c3a8ae25a7483b13a593f801d689245918fead3ab6668c4a6fbc3a2b9c0e6983c0d25700ab09384d04c58f645678f05aa2ec4ff4b153d9cc20e06e44d14706633528ca00a878aebc7ae7daddf529447b383c0ad84c925ecbaeacda6e374dffb3b20edf4e93f885741948453b78f0a32cdcfc7b01117d111be926b368cad8186ae2c3061ca912fe930615b28aac118c70bc3e611aaedde8ac79de5df508d45d9faa0b16e7c6207555cf0edf12e1b26076343003e8377d90ba1f08c1c4c35e114c0307ccb7b75d13c4bc79dbe644eb500e1e7490bbe0a2767c3fc537f184852ece9189b61cdc65f14d0cd90c9d02f4d5a7abef11de334295c6321a4d6cb8d61f8c7e5716e5725d53e1588a2bc36d33ab76d4c10afede9177bc08be113fd45e489b4ab47953aa7e8866cdb4000f3e3e640dca4aa8f7a977b647baa8d08848e1d14f8bec90526",
+ "spend_index": [
+ 0,
+ 1,
+ 3336449762,
+ 4294967295
+ ],
+ "result": [
+ "35b7d911fc9f0b8597b8b0d671719a4dfd381320bd593d5d8db01af2d4e5681e",
+ "f283f9f2988a5ae806dc1a41450b96939fa6e9c953fb6e7398945abb8c3ad93a",
+ "f8bfb30a4d452ff4950e0d9bcfbd5f767e1c035b58105647a6b7ce7e79a0b092",
+ "03e42937a554a7413e4d69a1c9853d185ba04541fc2cb0d14f47d51e694cefbb"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 8,
+ "Witness": true,
+ "Version": 927470719,
+ "scriptSigs": false
+ },
+ "hex_tx": "7f1448370001058533c2c300000000000000000000000000000000000000000000000000000000cce1c49d000090f653125d362700000000000000000000000000000000000000000000000000000000a074705f0011270d74f05bb42c000000000000000000000000000000000000000000000000000000001c7d646400a560da53d34cae8f0000000000000000000000000000000000000000000000000000000007add3e500a6a2e2c6830165e1000000000000000000000000000000000000000000000000000000009f76a13e00272a2e5b087418670bde018a03c84ae2138e6bebb37de8e931ec0b26447cd365cfa52fda169fb098488d761b3c84e6fe2b0a1f2cb7b87ad7e7ee98c5c90e7cd22aa53d0aec01eedacd85ee7a40c56dc76b302075eb52f5a165010ac54e9ce47e64741ccfd6adab3706b71abd4400a863b6f34f23ac10e3e0ac3ab3a063e9ff98e1cbd59a5ac7b35a7bfa3bff1a4fe56421cd655d75a09c567d09d072a1a4a60211ea931ea1b6e99a56ca238131ce6d662c41c678e1f2ab2d21b017ab9ca65056a392ab60919a5dc5c2c5add0ff4b0985690bf53b92aac4a62b10f4b3de1bc8f9995db1f08935c9663bf3b2c27cf50ec9dc7876e1d53f8a33f01c714cbce776ec7aaaa692885854534e8041e923f0789449d7ae7d1e526619c4472e5796babea68819e6199418c57b3ff8b2168c55c4752f86e0cc35b44d9fbbbb851b769f7a1df5f25968fb9f1c293e28b6501bf6688dc6d9724a75c16f699297f3cc92d762cc9eb4dedd0c846afd1aeeed92c31eb03270d796df29d5cd480787b71038099345e71d8e8dc702732c5c6b06cecb48f170f8003f4d8857334d4f35ace0be136172fa465952ee318b230f3f39f1f2207ac889100e86c9e553a938162e02790ba30d4ef79a77b25a6aa35c3eb55a9f6dbd1c96e78bf4bddd0b450b9890efa7440a6d279ce2aa3d2c504b5811391b3157cc30c1a1f889621d9df320a2e3a145feaf15207c92410fdb82fca580e0833379e330e1b883e01757ccb99b89db7af2e8a783e20327a2b83c73ce13e5e209bedee8deef0fd64125f3aedb486e1f7f75d156fad00dd73f88880ff72f383bf208f569c84982914fc3c7afd69ce611a3e13be66601eabed2690b2ed2bf3a1715517a33b2d55d55ded6aa283438a8b956fb471020c88ac547992874716043d1deb19bb61c618f7cd13439e0bca823d82da3566cd0192c36cd509dd5235f4d612524a6238776b8936e80bbb1664657a00a1f0ed2a5175615d00ec2515467bbcbd0fd32f7db1760acd45e55634054d7229924a19a198285030d3090d41f33b11b99e684823275313c3e86af60b567bcddf7e60af4f0fb8a8c83aa1d4611b032fcaa5a8a902bec0cef342eeb67887f575e2334022843435bd27a4f26a808ff7b6382605aa64abfede133f96268878592f26a7d0bfb9b2dd7cec681d03257d96ff08d3d2812c459c8e6d4ebca99080c3b44b73666589606cd70ece1ac29c921f4acdb0aeb6ac827d3d1d72cc675d63a3db5ade28b405f9eee7e43692f825e77b018c30ab2c42fbf303cfbcc717301cf10f474e02fa9e71f68f1b1a6b600724dde7bd02090f6f70900470c0f5c18dfe9b5ef91561c946449f9f0eb4f2d3fdfbb4dba6d56a0ccc7fb77fd26797b7ff958cda25a2fa435ca25678ec0c97512fb5a171212ad545c00dd63a9e134a23f168981bd3a6e744d1ac6ca36d5ddf401b27601fef6bd524dce6164a375380fcf67cf5302c27f412c35554ac854fe2eb1617669c5d379220cfdc36fa7e77985aca7a9baddccefcff50e2953527dad07a7aef5ec37518762f21361971f35d06934b4a6cfa965eb9daa32bf7a02d3cbe71da5b02f4ecd1e002b708d4accd13bc5ddd27a84d792159464259d6775714f34cbf09ab20458c95505865acdde8fc6aa6ef30dae6b60cbcb0a07d2a7e0b13cf035062f590b1f35bdb5ef9a552d07e1c5b3dd757deabe23b44158ad1ed72b860fee4f25d71938efd0b0ecf89542b6d50d656c6e918b8a6746c3501ffb725a08ef51d0eca4c563eadf395da17342c832e3adfcb3a3c272625a2fd7ad37b75e194b9d068e41f5e90e89be73e1fa1d47237ca78ba1072e7781ea45836626d08221ad3d14959b4eb4bd5829b9515b5540b2de3181c83f15924faa547b75c86a079c592ff1cc73e12c46271df825a340455a74fc4319df941f7e342e9501e87f9c52d71719353787c0888b451ebfea884e7b9f7e1e08336220e8ee987c09ae264bc727bbeedeb88fc9da6b10b36ab191a3e559fafd351f3405016c098f4429ee97c1734d347b547ca90821938551a870b7f4315a31b7e1c64d15c787daf61a452ac87bce0cee9daf0fc3ba011ff3319e57417ec77756bd178f9dbdcd9179333e4e3a49918918f1859ab4aa6100322ebaa879cee92ac17559547c9ece339ba495a2e54a392674a0f01e596df37b92ad5319ac6268fa4e34be837aabf20c5aee8eb7faa9daca9ccbf498c9ca9f10df74937e0c87c87c20d73385da74ebf6b5873ff01e420984dcca17a688a021bc5d4f4a82e43e80bc215a9ebe502f03f9aa92698b848426876fadb90491e4d22354c42be6873f5a3099b840726f59f2262ba1275e50821f871c411e7850016324ea2332a0f611ca730f8389f0912bd647445a182e9a18065575727d2150d6e83b80c683824921cef65022b057429adfe0484e2e3c7ce8e4779671877f9ea1999295e1f9a8a01598a4485f369023ab24dda1e175310f6ce707b976bec4fa7e2ffc876a03fddc0152d77caecea97bbd0bdc11c92955051f1295684fd8f0e1443d55eabe1cdd098ee45fbf672d4b19285da0bd404eec4d6b88bd4ba5b88709ddad97d1868a517b7ade6e5ef74343e5d4f2fd4e49c3f16126543f96ed93c1bed35b8d73da03e8641110c36d46954cf5827dda61c54c7382d7cde2597f4d589477cfdde573fb3c94e3a83dd500851484cf0ac41e7d267ffc58b5f842b644ea36bb60ae97f13e6db7f1c4bae4548d86373e1bb61609da84b9e8562046959f23365fc98f663e646f1b6df6a17a5e0643324aeedd6c96829881196784d99b67f194039f76aaa0cc082fe83c5c425d9daecfb5ae2044f44b958babd9adda321fd329f2d0dc85c1a8045d03c1fbbb4a59c8f892d9965eaba3e2b26e521371b13d027bb89290346d6de1f4dc098b82f99740f2c688dee5fddd02818ecb850ce85bbed1c74a7147989143aeb0e78faaf3426510b0f57be10767fd9a7e764856255f897bcb2b02583b06de695907336f6018b9bf48b912b2354b359563895dbe6b292f2efe5d96d8c7494d57bb41971df50c0e4c3492be67539236d9bfd261783718b961ed7af3c1bb66b92e882687d90916fdaa989ecfce4df21d419b6025ac3d7a0b8df5e986d5245e09165d4c042e0ed373bf2c2de094b6a98ebb64a31affa752f226066b76d3a1818af06411d78a0e8f6712cbf41e77fd0d491332cbcfe03ac2a42875a2afb3f3602de6cf540d11f9117c5040508c77c2e8de0645750eb713f9c2daa86f70367950c2beb38d08dc8c62e4775258741fae09728590997e7e7254cabf3bcce7b53eacc8687a68e83fb64b4f60c6031d4558a41fbe0685a011360ae175ef58123ea07a6bfd6801330a7b938bbc46e900c34c0c6283bf727aa4c5a7b6ebc956a2a73a34600ed7ffc492d822e3e6799c1d218840c8749647a7a3e32beb0de784d44f97ea4bc89d30fb6aa60c202bdb52dd103e0c92106e731b7a32cb927b31bcd658eba282514223db9e132e71b42655b1f13a58c9cee6fcdfe3cb74ca8b20866a2dbe86712ab0fe2f5d83b368c734709fcd071aa109d500f465e30d31275ff725d66d61d6389de4288b7f16b9596a80c8a0070ad17aaeb2585cf30868e98480021e02f9ab582b04f775c289b228eaa0797a4aaacec3607b9de993d5e5428649883d8dadf36c570d531dcede705106fd78f8f73fae85e96ee23df325101bf5b5f5362f8287029f56102366575e8ae261d3c5bdb4010d69f2f554438851fbcf53bd4e3d5e5b410f36bac7d4a9a8fbfc7599e85e5461835e0788b6eb082604107a385290828e56fa4538e21c42e8b2d2d461ec4c15f1d34b8e76feccbab6e7832e24304dd0691f363019c70649e84a7afa02fd00018a6afa7ad8bc2deda6d7a77a392ae19e63663ca2866a5ff3d5d26df8092d1909c5c546d29a0cb2977c49fcffdcec848fcb064b0fec10012506d87227274328f0fb1357ee9645ab7610464f2ebde2f70de3695f80999fb005326f581b839e29c17b30bb24025881bec2763283fb5cf247ad5e2ca72a25b4aa16a7106221cf224f2519ceae0cf8c617a49c36ff0ecc2b847a05cd8f7cbf2f10e1b41774d7151b5d18a25b6f626a6495eab19cd432b4ea9ac757a586c3f3a68cf756d5eef3ceb5d92834c9e7ac0d43d20a6af1eec12b095e3fccd960203a06318c4f8261c576247dc24dc742e3a2e839d88f02addb1660133de1ccd693473919b0a1efe680ad1ef4fd89017e43180811b13f0690e4da19472e0aa0bbd502c0b5c17063d8f4d49434c261704baebc47c8f0415ec33c5f44a0eb189e864a5b72f31f1b9189f4e2ca6a0fb5f02e7aeca67c32076bc312e5c6c38e55ae959746540a4da5958b459638e6008376c4f02c48a6585e942508110c7d7f085c953a25d25d15190fd396185b06e8d6593363815a68a33971f9f6c80f0d5ce251def60037c16d49ac0b1e106a48be2f320fd29b7f78349aa64a7e3d922661543fd4ba4e3e2acd70e8a04a22e2676713dcf60795af6bbe0b62343d5806ca4e7bfd00dad24636cbb16b7e3eb9d08bb38d67d18719b5dbc19486d4a0de9b36748c472914e223402b8f31c647bdd02a840d471af6d3e021726fa7028d6caa14d164797cb9a30fefea445c35cebde590a337228e5fdd1bdd6c720b21b9539e64d0a9a0cb9d5c9274c2d549d48f9df1c471fee0de8852a0cbe1cb7ece1dc5dbab18c80f1bb8e5d57c1c381fcb6459caa475849652787bdcf81b745751423a1caef82a5066ef7732f39de3725aab74d2cb5891518e0514a0bc76058b8e02fd8d01ad79f66e18d236c9c1beaad88887a2d25d2b7127e907c5444ce7e4c16e852c08c5025c9c37897f0804ef9687f6e15efc12d191a6fd6ef49d2fac14552261668c959d37a1680264e19a9b301b88fa4e5757afe371149d592f97005ab7b5e1c5acec9faebab1f93d27d9dd5868c76fd004a5ba01c2db2735791411d029f86131e77f11b2df1998396676c5f0fd71327a681929095f84d9d7751b45d12298a84799c77ceb3c20ee3bd5fff4c31c81d6888565880518fad5561a799b2fd52774624c9c5a370bcd495c9cd8a589d4d83cdc77f5e807882c5d9a869f5bef7bbd778a9606f4670f9e21d587d3d4e106a1035c562ba276f2828160d92a095b932245545c15c9ba57bc5e3139b700a83d3d8f4edaf4aa80bc4aa1583169ba1833a716838ab855b146c05cb96773d1d23a26a86859aa3adeb213af7b95117530729c756b052d7b485f8d8cfd9d524e3353cec87a3d617d3f75f52b81525c1347c492710456fc19f437b89ce4837d29f44fba6df0ca58efa9f8cdea2a8cae2484ecfd7d099519a0279d21b55f4f5086dad7bb6ef3771ffe062186f2b9ea918706928d020a75da0948623fc34eeff53e2371e9495b2e25713960dd0b7328682c0f74282b700ec8af7985b10fe49014a70c6e715180fde1d533676b68bde54acf0eaffbfac407dac2d5431c1c10608ef4cabbeb83390a136776e041cc509bccce8eee0025c80156",
+ "spend_index": [
+ 0,
+ 1,
+ 2627771845,
+ 4294967295
+ ],
+ "result": [
+ "d7b1add885c3702cec9a2b0b84eefd49a406fe71ab6945d4de040f27e09bf6e0",
+ "eb8e5adfb2d19bbb1a6d37356313d462d192e088510459099bbfa85d604733b7",
+ "270111c35d939a116777e92815053d91a95027ca6a0971d7d0ef5b6f534666cf",
+ "d9431013d0ab2f6f324386e5532e812d599b582ac7716191d1d5e589ce688210"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 3,
+ "Outputs": 6,
+ "Witness": true,
+ "Version": -1061043830,
+ "scriptSigs": true
+ },
+ "hex_tx": "8ac1c1c0000103448bcf3000000000000000000000000000000000000000000000000000000000c0ef03f8d5d292809d1df6f8069d0392f54a00171e068db96ae04cb26a4782a005f5313a171539b47fa54553d56bcdf1f29f642c7e299c871f46da2ccdc11ab0c48fd89d3fc7dbb647312408f733e01af1812c95617b107eeea28450549d27b1c6815fce518d1ee46d7380dd9467262581740df0ff8997e8293bbfe51631635210f246f3b9756986a0f2427f7a735a7cbf47a71f160866ed8b4c0f19134ee263c4865449ffa1b797893bfe0171e3be1d7652b23c6e146763e942516e93720a964996e753fb5c51f133631e725099c8d23b4a0fb439293973677b69f6ed85963808c30000000000000000000000000000000000000000000000000000000093bdaf16fd4801aac47b52ac01c9d563cec02c54ae175e6d2a354d206485791b02de510f39a5885824db12577fa6e142a3d46393dba53ef60b115b0bfdac85c82d26458716d4e58c7e2da2a6dbf621e4664183950e637cb68b6f23ae65ba6996b843b49a0d9874de0c9e8d5e6f99322699db90a9ce8377b5abee3b724cf26982ce9b7acc2753b64478d493b4b1e1a7ea5703445d0dd8386e33bee708145268af68b2c7f34d4586bfc83ee582ad0d345dde3685ee04edb8c36560d0f87aa8aef0f2e5d9f6c1fef355b92e01fdd8d1ac72006834ccea7c4355ad13dbcf929a58052dc69efc1856598eb10d9bc1a80b4f72ff45b2ac3e3c8430983cd19a72da5f098639cd8a01f30d54e34bf88e74d8aa9805b17b720257b10c13b61f80e63768a071dbef4a2b423ee4a34c28cd70f6032243a2259c11d3ebfc37f0e7e9ce7af6dfc768fdae78c0e4b4567c93ffb082b5817b5e44601af8ed000000000000000000000000000000000000000000000000000000009bc7ead5000ea2166d06aaead9f88b7ab147c87caced45785892c612353aeb80b8ef429fdd44b4b1b8fd9f699d480b51c3ccdf6e94bd947e78a3b5921330acd805ccd5156cdd6744729030b63241cb7a31caea3e59ab65d23172c5c7a52c6db5fad2131063f5cb1418e1f406592a04b4338b418748218f0c6120e9d6ae55c6ff064569b03eb32ac3f8343d6ac1a3c6e95d442d36e237ebb5fa185ac9ca050da73830c70646782d4f15ea97ff7ec047464e015e5837d80df308118abe91629e1593f4e6d422ba6accbb70a680969f4bd00ace22013fb3c886c2fcc49776aa044ab8d261c8feee059dc6304f6d71e23d4b0194bab447e01ac84700c12f119d0500d9bf867eb3180972322af8e2fb4d3119edc5bafcf5525ad5dc5d6de140dae4da6ac0a452b7f0900a2b30bb5e909c4c40aa395d765873af357305ac2f940b4e1d6422eca4e9e2097977a305837efa1946b6752ee25720b2211cb6cb38c058336713980bf15ff2197b545d1d05fb2dd5163096506b1e1c3a9ceca0e41590920d1cb179bfd197423fc383bbdf2a2ed624a04d6729f0b33f2faa1ce8bc6b3b8d5f8c7050ab7ae43fdc84ba6a8ad61cfd8e3e93d6ca1bc8cf701743ff16bfa5a8e7d14a662d01f0283e32bfe1eb420b73d85e69b34c3a935cef5922f8d581878f15bbc63f9546f1c2f0baa102652c94058b4e5e92b5ab4121d374b1f1625edb0d0856a89eb0809c9e6bf77fa52257d98c500221c733ba0ea9b79a83abeca65b50e398b91d4222c0e2c842488650c68d9df4a799484f009520f57be7e3b490c7c92f021a4b686e527031d9e67c6739d40d1c3105be206427670afba6ee9e61d10db44481032618492bde0200ce0451a5c17a9315159f0e47b5ea9c32aa13c12dcb53b36d37f06875c89dca149fce846a233e49d9e018182e2cb662d90db0b2da6b76e846ce2b969c67a699c86008ccd53111720529ff22a7ec867a746a28f18029164c6c1df506a2c3d2b042fead11e8c9b38acad93580b960818f705d836b2c15a069451f24317742465bc0df71b6e96cc46fd36e906780838436d8ce5ed1bc6eed9f6155367075be6a93abe1c62423dc07835ece0030a813b7abda518b1a2047e1b834cda8020e17609985beac3919bb5d6b5a072fd0301780de28352207ad660434f74e3f86114cc25421d1451b2d059b0878b0fed5c130c8c3a9377c862f7f357b0cdc727950394e91e7a75c89aec17847ee500ccbb857c8317647a24e424fbf410e484d72f2766366cacfb7767b24d17b1124d3608c9c8efa56b6db0a8c4dc77d3effd330d46c465b529a419213cf6efb463c8b23c846985fec32d3d15d84aa3ce129b507b34c0e7a5fea8afb00ead26e9e1be1d126a46865fe7ff979943b106de6def68c3371e36024999cbfc81eee23320d67fe4741a12ecbaf5ddd1573ceb71ba30dbaccc4fe7c19caa33a5c0de007236164e0b96a75c07e00c08b556265400c6c7c9cbf8e2dc8b91403cd843652c20b35512e7853f3eb7b86601e1cffb21e933dc10a4c214633c92bf0378a09d5860db7e941a401be298202e1d148384e4a5c9777a37df4e56bbb7ae071b5577dc3f90a4a4d5dac281ec8a4bfb241c8c8764ffcc0276046162c7cda5934a2090c6c089848fd77b5c8c79a197006740944d6d3ee06b0b963f81a7ee90ade804724fc8062e789e0743864e841a37bbaec96dcdbd4e651472964480f504ef7e36be6b9864c9cd3093e436cceac2dc2fd5bbdb156622c9d6a23687b56c8d6b9352db6eb03fdea01e0758de3a88a4cdfed10b4f2c7edb91b36f5069597a16dae55a582fea4ed1a875d79d031f9aed1834c37e16cd3a6185d1b8f49d9ffdf99adb3f425fe6777c9c71da677fe16c1edcda8e40a68b3893d850c8189087212d9d66dca4a7e4bdfe04b7aeeff979673a16e630a981e89352b11646dacc8add3564d49669b0368f2873d8423f1f14c338a23b004863c42ce2d465d939ae92b9d83adb98003a7b89418a26ac848801b05211381b20e4f91aa1cc3387d41dff60712b4c73db66205ef36638bfb7022fe6966d43ab01e93ef66ebe56e95fee5e5f2200fbf530a048c692d5ca73b4ffeb799b8cc8f9c0863d53fdf35dd8fc9da6bc7c70060bb079d34e0dd2f6b90c5f8446cfcf2cd2367a7f67d699d769580a432b1b0e4a0dd7d57e26afe2055468819ed536307ad1fce6c5de4415595aa499cf351b8f7fcf319801cfb479f371e9a04290e5f3d1909bae740ad61784fb136ee99828b126a0e9a7cfb7a9ba11a2f26457afb3d50666e763b0c50db6541ec85f0cc5ee9ff610bc98a5d4b0d45a85bbeb4519cbb78067212e54b70f08ed1bfec143410fbff00c552f071a09087df2a3c4f7a475a66981203d766a7ce6ca1ce48c98522ed302274030a2e3b56d3f4f8a16c5c776c4662e0f3b00899b279bec631cd0b128ed2748056a30b6d3d2a743eda14265a56c87590fdcb0181899a035d41f080150a233392c57f886a1e8f56e86ce186f50c0fcc002ea90cbba51ee9e3f11c4cc49c4f352efe788954ff4dd1096d67c65fe02fe5aa34e3409049264a43b905812139dbb3bd7ea2097e3564ee96ca3be71ca7922565fc8eb5ebcd387e53478fe6431ad88a9f2ba3017e6e793167c379d60fb6c470fc215f3fed6cec1309bd54d5d869a19c0273942090b5ed0c9c80fb00da664dc7cd6207a6725ea080d0fa59d14faa064050c9fae9cb377d6676b925815f075d3b074bafbf75b0f5c8c80823e634db6cfef5c88c0b5eee2c09dbde344233c6bae1d909296131ebb902f70df34f67f13adb90d006dda45bd482c931547c1db41f63637afde5345e2276dd2daab4b40e77c472c1ae4f9c035a8eccc870625bc5dd415ca3f1ae488b820928579fca63fee3dae4e8d01e8e95a8c3422e854f022799096538cd55a03113254e869c3e6cf7ab566daace700aaf5478770f5f0c3a95770e04380c1f01d76a7b1dfcadd5322c082b0e2fb53b42a42b06552dd5349702a8ab7dbb7f20814357d388905ac03c56e5d0f475636fdd04b74820f76c742660dde2bf4985869d05a06fc1b6810df3711dd2060d74b6cf4c28dc60a5cbdc2c033490e20d344434c8de3a30a831e6be4a5885a44f58c74fdf64b0a2cae80c9b96d24bc555fb40d8f47a349749a89b45cfaddece78617740448ea61e8aca5b62490d863596ab6c2022c84fdfe6ccfa7e3330155d9abb1d5c43e259c7d860b88f7916da09959e51f3ce858e4824d031d1d9bc514100a4c60935aeec2524fb3fbbd8823b64968f5e6ada316fd9b0d76cf2ff7f1730728ed8a500007619d1bd",
+ "spend_index": [
+ 0,
+ 1,
+ 1560890374,
+ 4294967295
+ ],
+ "result": [
+ "07f23b994884bcf10b13b63dabe7c1f388d86ca7539fc22f8952992b123f124e",
+ "dcbefa0f06775ce907448903dd0dfbe3f754fb64909fae87115a0558a412ba8e",
+ "1d0b4bd141ae344c8cb6943699dd2c9c480aa343d4a27343c73fa002d7d3920c",
+ "5a7c44ae6d5f5b3494cc1180f843fbe60275377ac73334f35830c78e7931e9bb"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": -1889566180,
+ "scriptSigs": false
+ },
+ "hex_tx": "1c825f8f00010274e974590000000000000000000000000000000000000000000000000000000049412be4000f1fb9d3fb797df600000000000000000000000000000000000000000000000000000000690b0daa0032f54fb904adbedffff142db4ec8a3b25bc516a8bcc908becc67d7cf8c699500b29c7d29dca0d3a87cb678c9dd16f77913c5ade4f21431402f9110201efbc57b65ce926fc2b2be7de3291e53715efdf70323931cb2e43e86ef1d3669bdbd9a9084a9b6a3b6a4db8e4d7fb26f69b68ecf3f09970abd3a4c8e1f89a50aebbeb9bcede426234d385d0d2757ec18f740adb8117b7f685d57291edb424e3bb190f991325fcf2f8212da9aae593bb625ec558fc14cd57d23523b9c2a7ada70c7549c628fdfb5ebe897b7b5ccfecf6337f1a29aca0300f9bf48a84d6ae862cd0c30c808be134107352f98ff57a0b45c42a1a64ad9adc2d7109663e61e3d1881ebd359d54c67d42e1e7b85c9d3b76256cdebbe619c4a3a51bb5d953087254e8223c37a7a65795fe131177faf2e900b2cdfc0a406c734f8cd89e087bf87cd57e47e173f307246f25b4be62eb85822b55bbcd6c043b913b486acc7701f6b56c69491451364c458bb65633a3df4175b63c37881fbed88f27dea76303d92ccdf710855d483c50c69e09284a9c24857a4995f613d9dd348a2e003c602c7b46e6f85d0cc0731143bf5041f5ec6282823600d27020e65c83d8b659d8706e407f465463e77b32709a0b07668fafac94ce436612e38be1e80c7d190e58a2bb132c88e0ee9722e89e26f5dc3bb573e2624aa5b2ffb736ef1ef2798bec4870e2d347f8db9a859c8efb4980ff744070a25030c33095443e1d068acb2c38d9e4d279b176f0629fbea92da1beabceb7c9d184de51dd13571929320fd80ed0ff06e75ff4f326b140c0e8243246961874c0ef5c8b2bd5c1d859935fa66f563f9f15e6d532f6e1a21c10e34a409edea41750baa3e347fcc7c4f39fb4f08cdc6ad6cc947a33925c64dbc373419c8c70a730062688e6566998919976125adf06642bf69696ef0b0c4b5a445507a1761c37ab63f5ebaa8b2585424b1f687b105a5674e862b25666a54d32f5eea68f404cc6cdc2925c40a4d78fbf4d7f8f903b35ed422dc854cf60257d5dd9cc55652a3725bf7f4be21ace11932676d4e7947de73aee3af5d18dacaf4b497fe5604d005540dbb639610911bc0d5eb0017b8e592c8f2253744c4be6bb9cd786b8afe2d2db7badce4648546188af776f0c0f65b569e43501a891046c13910466ea05a6d3af1e56f8e9fffa301fd8c01cd406e0f988ebebc8c4b8003fddcfc481f00cacd6136c7118eb05bd797789cbe4d0228467aa539b4e3b37eb3641aabe38cc824d801519ec4faec0b2f11d8d1e78b76ec89d916ebf908b51232b703c39ba302e47cf8f890cc26fe29b52784157fd1b72242eb1b22d28bc6322e97148dbfaefe659924ef185ec61bb98328932109b56abc50a5e365e2e9df712c20864ab3cb57eb20609ba488973f8bac01ac558617b978f5de900bbe77f4cf3db5f18ce820d374e36f8fd6e7f0d98c600bb407889587f758fa1d8ac0679b5e97521a9daf3891dfd9e7fc23773bec088338d940f8b873a5d4fa1780cc14d0bc0e938feb740ac086e471ea2c9788fb9ba6a7e2614d52d07ec1438cf1a2ae252f0e82239478b82216279fc94e7840f05912e29f9bde5a1aa02960294080ac8f96ebf0254e8ee9dd9468685e4f82354b4530c0140d9975479a0fad3b69007c606fcdb8c8a9837c05b07e3cbcc8d2e50fea37984c31bf5dc7f42ebd9bef800480d86b75666aba8f507143570555a77d4e1afd103cca0a840fbfc90d84806b4789396700cf1ad61f",
+ "spend_index": [
+ 0,
+ 1,
+ 4209932444,
+ 4294967295
+ ],
+ "result": [
+ "18e34b4d95056dba2f50ae05129bde6f55805557e483834bb948cd362e922b0f",
+ "46eae96e40720a47888c2495a3e5eba41962ca54047c14e2b7e77da87059da6d",
+ "36b23377c481f92b265cfce6102e8c24e113332d45994a569b38653a649953e5",
+ "0f87b0636a601f0cc0adfedef7f48e0a957350e643ef946650a35f36fb4b3af9"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 7,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": 1968100721,
+ "scriptSigs": true
+ },
+ "hex_tx": "71d54e75000107b6d84e5d00000000000000000000000000000000000000000000000000000000209c3bb100ef9f0118e299bcd400000000000000000000000000000000000000000000000000000000b3848eecb8c909ede6d119103ccca4dfbc2e85234c5d655a21345b43e7419c65abe63d4f4d80d60ccacf0cae717b9c9ed7142a8f406bf33d77e9098954946bbd05afc7759657661308bc4f793995fb6bc453cedb1e45d6b6a52412c8ba703166d83aa614ed3d2f7360a89fcfa21293d18852e4ee471195a07c53c0e0907cc4e352decf2f75d6b2e7624e83e1afd8e3f8854403cdb106b9552f76564a9f75e007f66750b32ca3ea9347780941d94597e3e34de11353bc021198f6940679967ba1bc42ae387e000000000000000000000000000000000000000000000000000000003857dac3fd4d01174cbaf6782b012d2b56725020929cce9952ce0475c67ea056287e85d95780e79327050683fcd1bf105d7468c584e61dd086c2783a09c3f8aaaf94164c3bdae3d88659612edc5fba6800e38ba824715b6237dc96ea8dd84b8c317c84563ee3a44295d902921a92c626459ed528fb26c7b13926b6941450866a4d98ed32a33eb4beca80fcff508a93c5769f62cfda1b4ead917353e22cae84425d60ac61e89f48b7d3e1ed8548f8383c8eb0e64cc2c3d85d4d52d5ad94f8c2f2b275166cec72fa62df15a1753fd0e3a39ecfe1945ca72d967512455ad1b872d6ae7d0c905b0d27b77d321c30292fee3126853fd7d0921db9123c8e98b9daa62436bceb851f4f1542328c830588cd7de028d7dc91ea0a302002dccbc3ac900c9eef3763b3f6967a539655cf86d78a89ef7022382bcadb2a51fa64e62a5c8b66bef088aea6b9d686e0aa4568e29e28ddb2c0e3bfa768d02b4990c3afe30000000000000000000000000000000000000000000000000000000018de6ec1fd15019812e1c2b3e36f611e30deedb5a60d62a2800a5e21b293e85f6dcf66e3cdbe6210b3470fd0ec3ad1feb250b087f1fe97a4a36da4f55e5bfda3feffd9c9a87e9adcdeceb26086b802d7109ccc4abedcdb334263b93646c22e87c7ba0c412600dc5fb55db472c21b594509e9ef110a0f10fe0d8a7276cb192495e8177ec228055dd1bbad401e14b981a3bfda547441d67498a492571d301c7c592b8a05b2d5aad3251cf3fc0f0b6ca396ad39cdec1fca93ad87bcf0c4cb1e074d18bc2f8d64f6dcef9335427ddf3073f2511a1e6e322ce4ab9578f90827601e436226a725c99412e93d8b4f4c96cc421fe766924cf82e5c639bfdb80a826a448edfd9281c3e8d99638458b5d0b0efbc9abe15c1a83f0d92a181d19cff190f12be38c67555000000000000000000000000000000000000000000000000000000005d1ca4d6fd3d0109d0107054af948a2f7f1ab85d80206c2d111e52a02fdc52bc6f438f18ad58fe4979ace46950f8cb12459b60d0cbfca39bffbce5f016c5c6916c63d21e2987a76dc6b291bf2cc1362b37eb1cc81bb066b77302eb73839943173b983b1fafcfbef5587433847eb10cb06c2a55d2d23e3b92930d27552e8fef6690b73d1db5e3f06795775f0a07a776e404114616c470ae67e6f074845500f044ce63b531365edd47802a86e0406069506fd8b01927ce03ae3ca0b8b1e19606d82f0d0979131a40514a3b3304bf50eb6896473e087370e6813abf68d67ab84042f3612f94152f1f4c8065d4c5d8350f9386a592c50df9f5bce6010e291ea2cdc86f391b1c5992f87ce11c8c03f8ede96e1dabdaca44c23e89da04e7ca924e59028b5a2a18b001b0535a4edb3e7485bd053d54370601315f7a0519eec10b9ef02eaba51f597020b5733cba26e10000000000000000000000000000000000000000000000000000000042b02f849b850a2f4938d7b56d85d6afc0db9ec0c0c23a6e0b9321a37c333de904dc8e2e88d40327af86f64d7221baa92a580c8fbdec96581bbbee9733f09c1c623dfb4ef2cb4b26c0bb42f4e3cf3320465aca67be99e48754866956d86433ccfbced928967204531aa3090ee7f588e11a458a4dddaf9ee7f5193d56ae95cbba955d4dc8e22d6ab098c0153f050fcd795faa8ed9a17a56fb4d065c36a09f11275d1e9ecda8f24d4700000000000000000000000000000000000000000000000000000000aec8e2a300001fceba016321f30650e0a147c8dfc6de4f7d2bb7b3e8e0d40a5f92c8aa747d8df1670c83411cdfd311acf234e3a9c56ebe4b214d0c9b99ef0cb3381c5f318fabf034c92f8ec6cd2cf6f4509850a584d131d38a6ec629bd10bfaaf58f8290a74f29f8d490e62f4ddcfae07b59967c7962ace83dc4fb4506e16441507e7c8ea92c9a91af6be770aa3649f2c1891e07e5e73fcded3ec6b6762274d6c8eab55a019c0d930a8c70329a424f51cb8ac41210aae262f3d5b2ae273110e2e8f6389a43a9f783bd2896a56c4ca72081a8c3a954d0cb897c2e4a0173888ca3630787723110096993f898c03a0d51ef7da9abace3c182dfeccbfc542750c4142bba5a161ccd0a93b5b693c9754000b917a05bd5b79270a7c96c2a9a4d0d12fef9b8c930a7ac6308532eabac983d07650d15b91fe358b96aa7b7d7f1a3aad08f2755baf4d0e02c791fcbcf8bd936583204fdae0116c24d8d9e5017d8dae77bb97c3b7e073c66096981277f18fe865a7270b8a636fb0a32ffa86eab5ef18cb0280fe6542a5ce9f944411ce8eece59a01f73134524ca062dfdc004d7e783e84628276816240a245fb038084c33265d9782061a5dc964e4a43e1ad418bacb19bff83724379d5a0df45b2b17d5a3dd8a6b434f7a4950f125ba58e8fe492ebc89a35f5fb80e0d587c148959a897df99a87de1da079a15e811da711b4e96e56d75f97ebb9b13e45002a6667618573a5b8fa35291736a7d9e8f2578d596aabf95f08c0c0fdfe8a3d31a89e734c692d0498b7051d5d373bf74a4d804ae34eef159eda2dd568b179c82aaccd864854b8c98388957ea73075ce6c68c681e3d9b40b2a86c224903a886084cd7fcbcde506247f8db1b4c5656c02c54d37f9d3ef31d1ad980de35a692b5134d456a1741a30c6cb121d2df7b1f78157739a631e8e583903537b1e103f567c2cb8d4072b04b1a0ba7bd5fd1e4e96b938c863b660569ad4b061cf292dd308074897300b23d2f7729fcf027e780b89fae832b5dcc236ebc64d878159f9fdc4e6592c5ae07a43777be86daecbc6643326b58dd9e83481dbf74d42a36a90fe9b2a4b2a5abbe6045e9e2076ddf37276c614d371c7f1c9a0ef95292ebe0457971fd0dc4e3f37c850f587164eebd76ebdc0786e29ffd52c12b6db9388bde3831f631f2b3afbb0650cf643cce5f05ffcfb789960ba6e4012fe598b092ec018b34e8171a6a1de3df81ccc979cad55893761e7ec70d89706d5660a8fd3192f86039a3f20708d44d6dd7b726f247e834aa5648231ecaee97d15baf9ba09f333195a587354e168d305358ee7185b16a10cd3f2b651ddfa83b65f632046aeae8e022468a098a353a995cf6cb69527914396f63fdfef1059e939d6c1f241ec1d1ab4f90f61d253defbae9090bf5fd1e01c4c70b19ee49f7fa40d03b5b93645f249475af6729c1117698c52fa2fda6c8a89083bc3ce83b788a4e5c67b92682556f1138261dadcf568a0e03ed9d7305e1b5b0cc8c6b18bdc677299ae62c4c6906a92530bd8ebc6060015cc3cbb36ade11d9c98b27e7a551cc83e5246e08a624325a7a5a8b9cca454e94cae68a20f10ea4b63648adf6aeea74ad764199c2ceb3a4d6cd2836a8e8782d304e5b5d44cde8fada642fc49a18bc5d7e78d1e6113f9f9a6c0b5cecda95d0d7e0f0026ac8f3a7d136701e3670ed036d8570d5108d517b291ec1779e49d123f416dc3855cc609641c6ef4f9b218d01e09c2ddde5f35e8146713bb2bf637e50357d6d954545671571bf02368d464f3a80d7703b3bc45a7e518c8bd23fe7b31b14a1933e68617b7a268f63cdfc0615cb046799338b2a8937369532885130f728d83472d17bb7a9a2e0e7f025473d6a04fdb7011b43ceda5924a8c04138707b2e813e05b977d30d4e38a7d95927ca232bbb5ea1a023f3e046eaeb230c247a51f22a0789d1f67dc92fa2dc0f783c8ace067fef686615396fd2c27a177f20ed4bb4c88355c8d83e0f51a9b31406f84c4a2a5ca668e86b4d2e64f46568473aff4e33ca21b7d31ae24c9509151331cb3e1ce348bec717db172bd4010f2e536c9d7fbc48a6960379a37c75fff53cddc5308deccdf38288b2f0245244b0ba1b45f0bd802870575b38dd1a8c9346ff2ad47eedd54115454579e6053b42cf38de9722fef7180b580cf13dd100681ddff75e8fdb262af179f2f11fcbcc8eed0fdaad2e6642c877fe19d22ceeef8aedbd460e2cda20afdc2faa27aa3463b2ca1006cba996cf5883b9b780a45606553d51a7050d512a06828ea9d8c97e5c7c3154e1fee1306a7ef6c82e344e334e652819253c6718265b15d83cee6770d585c313278d25e78928c83c6c45ad32ad8de1bd665a762db5f032088a3dc3b300a574ecabe3d872f4f77d4c1a758bedb646114ceb8730c7d58eee477c1038d3dc2dc405282f677e26903cb42b1ade7d55fa1ed54aef58c2886b8940924165ce863c80e99beee053072ed50a997edebac7bd30fd4b013f6b503a0891e7c112040930a235d3b311dd8cf81c71a6cc1df44120974a40521d685762d42260137a332a9b35004c729f5b2a2233ea6bd122ae8868b96b57d8d537a78420217b12371e6a41d53570ad2ce6a29bee8ae4b7852844c3885869ebe29f08db97658f2fb1e8f522fc64d2392cec4dd554bd4c69c7210dccb7d386953f742d63797370ec2821d1fadda679e30c42b30ebca43cb8634b2ae9d5f647acbe30d2c7de434695e9e0f9e939c8cf6428dc1fbe94a08707158216d326855b47de19704c0e1e868d575668d4a37f8bdf3037e81a676759a68327c801b292b42868af3301d66c6a53aeff11c8edd5c3030d9e9d27cc9a4c4850837aba26514ed5b35f3a76d6402bf54e10735a6877feaa47c74a65cdc4ea487f46ba65f4adf01800f5217949c9093835734fbc79479fb19a522d67566d42c19ec8089559b1f77068809edbf1affc4a57dfacfd4f0129353c77435bcda2d01d01f9d07e489c31c81c3138d95142be2b4a501f84231efb13db822f0b85bb5d46e055505f74ab2e016245f61d2a036ff83acd8e74a7bb5b0f299db3f0024b0755ed4151584c283452d67727403c39ea1f68ebddf84ee0eec2557b6a05dcfb5412c71dc94ec8e03eb393378ae853337465caf98903edd34ecbb34022902eddb1d125378f4e8d6d61e785a80e71d6ea6c5add25b19264befea329757a3948da8ad27c50e742d8a01bdb3c7175e04c8b8919ae46a930372c38c95dcc533ec2b02968592d31de64089385401725ff042e979fdd3783d54dff6ef9b4ea1bc210a8dab8ca449d0e205288850a0c44af79c50cf7e1b8bd36b4ce864d70b965eed7219214c324b7e378d7430cd9fa7b69cb462547e0ddabc889cb767d83d03153df7c405cf1bfc6d1789376bc542a5448a17568f1736da8ca895eccf15c094a62448966470fb9773edbfb7db4303b6d72ebfd018d6b590cdf7ed40c7abc80df6801a5e0a56e006cdcdbc6da5bcecf8005a3c6013645e49d33cdf10948fdb88a972ceba920a72e82ac0f3d0124fe55588137604eb4f2ebefdd57aeaed44f1f0328e90526644a848b548b16947366473b628431d8a80b661f5d538a9c15ed288cf7d40e144efc89f7509297533d3e0032c7b99ef1929956272ca693f76a40a9f76ab7002f11f549128380cc7204b80989822529dd9307153da4ab5712eccec3e4b2b8ccb425ae599cdbd7accd00355af6f190490f9d1551be069b7e6ec9d77fea777ea86ef74d61e19ca22bbed8489bb74b47ad8b453c173c6699e14b66b3f7775e0a859a020701d3c4ea36b04c74691c563f7e427c755571563d47b80f008e6e8ae96bf6355599f455ea68201e9cdda8289f48e516ab90dc8050691c2874b64110bd4e899169e7e153c9c54e775833f1b09fa70d026259f607aed8f35a844b3843afd49294cab5cddbd20e88411e17b3594cb350cad5cfd68ca304c6b1cf3d9fc9ddc714328e53ee6e2d0d20aaf604662535335303b33a3d9b60cf4be9c82758a09bf4ef8c90e9cac028d32317c51eac0690beca785c7c4b96d817f01fcf7ea184a2481edcf910bc098c82ed52f491e666d55f59142943cb667a35013ec0077a17c1e519a7022d00afbffb18ae0f6230b06049515c90846f8dee5e8de56080a4c2d4d053f8f0924000b34546ff0929693b484ef7fa326d096b905401aad28231b3cb5dc411fa5401b04f6add2268955ac986392b825185f5652007aaa3530291a768fd508ce9cf934819c50cf6bdae2435a5d09e323f714d83e6cedf4c22f2d3a040b89551a27153fbb967eaba61b2c3fc37278a6853f25c392f16c607e945abbc173cc0047165666e4ed2fa981c85cf61237e4a614ef09e84acf4158f581a1238ab4693aae877f1c969113c549275f12ea797f2119cee1ac1d73e63b81e2552063569a8e76e95006bba2f31",
+ "spend_index": [
+ 0,
+ 1,
+ 3326047036,
+ 4294967295
+ ],
+ "result": [
+ "63c91fe826d7cda1eda1c7ec22e086a161351c0fedfab39a5f0511820aea00ce",
+ "265f82de40725e29612043afb653e7ce4632d49214912d25dd976906cb8a8072",
+ "54f9ed49686c92db01923931ae8ee4459cae5ec800a04471f91b3c8d6447428d",
+ "4bd7c3490cef1ad26a759ead29d2be88f64523010433ce1ff13c1558d6f96a4b"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 6,
+ "Witness": true,
+ "Version": -316499655,
+ "scriptSigs": false
+ },
+ "hex_tx": "399922ed000105c1709b2a000000000000000000000000000000000000000000000000000000005181be300054c54e0220c16d9f00000000000000000000000000000000000000000000000000000000828b1c03008cd19e08b34c333f00000000000000000000000000000000000000000000000000000000930509150028efa61a5dec5a4000000000000000000000000000000000000000000000000000000000f5e853680099eaabf38cc2679f00000000000000000000000000000000000000000000000000000000e486812700ad935dd906ff2a3db5382ef145c8bd658166ddf1306a4d978cd229a096de55e63bf66f42e852fb94f37c68996efeba07923138ec6ec460e3f0d6f44693aaa89ed4b1b6527d84abc0bb4f275dba2758ccc4c6d7be64a6915e951cbc26c95a299dcc30a6651870d8f188e93a863410cdf0b66f8dd46c5a8f3dc08a0b0aa84a7b20919b2fe0f2a374e7c405cf24ecec3d00faacb82b9c72c7fae68c417c0cd6ab1b8c73a56d5e5609e3e1833ea4740ecda2c16866c7ce70abecfce5c12adb99944ead985c78ad2dc548740c64f4bb24d2539726cf4b4409e4caf865d1c8df26c8d01d6bd79c32ce0f8424238d740a04cc9ac3e261a41c780ca438343fc633935f44106a580f85209317b135aa84c12789d4b960d00cc57e041f580d557a993ddf4070bba3bff4b1279664338acb6790d3f038ec6cf1fb6ac921180cb6254074cc0ba05ba08f18b24668bf44afd9117df1c97553e606b418ba519db256dcfa6d48f47912e12d4eb471d480ff7dfb3f4bfb296d1099636ecb2d9387ddb131967bd86e3e5a090a90e24c0b10e7b2cac7fb1bb8b2e2e148b83f09bd837354f374ef840bc56edbb73e8c438bb26d2acf56f329c8cb1061e5d98898ca7d9b7259cb51de0fe913db80b314f79a7ad456543b03fd2b4d136f4232db804ba492d4f8a6fd9bc3a615971dba48eabfdda968e7eabf52caca7c0ad845d88ba3336afe1c3bff6a95afa5b65987b25a0b1c4f76bd336ed2ac16bf4cc7e8842363031a611f2781f679fd6d7dd92e804ac3bec96bfb9ce27a5c1cbfb2a03e478cb1c9ce4f8be188744468ac7b70c5076df6a4584a657c7d89c776ca662b6e42a48536f8f6dcca708c8620a5b900eebaed0f18bd8276e1122e926f26f8caf693b95849d257abcdbb204fc8832eaff01c6550fcd560e9766ee226def7b551c900385c586d24f3f98b733a24f2bf2d90fbefd5af2ad4f4abc72efeb4c73d287296952c068258a22f8d7e406f90cea5343096cd9b45db89de96273a991e881147b3d673c380b7a92b2784bf7fb90947fac99cd32b9eed14943a270b62e846a3c6cbdbaffb572b62cd613e3d34fda404ebbd70d6491e6e75547b5ccf7a2a13b411c67761b875b938730500c3827542e6ca4960ab78d91ca5b2cf8cf00f1d517601f1c96443bbea4abc2b9dd1ea6ab7dd2231965fdca577c6f1cc79492dc815ddee4a7e2fc5c96c8372dd3a24f84033d166a62c9becbfe4024aec470ab9fb9488a86e7d0885bc3777712ce0e3e4a26068fd57d0efe01c04712a9397f4f02e096368f9491ae381c063dcda252595d37cdedd3005589d09a4f3ff41682b2853696f83b534fb0760f4f5b46baf4cbfe9155c866b1f7690299f1ef2622af2c24718d36386ce690c8bbdb72fb292561c601a863cfa71d0a7563ccdebafd34bb41168cf46c230141345e8e8fffe1b2b19e7c13f0623957e89a0c9cdae2b16dc336bd13089f40330222282ef009cfca60d26c8523419558bcdea5af03b7c5e5035e6a1b4f98691a8b531fec14a794c60679baefc4c2424908877afae1142293bd03f4f6c0c79d6a7cd2c5034737ee3e407cf3c170294c18c3bc71a295dd2a23fd4de738547574940229a974c86ad8e30030cc9bd3c0016629bc83f579bd2519d3241f034d558e2997e20fd4070fedb4541af8f4feb5c9506765539e06efbff3b85940bf62f837ad4a425e6ecc67d35d15aa9dc7b2cf0072216e87294f49bd7da547b27648cb1e124c83521db271d9fdc6f1d0f0e416402ec6049e404fdde01aa5b1137253480a4f3cd4c1c7b46a72b0babceeda57b63ed0ceac604ec313ec117a0b69759d96e5e81ce048b5a684f7e2cc3170cfdf3470064e110a3948d4ef132fff97a9437d6cc8797502dc05f412ba792b048d620ea7b4353610619db1e6b8eea6ba305c6da1fadc46a7698a4027bd56ff96a7e3d0e34266b9d1552e51cbdde5d1fb3cf8ee93120f2eb68b8ebac2ecec6a5b7380641dfac005ec21547b994508a71b5a0e871d091a6dae6565fc79aabd13b18594617c3c30959a1de1835e4ca8403c8c3dc4beedae8303a149a12e49f0ce4cfe64dbcc90047157ff5a03061ee1b6d6cdc1ef27f1e75b67aa2d0d08449c16bdeb6b42c793b26c3bf9b3462b62cdcb29db21f720a0eb4669cf69d345c0da6d25ab70a989f2b2144991bb1d8231cd04e3c351332da12ccfad35363e1fcc1c1cc4551be2ee3322d07c6475cc6b793be7cf463733811cd88b487d9bd88a1cdf235594bf2db268e8d033d2d39e1ca2f77fa9bd27a2aed1a76a0e85138a685062b88bd50a0d2873d33559ac12fada26e98299d487583491a251d53a1e0906883f0ec513d3991e9b9086154b12ecca1e2866090f59d464571ef6d6cc8b11731eaf20e82e8ef563a0ba77f6c8f564ff1828b90179e83fc41e1b9979a42f0282c328adb5ea63d49da65964eb02100fdaa01a45962b4510a581eae99064fc0273ac5a1498e9d59dedf4688b37b0fecea4c50024c8a702de7dc9d473aa223b268f2a61ba19fcda6c51fb46d8d3fad2c0315d9d315af8cdc31b4c3d2dd7289d15a4f646fc93b7010ec188820ffac7403a0cef0767068a58d8a9ebfa47eab5135b622350445656cd880391e34c1d77a6137219e5455d222ba1e8e3f1c6361445c57a7834da401a616604de44e95f9f5c6b5bcf9cb9d88e7df9f2ea03372faa4e0a2df812295b44e719d0d39e90c047cc0d1044b1b55bfae0e9ead6479cce7eb189b538657e8355fef4f16a27ed44d57c0d86f957279096696b1a2e31ae1c61e1b743e434e8fb5855e7edd756e05787c016547f9cf658e2b7f4e0eb80a170bdab8dfa9eb756f4d6cab3a316ab97e6ac56816449640c0358eaf4c9ac033805b53f110669f1e6692db13c326e12fae93d0b4f00f843f129ba8d16484e7e61d57b3f10981c7fbfac811ab8cf27fa0f98e665a4020f665d5b66c8daec19e5b1a2e22b8cbacf66a708860d8f97997c5d14b0e2061426df76dbeee273199fedfbc4f2d194f08f47d9332a3c6d6798b27afcef2dfa669a76e8833917da247ec1c83fd4d01caabfac6dec16afb8842e9a6cb034173972133bdd7c2280a4cb0f7518fdfff9c4a32b413684c65a6852a5690c040f549916c1e7cb775484bffc5a35917d5505201b3f21e009285d99c71637732b24862f3c3b73e3e6fff9061719c72c5f7e932a0925748e10c81292f30bd8657d078edf359e55706cbc850495173ae199aacdb07bd0462fe32f9c9b7523024742c4da7ae42d67b7a699d9fd4fcfa4d430756525fd4dc78fac49c9dfd34085bdb4c8bb32b8ecf7fe144368e55110c18f65e42fc85c80035c61374f5c17681ae01c42fc16b926f6964052676e8919e124e4992c7da4af8473603487115e9d9a4924bcf7a0719e1f62c8f730d9d7306804a236f4cc476a7e4041944892ff1c8dab2cea3e8ebc13ce450d9b0a9927d11f63e62bec62fac208b5a35a43837486b8bbc4388fde307ba17feac696d2dd932fb39d8f78c8a112f03928a818a7cbeaaf875fd33011f77269619cd185e58c514df8c688eb1caf658bfdf1b47cd08caa126c278591eb34353e85a2130d75de2f482ba1beb21ab3a33021dc68a9930d169dba4046879da7b6497edf3bc48f436d64de75367e86588c057e399448ed5944bd8acf59b900acad0e79b293221213963eeedc3cda833e014be2097228d668650e9b9eb76767af829cda02d298a2bcc1af6bdfd742d1bf5b09b071393f3d18b461c0df9f468207c7a96f5d3fc08aa2707eb82569166870bee193cb8b9a460167f292bbda2cdaaebe3a0b42332ee228452b843f0a83f45dd6baa70e193288fdb15585eba9f8d54068e28b4acb6f7b07edd9ff589ff3c30e51e2dcd311de6343c27e2a8993334ce4def6e55c5f439131ebc913025bb77608d2d3c19abcc0304717ecceb47fcaf64947e6e37e076c20a2649c0de4216a3133d1802fd3601e4824f69db342e4ccb2913e45059653413ba911971b243090c175c06579038971e8dd31e1159655bab2329bb0155ec5ddb4680a2d886d503f3a893148202fd1ad1365fdbd4813b8a25ea87de955f027cec21cd203a78ff4ee9d905197b8d5cb6550ab0df4ce595a80690f28b832b2ecf305e6b7ac47a511fd3c60c9033d050b750655b62a87d133a57cc2f2b0804516de42daeb6a37f23b294a4eacfd6a368af7221dcb556a9ea0962419e636e87ea7bc58617cf1db6bcf567c80c0d07fb6282c175507397c9e513923ed8f799f91399cefae4d6e27f83270970eddcd8638b085a411d6b449c8c9adc49245dd5b6fec2f96f9ba406924086e8f2bbf228ef9f805e1a4f86a3740b2a80ec1168bd1d58a695f3a3655f1549b63f3e06944981c188f2978e71d4f98a16e1d0f63a4ef46b5a27fb40d04abefd480112f3aa9bb4e3db53c86500b150aee6e7dd4760a0745715baabea6746ff7d77936f95afba776d79ec0bb1e240df2481d13d96f51e1250e9b2c9cedc700359edc703cdcb7c14de860f18ea9d7cc78a94f73824e0bed25d4c9ab367c2cf8c240c3c9693e87f2f564fe03d5b9ddb8a8852babc1d52dc5934056e1fea8ae5c9c979a296a2dadea00c70c67e692e44d4552974116a3ce9fb6152990fa99ae3cf15bd3871684073f869c4834f1acd4c8b66c81b480fad93f92aa56ffe2d182f6d04d09205b06679d5bcd5f8ee6f3c32a613f2fcb3ffa17b94a521f69415568fbf5f8db20a61c8a768fc6730159fe88f634012316b568d4d4c720c9c5d67fa336151bba71a1f58818eece6ac3ccb3438c05a5a2fea8ea5b1663df1698389d4b5c92646c1dcf0c21bb35ab469ea47cb0e1ae0f03f6cfe14ba4f9fe7ece7571c2429d161f23054fdaea9bdc71c0395b07ead43163412336701b0e795654d21ac24d58ca14e0506f1a5ff07837881a89ab01b6fa6d51b2bf76fd292ceefca1bd9785e908f14322ed8affd8221ceef519edc243d7465d99d97b9962caa3e6fac0fc2432126995e55aa52c461619f5e1f58a936a53030b30e5841fdb1ba3cfe0d77c98d781273cce1912b44ec99e61b087dc0cdd75006997910ca92019d0d4690b5ce4bbbbdfdf0019c2c8e2ae8a5f4b9c4656f226eca67bfe0d3777f8e90d4cc092bbd0e7f32d287b3825c37baeddc7204cf2d9070335f07b3c22e0951d52794c47c4022d94d098b38d607288468369199b7840b3a121b3a1c66d52fc7380908170c96b2bbfbaddd4e88e1b3d3ce77f1cf7505b12319fb0eed5ea013ff55692534280c22ac9c0d9f827b4ec72475f1299834e1105ac0a01e98121f1693d14f5e27d10ce2730b8975feaab47a75dcbfd57ac432fd7f0eabda353410504dd77349b4e184d8f6c5aba889a1a2d932a0f0b2afc0d58d410d1a841c160f6eea0681660b462e9b7bcab5e302af4342edb17f7d444aeab6ae741441acbd3f5cf555ac96d6350e812b1fab75054819c97ac77e74f384e2a05ffd9de2adc28d5c13637a44082f75287914ec12062674af016e348ef34ef0d2ef4b4d5fd8e5244a7cd028e011b98e9150ba8d426d0fabc998e3a596be06f3fe2d7c3af46bdf26ed1fd37b793886040621e7bf57fce0154a4d194a157c8a6af3f302a260879c591a28b6273c65504b7a54506fbdaa97b89a23c88203acf07c62c36731a93c478391167d2c057142030b2d575d8cdafee3113b545c2ab83df742914bf86942c96bd942276d6d6ca884c811d5edfb80c83c2138f1561ff30fb713d3854683c7cb60f07d29376407c63c5a5ec7ba3a9ba700e7b7cbe0f3701ed8ddd849c254fdeb0112362c0b589764687212493c7bf438e05ec0903b77fade1db4512ef3bb1196d4124dac4f1e4657f52def9e872b0c31aa4bdc08fb9d1df950a00bb3b250cc73439f2955d6d35c1d54bd27d8d7c777cb16681862c39b894d142dea8dc41a15f591b378583761356ba4f039b37fe819b487fd932356e59cdd66634f6ee2f3629080c755caf495f5f3091be1c2602a663ed195ae3d7a77ccc56d9411477e4b2f57e218438bd0e2987407f982246835170f6cc6159b14e35c41178b57537bd24c9bf8db2b7da8267b9b10a4e82f62c07e689a059cff0d773d9f4c5ad78f8e4849feb772df2f357943c654e845e1f3af28cc79d5d6207acbb26325cbe9647688c0f127c5e0e8031da75923677e7e9c931875e036d416d05e2832cfe91e00f1de8615f279ae6182cf188ee75a7f605d87f9e0b6d6ebab35e0aa34788c38b5b7b128fd7119c569add2c3347d83300a86b2ec15e2c817519595fe560669811e172fc338de2ea61d3f774b9fc9d9965321d001845bcd773bd258aed2dd57c0dce66f6ae6cf42991a6eb9ae223fb6c50ad06815d6bbe7219231264377272719a286439893ddefd2ed180d21f3990ad58bddd9ccedfb5b6966fba304f0c42cdebc7e9c0994eb685ee7db79f3553470cc93c0d0f611df7195f9770758eb6b2309ecc6387ca7e62fd9b220c6ab39f657032803fd2a015634abd73829d0058c9960bf3a0f788a642ef098ec627f15b58ca5d6bb965251c2f1e3829c83ba3f8fea57aae92a4500dfff3c73d0d0a11ced732816261396ddfe85772454594276a4beaaa36e2164bcfa787b7493f40af404263d1c6a4d2cf9fa12713b46e9a496f4dca85f6800c4da90718942838c64bce8b370211023af5f494bad465ac916f728c79d379deb8ba09f6afcaa781bdcafc17b029907fbdc79d5d03925e5ccc4bb9c4c2ec79d4e514268f9a984b97882a8dbba4e865d7c44f89507320afa670b2a43851502a686891844b87cf65fe3d407a3d2bfb8bfee82b7400dd77d4dc427e16e71713af0b583212a27570479a1aa6461e66efa0eef33c6a4c3ac05f5249385a5ce0a4c2b50da420b77c1d30b37b5883b4f3ea0ef59d87b45a4a6acf5e6316207f1fd0a019488f32a6f3a8517dd3ba49619143f57f62b7bb1cfec8dfe18d5dfaf678b7d13670f49d65ff53f50f2dafddf1f858bcd7667b9ade86cf064058dfdedf7d472ed56365c819512fece143419daf7ccfbdb403835a7cfe0d3bb2718163e0d7046bbd53bce3edde7534fddd4cdea5786060d94ebab4b33bb74a833da438046ec6d787b3c7e88a24c670234b743ce69dba5aae453d5d2182692084cc0b238633feeb80fc684c863364797314e344d0c9bc4dade506574bbe6829c2dbc7429c6da5df2260a2c5306b0aedd6d2c830f872c9c100bccc5001598843ae5fcc26da830177e59a63d48fbeab5daf2b7ac66ef31469e9f9001da671b0c1eb2336df53628a081947f7d9fe63adcc8bddafdeb019edb952ddd6e0ad6fbef677caa99b000f96167fd13b2324adfa1d3c78ed5188159f5619b29604abc8e8d0ee8e8b888353a07aaa0bc6a3cf914fe737f3bbb0a70a142b16e52aa55975d383011327018d2110cefebecd8882058c19d4a4aa7f080fe4fcc781f43ee67c4eaa948156bfeaee7cbfa277816db60fa5deba4bd9978a7ff5e0566f3def8c0919cc250e304a3965279417010664596649f7b1ac400934ca6f8c9d1ce1d63c3086c9730bf9cb762414fad35019f0f2041ba5468c3eac7dfb1e8083014affda6ead6b2013c29495c6d35a5400bf544774e301eed5465ec3e12bc31046593ae3eb9d282deaafc83c0d8cf885d557f30be463e7e0330cfba4d6a69984ac978a6b5c391d6d1d28f2115a0ecf4d7cbea55153e3e9f0b0c219379d2c59aad5c83e952124f475ccba0fdb03e3ba62844a823777d513e481fd69bcba19dc62b014af2f9c8e482c163e061d5578c5aad292d254de96b191ba88c36a4ebce818d9d61d4933aad15be9aa63eeba2de6026e3b36c6249ea5c8c2699da5e75f4fe56cc157169f0a78cc9d3d6b12f985583a4d6e28de5e5b30c70b3826342bf8c6ace75639cc08fa4f7562702a307060004b18d07423d94d0e658c9a9e7141b625d85f1605942fb9e510c971c87193e72e3930e79c8008b948ff93c672733027c94febf341d293541ee003eab19ae",
+ "spend_index": [
+ 0,
+ 1,
+ 1446282621,
+ 4294967295
+ ],
+ "result": [
+ "401b491b439289d26a2f389d10fd79ce500b93e9a9354a07ca063de47bd21fc1",
+ "30dd1c57097fd956c04e75a7d3a8ea6768ff13a9dd990804926664203c1b2b88",
+ "0b2095f09814fef07bbb58e07069524af34c0416e4e20d5766ce5b682e5a31bb",
+ "7d175fb5b55e2d6ed61a7f183854e7fb48b822d5e2a5d62eb15963c716b22daa"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": -943280664,
+ "scriptSigs": true
+ },
+ "hex_tx": "e8adc6c70001061d608d8e000000000000000000000000000000000000000000000000000000008dad378df19b99cdefcc47348448fb0e3f7b537987dcfaf7a09f1dbe4688f88b41f1a63f06aa3824f4c59baf3d47fe01fe38f012be213c6279ab131549f362e2eaddd1d5cb79d622ddcfd738f2588879ad7b3a54dca6c89e2c848b0a94461a2a279a85f4e40023820f7f8bccbeb059890be4596c919573b508f2b48396c00f101e79c3a8e8389ae4cb5b7a604254de0c8ecca3c7066cd90a0f83bd9b86e6723d6e2cf7e483abcdf7be88b41ac337cfdc2e4e4115ad7dd2ddc28b53a2d8b2c8f70c67cd1c2926760c680fd6441945a84b23cf1d1186230694ccc8661ad71e60f2610dbaf2bf6187ee5600e56ab30867abf7a3bf143b6b3eafb9afb71ed72600000000000000000000000000000000000000000000000000000000a3427510f5c0f85a2961730984b8f0628679eca08db731d39468e7422df04e9cde3757123e7b3af9ad0cad2d420ed16cd64869ae758c82ddf9a712d43fc35995419d22da479ad41714a059a2b6222bc2c7e2076f83c250488b245e9c229bef2dc1dc87fc0867a4f74267317ffa8281f7c81d70acb00f5751683ceed72c042b90a736394113c91fa6fc865c1fde963f14b3a98a67a8b555c516d2e5693cc7249787ffe875e9f2264b3daeea6fe84827627614ad35d49a74133fb63527de79de4dee0d7bfc3530431a7e699b7d3ed229c8a10cd05c1172ce249b6944b80513fe8fb66070fe9e3d24d94711943da3d044a11523395a11a8bf983da4a0eddea8629e315b00000000000000000000000000000000000000000000000000000000d0f1d3145df7dda966acd462152fd9d689cf4984fcaf790de587b8f511c329b7f9e077c7c0cc7ae556b0b3bfb93b5e66d4b4e23b30354785db6c1a59ca9f3b022aeeae09a307fcf75e16b0c85089ab0c910f76b3ee60e7db3cd8f2ac2daec2e91a6276cc189eaadf445c0000000000000000000000000000000000000000000000000000000029d9f470fd7f0116992fdb68d299e30b142a324bc40cc9552ab0f16fc59056f9e41b50231c0ebfa05b69c4807762552b67c35b7dc616112fc9bc34ff7afada3f00979fd82d40d70dde7a12a7865f2835819bdcd8088abd36f2b04bed21aa3d58a407ebd7d307de842c4c870fa4f3e265e5ffde33378d4c4e3e4b70c68b9c581e548adac0a497ad3e0cfd07e72c5a20c0ff6253544a570cdb65dfaac0df69d7710700234c5940d953bc84ad41f7a6142ef1ebb37c025dd9ecf6a61425cdb34a3667c2ced06c0dc226bb43a7815a079caa0dacfce9c7e88df6e4c55f46d2bb71687a49418a9661534b7afe10d7f767c2fab5cc3890c88941c61de50e5550d4f27c084aa75b698dc45cfae43c12c4ce5fcaeb56e6da34ad1b61c4f22a9c91a452d174d240d8a52e346ba86a4db16ceecc6d339c83dc551c63d03ac50c9bbc40d907ee35dba1a208d71476c072265cab4d34a6697db0ebf01ea4f69d152ff02282dc340f252c5067054d8b99642048ec672fb4e4bf6240a736d89757569fd3e694cedea8eefb8f6b284aa482a2c5ea1d00000000000000000000000000000000000000000000000000000000231ff2bd76521251147acc8b898b5bca7fdf71b404423f284e51e708785f70293019045937097898cd23a89f6df62557340e778107d77aa11f22a905376c41a29db9b0d7b42b0c9c5870f6d9d927c32baa13509b8907e47adb6e79718d36e6f01312644ab586d754d6d6e1a6445267abcb21a9d24549dd25fe79af4535fa8248c1271600000000000000000000000000000000000000000000000000000000fa14b3fbfd4101ebba470ffaa34deaf30a9658dd643d425380bc1e4dbaa7e56f7924748431a86440485dc60be0a1c9ea308535ee6bb2cd8c70cfb950a2ab7008929e4c9c845a77c3da89f7c80df45fa72f40ffd32ce5a145b3e6652a9d98d4ad5c03c90571977bc5086fab8d88fb700e3788ac099381b590ddcccbbb8c2fd7a417d5284cd75cb963b168f3a33787c7b7a56ba021c4f09fcf21ce81a0834ccd2839e920003882e7dafd4170b12c6c0ca3747e54651cd336e8122d11640cf99e20d0928886a79cfb391ac295ce06fb8b7ebef3eb34f995380be42830297091255cfc0d37bf92faefc9ca61e1dbb7e85d37d190c86929459375fd9d4b8a5c3cb4a80e2ba5a815b07f6749052579fbd6fe597920814490091239677f9fbd8ce69e6352d9508be69758b310cc6024b45cf9d2b047b969295339c633dd9cf008e02966dcefa60f647293844ff91af801182ec639fcf3f41cc8fe887bcf61222c015e771b7d6c6bebe509a563c88a5f936960292dcfa603cdd428c7e1e97fd1939929ae7028f665d2aa55cef4596afae6419d5eb36654f793cdc3162a8cf9bfec8c7a9c9abe89215a78289e259c8250fac22db88e10643bba30065fd53bfd8617cefffddd6ed8a1fcb637f193f387c191bf2456fd6cda456b1c359f521d3a329be8e64a8fb6ae43bd1cc0883d5a18b07e999497cbca30ae93ef079e55f96c2d01480a3e513c1808674a110cffc6c143c6c6ddae11cfd8080b6e72b1ab01e476779b01fd72014bc379e636939751a8547d44e16a7344b57221e4e59477c8325b6b3201a7f02f4a9b5c1c280bfb0746f011d84c1ff9c79b9b791cca1f64e93986eb3aa42c81fb319ac173dba4bea727984c55251841466e5e757c67be24f623433f1a5784c3bd1240af7afdcd5dabfc5945e85c7e33c797746896ff56cf2ffb1daa689cc45dc093cd3cd16974a7702580d0fc57881fe24d837c28d9b2bcaccf417f938180d67e83dee41d9a4b42f828f53cd9313e8b8e75fcf64537cb4264c411b8043bd81316c5f883dad2fd38fe41c160efb8d30e71db64a311ad87c1730322f48a77d5bbe57416ac51bfd60c5bab3011018e6d25ed68f271fcfd73f4bd2be810c8e3da310f71192b65deda9d79b069168ffe05cf444f2dea1fe6cf4faef2c1d55a9a0998f4ddb6f5c9bb6cf1bbac59e7455649e0613459f4da3c5c5fab2b78a1b93c6f36dbd32c92c91104fc46c3dff48df58abc159639512c88be297b8b735d6153eefa8c85b34fb17d7622dd9e6578d4ad4fb80c616a02fd3201be2e969368307f65045c67e44ccc3ebb559892831e75cad0ba0e1d3ab1a02e4cba46cabcb94a8418c7cace3b5f5696923977e85b43daf8e5ac7849628b2d97abf5bad07b1e7a114cba65499e0cbfb7dbd50b14fbfc98c234ceaa28a27152fded1407e7cd99cad33cc298fb9d32f03af05749ce022d73cbc0cfdb1342ad19bef4e5d1f97a99ede2678812c93d773f62f9a81bebaf56b075f18b8a3a6b3c1b91c94233e102317a8c6c88b0833d1e852f5a8c8af1c86b887043ff8157ce76ddbcb1ca113d5c284e7894b27578c7490ff4f2baa51e35f6ff4873568e15a3106c33ad73dd586b4a12d812677cfec3b42df0e943cd085654cb031e588a50eabfbb945efc96152cbc8bea48255fc1596dfa7ed107107d07a608dfcd58f5be49d255523bb23bba79c22f582fdadd25134c56050ef730fd0c010c902d0afde16b125a722b5212b9337a413eadc157a2737330fa0a8565d7c1ede5c6502e4918414f80842e71a7a6048543a9e61e49b67d7de21333479fe43ef30843c28897d1d53948a5d92c87b2de62bb076147b4de04ede2f8669731116fe95b975e5bca64f032fa0627fb2cc3fba548f23247b4632f0d457961d982f5b8717b2150f0e9dadf0e8942ff8196d813490d28c0b28387507943753c7919c4cb3a4dabb5943bea03c844e010972bbbdf86f2db7579c2b2ab8788b614b17be6fb721978ffdd3f3a51811780162161614aa6351e7f1e890a7f13ef7dc28eb4cb25231b92a000cad8ef265577f48ed9be5ffd58486f0b0efff88115e23b2a5050a07b58676c115cabb15a2c103f5801a4c286bbcad5deb72ff2325e45add15edcf421b11ead72dd7e86981af5c0d37331483b69284344c43ccef6e120db1b47c5648d6175aba7fff3341ab364dfd109ace8bbd54448e424b8bb80a940dd1b8865428c23955cba9bee9ba83ab4cb067ac3d706d95eb36fb87e67c47444aa6cb76112bf213341ddc255acd11834672c8630daaa764ba9750832faba54daa93c20dcd3f188c3641d30f719bbf3d1883b4634d9e055e002e30df8f436e1480ac7fe3ce8a845a46414d09684023555e62f56f5d2aeeccc3af82ea4993c02d30fd1e7d5fa5bee40cde77b5d91b2e4d1641ece2c79e9629c13d90c7ae29fb57366ef1a8098ee92f6f515d3bd9f052e3b23aedcb79feeae5135129d88a29fa1338f5b73adb26bc5e1f5f5892e34fad015e54945c187fe6e3abcc3852dc42a599b527135ba4dda1776f05c5f3bae5773fc99b281ecd3b5ed92adbff9dc54e3853a172c745a99113812eae3bb9fef5014d3e25dc41005851edc093cad4ce886bea68004ceae5a6787e8cd81eb855888f72efb2c59c9f78210db7e0f130b3d7c5352549e0aaf4092cd174be428c78ba235f8dbb9cd9cf0b06f26fad9bab87dcd08aabdd40bd005f756218017e02cdb3e99df25ced8e60d7ba0af9bf039903134e0cb761be0fff9a8e80fac094612023fa0b001df37f1b867f0c97303b89d89ec9101740ed03ab27dd3874b8d251caa12331e1a84d935fc60490d51d1032766cd641cd50351e4f8a913dd4042db831181eb2338d99b19bdfb37e114e9c1e7a5c9fb62533f73aace0d2b6950ef0b36729ad3aa4cf6e916116de2b227187d8547ea666878e19b82076027cefda2e0671972854dc81b9854587bcd1dc7e8e6e6ece36a6a1f612d58a8542412204a09ca7b91e57e4ffbd886f4802fef20f531e4a99faaa01589bc4f7ff9755d3c6e8e838ae56c7eb01c52c418f9501a4596b6e219727fd0e955fa322a5b8f96786477a77e26adfaf664b380e0b62b12649ed4e7f343e7a53f5953734b2db89f3ff0480ead74fdf201a333fdec92e56685ac2531974e0c32f6b38ce525b01657fa77badc73932cd701efe8fecd96a6f90f1f738097abae2b681bc43a0daf92622e990e9424a36ae01ce280ff2f6da76d533f8968416c5357ad40cbdb39ee41d7081f2e755a2b6a7116a294cedea31d186f4dc0b40e9b383b9cdeaf99b7b26cc727b1496b56444fdd815115ce80604f22f881b68a6927bcf36f34557e99f7ad11fefc93b2cce465a63a15a4ded07faf9e351286b317bcbbb7b57b739c34c85237b054e3a423674e64203706fe1d24a9f3d071988b7b3ac847020352448817d7c4d90cd619b8d4fb8c025fe05104b746acaffcb96f0f85a9aaff62fc44cc9b811eea896a22d68bbbbf9e54221efdbd0a7408fc0487d13528eeb66bda0256b0ea15ece241693618daf3de2165d08376c51542453bae70e711b861327cb6fe5e05b606af2a2357e9c5aaf3319c51f87da4cd390cd9715ac09232d1009e3d070a1170993f0b41066c1be85e5a72a044bee1087218a3e740170dd0c3de5e6c6be127243ac490baac1e54476a6f622a80b7e7ddf89624ce4d589b76c66c8bd7ecd3a1a6add51b38d9f2ac2c2c348210719b2af5a521315d689b2e2b5464455c7e9aa528c0cf2d0a3ef337600d271adae8a5aaf1a856a7cca627c81408ca36323b4484aabbe0fcf6c716ccd1070a3a00399a2056f96a0058b4bcb3ec49d6c303ae96fc340c21e3bef62a1db8d77ca8012ee5b5bf96f9fa05eb08e8f5616b52406f3aa5895de4e2ac980b21cce62bedd6d3ed04cc46bc272988b9bb4d6750d914156aed123e08aed4a68df2077c6f8198143697fcc8e8ed79d63dd462d18d627124803041599e2833123b85cade4c1bad3503e9b6e791c0e5a8b26577d4fa748b4e51ae75b9e77ae7d17862b2e12ad3eba748d5cbdb0704a9caa6fb102c12a42e8ed2d02866459ee51daf7b439e6b13f41b92f305ed41319e9e33869fc7f1940ebd985f01ff330dd17a07bb1c84fed2b4d12ec630d9f460e6faf8a1e74e10aa9f2a400da251377968bad097897e5fcc847cda591b7fbdd93fd8377daf174ca0aab86ec900bc02d49d6e7ad08aca6c88454aa351c42b2790b28a50b1311079d11b4ba02f259902dde2aae253e93213b51a018c1580da57b0f49a111534df9219ab944ab36629231f6ebd5322684526d95ea1eb4d562916601b622171097cdceb43a839990803ae71517ac15150285e54c809b713720c4ed4de61a9427f4f4ff3a03486505278088291538ddfa8e792112a6e65f13c57ca7c7767825445f5c4d43a5aeac806b82bae6b61b9077a459c92e5341e1f172f86156d536662dfdc7ba2198675b1fcad23488cf16d32d06aef40b8ae280dfe7015df1f431befbe1c05e23344072789d61a12930e1c56d5d9eff7ff8783366e4abeed891cb95dda9c70a50a472145d7733514b9ae2ba8ac9a2cc482a4c96f8ffb54ea75916e87b1206209cb273df9819b2a5ad66553d9b5e5fb148957528809accefebe7115fdc5a9ad6e65af7b1c6aac46b5fe8c7ea585aebdae333eb9b18500c2f22e60ed67544e1bd30fe3",
+ "spend_index": [
+ 0,
+ 1,
+ 2131649645,
+ 4294967295
+ ],
+ "result": [
+ "33c4ca61245d3f6ca36c99250cd3dd0cd41727253d849c858da5ede5ecde4a67",
+ "90779500f5ce8db89a47c08c7a057517d6f62c814093153107a03d98b30c05c2",
+ "6b7033b441fafa098659364a02ac2e95cbbee6a8bbdaf5ca2991bb731765a54e",
+ "bdd72df524ab04c74d98acbc06ec195bf33bc4b93ddf74bb650a317717f73391"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": 485614025,
+ "scriptSigs": false
+ },
+ "hex_tx": "c9e1f11c00010948414d3e00000000000000000000000000000000000000000000000000000000e59e1ab8006cb08fcf73f1dc8200000000000000000000000000000000000000000000000000000000f1f6ce6d0097953b6a9fc38036000000000000000000000000000000000000000000000000000000007d1a45230031f6dc8c10dcbca800000000000000000000000000000000000000000000000000000000e31a9fae0065cefbeda6a6c30800000000000000000000000000000000000000000000000000000000c63fc07400097d994d032b7145000000000000000000000000000000000000000000000000000000002141dbb7002a68b86cabae3bc700000000000000000000000000000000000000000000000000000000a095934200235da408b25b2dfb00000000000000000000000000000000000000000000000000000000ac56b6a800e963231257a8f62400000000000000000000000000000000000000000000000000000000475e475600e2b549f601179a5db6314ea84bc865df5c0f6ac5eae793d0616fbc788219e8db4e5466b3db1f294fa29aee18da2c58e1dae9d4efa0c413ae6be6cd6f149d4a0a192bc213cfd6e3e56fc062ae231a497a940d6b3e165046fd39b129f478896ed9098df5036fa6f5dfa2af494d2cccfa14bd765aaac1b2ffcda4e686823586e5d9146af0aa81c1c61d46dd8ef11951516d957e841d8df0a7a537011ea5d2c0da275de77871b6921204b77215a9a7ed5232e5cbe6d2c4faec4f053d4839b8a84bbc02b0d3af82d46d6732eae896f7361a538717f4e8d77301267031b7effc2b58c3308b6c07d17b8d7b5f9d8f4fdd97d22b6fa13bedc72148d09e92384e2ac103c9fdd8287f24c8d8769f8ab7e78570a7303771be40b89ef19cab7419b5f67f2f31d4905e2140fd4346daff639d07ba1a730376dcf680ccd919cdb712190ad9a797519d4595eef77ad41f7129b577a174badeef18f6bad0e74b508eab661098e25c88eb6c3ee7de43aa205de5e3ae1ea914e13b5af00a29b9530dc2a4d7350957438411c6cb1d89a7ccc1f7797d450cbfe75476df523c14cd39020e84d8ef3116582e6786555c096e8c5e51f89daac206ed996f059f20037de043ce41e87fae26248d1ca0ecd53e8ec63cfdd7017b48051db5e7b9a5ba62f239b27794b4785103934e1e549d92801727ef659e0565278110d7ed2f974be8bcb91b4bcd6fb9c0423edab23f1252dee60ab55117942ab25c4228b0ae285188ab9a5947656f611a8e23ec3609cf6e1f3e1410af559839d6ac367e3eabf1828c86a6ca7a2eb9d8e7ddeeb2fa53ee197e8e0d35f998258053f17d6b478265842f583a5e8e05f11d4e20456b0c63056f8b7b43c6f3587850471dd7ab986b644dc7d99b1d3ab438673be36d2482cef1ece0dc3f167913d4a5b7f0a6a859b6cd70fc817849e06494a3878f812ff52099db85a0bebc8e86b0928628bcc0fd50ce1083ae2c669299551f9e6b953959d01262ff1bbe7e5f084a93950807fef84b0c450ebb5b8d889d4049be3140257d64e4be8f0d837e268093298d0bd0318b5a02bd5ff7fec1d30467609230dbf7df931ac8c80cf914785191f8395676fbcdc3f825c1d3e76e1559ec51afce8675a06f98a6fff56ac96c298deca324c40e60dbdac1ddbd91475ad9d4a48ebcc7508356e0cce22a37f25edb5217694dafa19a58b174f5f78b9b09ce2a6f45110b2ad518e9f4db533f4f492a6a01e14b5dffb188eb4c55518f07ddd1cf2eb2b83e854a897d30e4680e7b054a9476d5ef83052fa42adcc810acbc65cd6022fb6da2b84125fdac01a342a1dae23caaad4d16b3469f44e9a7b36f45a12e3411af6253a2b072912c899d363f2d9ae0f5e21ee8538298edb140f3cdd2593b8004de075afb13387b7d17320300d1c27d6c4ac8b8165bc2b6357b73169aaebe9a17820e991ba02340f388fc9fe622913183eb87e543004a1a67140892503b2ac532cd80b73521d85db5c582b97ff4a628f96627777b0d83b3b5ecc7f056e06db37d29efbba8de3f7569c55d79000aa24ff70858384db9d6e9eee1b02034dc0f5ab67888e5dc9d4de12f28049e79eb21613136c1fa69a09b9d74de7b94839a5ff916545318769be4180e5ff5c15766f29c552f181d88dbefddc5756d4ada904895b4e2cb9d7506165c40a6403e9f467ff22e98f11cd9097c83394e37090f3fe8ef0761bc9ca96bd1491f7886654e931ebffe8cd072b772369c3a7a37030c9a75fe950db98972920af52f6e119c477d58659f06e50c088f43218e34e5db754ddeff7789b7d955ac856645a445d2a19b4fdec8963ac9bbdc2af4e8aaf810eaaaf457e2a7caa6dd48e5a879457704a6967d7316791169598cfb3fcb258e3acf2e667c020b03126f3216a38bf20983d902f3accc14a73e48cd04fa304393a6d6ba343e96e6d4eeba2dc6ee41451570b1f78c1e70ee5b63115698f21f52fecb014ddd5acad48b3c71c7e1c73633a21ff89fa707e294a1094c0848da8662d18317fb7bf2f166e37d77073306e91158b161f840d2ab01c7f728f33890b329000a6829eb41311443c75e29d4bbf56fc5620a2d1cfdee67947ab3962423e00a60115e4af2ca2409cdffac3f5dc54ed09c5eff44e2860afbc0c2010f525e4071474ae65c075f5fb38725941cc99c1772ce3903b772a073e2436ac084fc0248f24b7e9bf1f6b12c316d0ef74ab4b3dbe410c00b42acf1e164feb59e28345e18e3406bd69ead142e75cf9a104295858a86b2caf14f4285e5a0fdda01618005338892559a941bbe08e44b7176ac88dbdfac6999dfc42287896d81f83f0550f1aad3db2c8e9ffcc4829a0e0f398d1b71498356e95e5941ff47f1e98775fa0dbba5392a3e85c4d187c8093580cfb671d3c3934c7c68479968c6d62ebe3d87867729cc6d9d57edd4c4da9ec3f62abc81423681f4a270b84985bb0d3a7a49532ccf5cf0d59d715945acba916c95389039d7c2efab83bd37bbcbce1b54cc39b11565b7a17334947e9c61efde89db023f9b23583371f6fa02d094ba8ee91426155c8651d22959d145ec9c77bf47a013e6497667fe9c2c12a667fb0b1b26ec18853a2a01a0d5c5251b4a0d1cb74d6f05423954872cceb8eee7ad47d802cd528eb0f1a4ad7ca489aa55ca7a676c9007c75162407640d4b2551503ea5c71ca58c600800c10c42128d24c25853077184f111ff3682578563f8b0c2a336644f2f1efbce8d2aeb15313f8ca7e92229cda2b5c628c3a0b3fd723647e816ff5787f43ee4c4c8afa0afaf15e45a71e3e9cc035e4398e8e7e25a5a9ef15aa1a5c8d54b2acf5db6f612afd773c156572bf2eaec9e7007c3bfd481508a35e950d596c266b836eacf4b2fdeb01efdcc3989ff3ac37eff5c0ccccae94c05eea3242b896f0a7037bca4682f56978175f2bf8dc7d6b1903374a28e71ca4702febbdfdf1015dab9d79165783a3324ad5a624a941ebd4e126e4909f35057cd46e3e2c2811e9d2925d27f9e4612e4c61853223e026d8f3398e5ff89d037f724d2908a7fac7c992980fb8716722e632ceaa451c141273625b761bce8add10eae32e310af7d05bab2552e70c5c9109273a3a2b4d408acdab7a68c9c00611e4616a29e80ecf6d3abaab07903570609dd943f8431f3701b3f5d65a957089335f73c7bf3338976337e804eff75f6fcca8679b6cfabedccd7d0201e292113d6fe20a8eadfbf23f56fbad98296879bc2083d1e6caf3faa26842605ab771251705e1263189dbc5b90c4b94b7ec1b7660e79882cf93fda08b62edea32947299b59ae61bd888d83559de50883c0e905cb8294500d60df4a613a62f34b00ca7069649a28ed88800e9cb148556fa28e45f50ee797da5b83afaad49e48449ab392875e4b6a80d2396a188c2a9bf47ff04dc7a05b604d5d044417fbe3de08f8b7048ac651c6acbd911036c16eed7baae9f5a6f19450b2b8f5f5b34b30a2ed28b6a1d51a89af31cba4d446a9ff18098dfb93a440a20d22cb06adb2916b2b8f79cff5fe916930b1ebdd42e12a3917b3fc7452af7c0d559bd00582851e3c34277c9bdcb50cc376ee6bec35f424aa2a9204f70b144edf20969a2cfcd209e2d7049ca419bbb0009a4c8d3ae67f795f7eb28d4bbb0303a7c4e71c9918f065468fb0cff6aa15ab497073b24b889680001fd1901894a4b3923c046b76fcd3d6acb61f8926c3c28b479b7c5386b017d8cdc6a4982d02a5b1a62e57bfe2bf15058cd9539146173bab291389f395e216e669d1831d6b0f70e7352573ce1166ed134b68253090d841d9503ff58d0d6d62bd9be62105a56a05738caed763f3066731ae907a033300e3da84c2c091bed0fbec57d034a0254627c52d9b8f28d87ddad29bf3ee2a709feaf4d914117629104bd0a60d7c34b91d52b0cbe008dc28d0fd3aedd81ea71fd8965c9be2e8bab0b015511671ad05e5bd8dc9c806a041018887dc0cf2c27ef80cf1aac1d1b345c1d8783e53702ca40d0328ee5f7b4118cc35a9608fb793d224495630c8fae050aa9fa4c6f25b367033d98714fa0e85a9155b084fc9fa7f6766713189f75dcb91246027fc00ac4644ed36c0cac7345bfb24f7462cf2f62fafece0ebfbe5a92ad3f2a7cb377e5bd64c5d785f7bb41447cfcbe163d0e79ba2ecf37f09c44209adda4fee988e56f0cfaa23191c0092c86393b044bf35c22857b69ff858a5b22aac5312c82f308debf2d5416014850d3302636feb72965d73c4c44d98ba2833bf5817e8321bd7d80dcd8762a5db570eb1e3168997f1d2a92554bfa3d8dd33d6111ce44eacaec37e1206b165c45d2e497e5c28b770181b52309a5a2ae28c0e19e33609b4a99c39239b80327ba0954d4a19a1c1325175f597e7ef5e4b4243d66e2b74e6438ac8db31d010903f131dfbfc0972bb0b4df68e4709eb0757072f4a7be1c6082cc91b85b411b20912d7245e7915767f7f0f0edf381de2ed411203cf323adfb5ef46f9abfefdcc70031f6f57cee8b6423c179286d16f72c69140adf47ecc8007e01fdae01bc9def0c121a1918904ad846f2db2dd97862b172e285cbe7018ac93cc5347a63bf8bf1a18cf43896a2c0c32b9eb96508dd4e52afca94e2d4949e238cb913de37fbfc8757de6d7f1622e1f80a9fab03de82f5201269c234e43f7e7c77e2fafa82196a5cf93700081a5629d1c1591aaf0dcc533e7aad89f11e195ae106d9164d83bc117d330b0625ae7ab914cba3f5e9efa4f0cad23f6b96af65834973e023387e1d5168dd25e42c20efaf1fe6f6540c04c698be4a372e26aae68e57b264aa8b21e35e124c89e72481a32bd69e298386d8dbd2f837ed5b325a6dcf245049bfb304fb580eb9ed2c0e12a70610676741389a241b0cfb07a2df412d5b124b7dab5381805f0c3822cbd4554cbccb27c2e42f8275e3636c0629494c5f592f256e3c026a193c3bdff6b78c5aa503dfe2e15561f0c06292e1e3b176e4b581972c957d2451aa8407a6566b4af1e4799d9b8a83de5041619cf662bfd50e7a36ba531a48d190bb2fe007b93d5de397fcaf2e6164480d3bd6577d4b6a63be31b3e0be6eb785a00648ec9deed2d1e7ede249ad0eb2d6635b507feca5e54be1786a04eb882197d71c38c0d11317526d8220047e27b8000005e515bd",
+ "spend_index": [
+ 0,
+ 1,
+ 2773995730,
+ 4294967295
+ ],
+ "result": [
+ "17a26c6ac5835fea6a4d6768276d43c6d364e7d4f8640d81d9b75ef1a1f38919",
+ "9c69c5727e1b331a00f51c90399781644cdac61b5e6e50468364558f29f922f2",
+ "70ba670c7645b244ac7116bfac53c066f9aa483f5805181e601b3a0453e6c506",
+ "3063e65347d8252812789922643a202cb5851f8de9506b1fd6b22feb389edb75"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 7,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": 879929405,
+ "scriptSigs": true
+ },
+ "hex_tx": "3da87234000107e3d9f699000000000000000000000000000000000000000000000000000000000e02a8e129f17bbd3a719e5c419f786ad2cb5934b82905ee6d9773b0a2c224c9e61b43ced03d3f387560038684aed8dbc02b8d7e12960000000000000000000000000000000000000000000000000000000050e6e834156282c8744573de6a676668c7d6cf7deeed37cdc6df31d0964d339f715c00000000000000000000000000000000000000000000000000000000066de206008ae386ae69c9456c00000000000000000000000000000000000000000000000000000000a4e18cd8aaa758a30ff2ceef19b9fca18f10f62ea82e3b20af78e1406107eaa1eb772f4c1e92809bc9a0c10ebfe2dd6ab865d81936b53cc74d00ea45139f61d1057d3e8dde146a1a4f9b4dbbf5fc794e43ec5db10abf1d8ce61abf55e3eb5b3d9c1e48aae2a8791cd00e36c44e36d2a7292d79d2c6846d4d68d326dca8ea48675a7a4072621357ffcd99bb738b16a4ec35d8309e2c3b52393801c9396032a8e7a18705356a44372fbbd014d1aab2f255ec7b5712e2281b000000000000000000000000000000000000000000000000000000003d0b52060024eff817d8b6370800000000000000000000000000000000000000000000000000000000146f8940fd09017154e0794010287c09ea7938690c178360b6fc93b4e491958a1f54135372238c5afe7d176efcd03ba54df6ca8b09a675d776975d060899c8764216c8a10b7687b368c3e05608800c12d8e69a26262a1a9ac5a975cbcd0f399ebbd649bcb0352e2e45390d2e653eaa5d4fcba293df4107f0d994b7cb28517e8937cd728697a7f1960d408f1030a02001d7abf627634eb02d28b91f5fc6053f937e5ff9d520d9cc90fa669ed70e308560abe1463127e47f2c00d42a5e5a9129e5e70761ccc83908be832b4c4087e3cbb8e81c5e6b8f41816055c2e857db3e5ef3339e03df7b29ef4593cbed65d6b386844de7884fdc01126b1a2ffecda1905c827140f566c5fa97533a6b7fac4712e6d27840f83247dca51100000000000000000000000000000000000000000000000000000000e033ae24fd5801a6c7e03f06d046f97b11ffbe34f85874413f50c63972e2ec801988a6586084d9345ecb81b2e539d96fd52f52395d6e52dd0f1a958362f7311280c8eb6475b74b1381a3fc3b8c7be041c01517e5c1e9c55d10b46033670794e09ecdf1d22b256ffb5b949dd130d680dc2bebf175b3382b97884fa21a1cecd329361ea6850537f5a40463dd36ef90985f1f0d73fa53a84dc48ffeecefafb64f7ba63b8d10e3030a6a1e7ca3ad386d88435f236a5e0669b64c045ea22472dc2ca1fe2d6345aa26c3723952181538b3c9f4f821ad14669035168ec12a6349a25a5caab4056ff3a12651ac3612e1a7accfe16ce6f8a4633ed214145dc0a1ea425d2b57f0c7af659fbd47093e065cfcddb2646cb4396496026832448f9eb20ddc25025a1b24eacec73a56bf8d953bef2a4feb6ec7005d9557be1c9bb1ba9f2f7782bd2162fe9011a37cf058edb76796fe293eea928c207ef3962d2e5a6e1182156885b2e4e50199a51e28b8f42f38c8dcf65496688bfabab447460b3b8c03605e1caed09ec1933b59d7e80d55d7d375614a5d809082b5506072df28ebeff035c7b4e443fcb6aea5238fac882999851e13322a80b56333c13aee8d46e659751a435de60191d7ff6a84fa3b4b99ea066c9ed7a4c31fef447b22a6f4f946038bee9e64dad2a3721780d452bda78ef82864afa74c6b57068df83ea06c64b0cd56d7ea842815a989e166c6c9101ce812c1fc3c4cbdeb217d59ac4dff2a84f3a6b7e183e6ebcc04d6f0d918be5702b73a14874426ab353c489f9903fda301c3cc7978357621e503e46fa82a2ebbd557f2dc43d40cc5edb212242356bb089ffd837c09958970c8beefd7c9055540423cf13398353ec1190495b0ec26a64bc690082914f40c508754a281337ccd04bbaadbd179cfcd093cb8163d7c542b4dd5aacfe07761444261ebc67e612fb11ec447c031a06513362de39c2e020e8ec2bc2f4bb9f92b4ae1a1b89d109cb2ab034b177f07840139f2f39dbbc2614559cbfcffcd9153bcfff7df2dc946036c6562dda1dd0ec183235e49dfa049161c5b723a82594bde07681443cb9301a9dbde4775fc7a8df326be0b0119e7bfb97c68b325d15f5cece4169ec52e0ec0def4f0ebb2dd944fc8d267209d4dfd92d07917e0ec0e4a82094be02f8ce71a756b3ff6b90233273198b397a2a5ead5d9a7389bfca6d8d577e2bd0b1b62d719c296f793c2edb25a478eb36ee82f0ce0061145ad555258be0e582dbaad2017f31b4f705534cb874fd75d435acd33773d1f72e58d64d6901f8377db26b5625b8db4d0ea2728e47934e1506069211433df2124411bba5aefd45d6d5f1089a5117a5d7c86eedd6ccf50dc38a61d1c6c754f66d7319bae4af68ff54f5774260f059631263b80719326596d080a389a4ced0b056e34b4bf1a1adc582a925e36b35095022fe1f34afb3683e7b47e22c9c7f1a9a5a1b7a5a3d0080f3ee66e4e3050177f1ae9fb2402f62c665544cb32909fe85dcdfac66ffd8f5dc28c2869aaf0c2130be293a13b73414ceae0805d37ce49961084d34626ab8fc8fd57edf9cec217d2f5c25949b13540c60c27434118b4220437bf7d40d1baa11ba9533b04641d7742a175536bd7ddb66961a4043a9f05c61485c0141bd38a5db5e20d923347552c0c750bbc72efbefa53fded013057c3861415e4b829aa3fda0d7bd6db680c796d4802379b1f07a831ddf87beb1c0626c97109f3704d451d10980aed9daba4908fe96281e22860b6030ddb3b10c4445e325b92c28b75900dc5e4b1a62992db85e91f2c9443e23c9029af2994787ec03faae38d49c525885e8183fa09e1012464e8c4faec0890d7de43b0432b417c92fa9788fc54842d16af13be204704eac6064fc6bc41aacb05a8f2cd7104bd3f779ddad20ac77c8cb47eca14be27c25e94d9704b527762a126f5fd91626391ecac9a7cf74437ed1f99d12d6e47e1af0a6cbdcae2c5a771e1a24809a981a51de6f1ed9d3b623a48cd4b11c8629b256815b754b193de7a19ca01897771aa3c84fe150cf2dbac86b78a3af53ad743e23d1d5d58a5b7eae918b28de940ca4566b591e3c3052880c1c9ebf603058f8e7a82e3bee91c47032d04fe0817a50f7fbfd5989410dff894cf9b60189bc397b1c6f4a48b144233c6d2c8eb0210b8c53a2700280365dfedc4674e6779c5f2a2a0b68df2a4b25b4ce3f85e5fd94ae8e355d456ac8c076c9bef88fe7c67e409c038cb6e91f8c1f3570c16a1c1a0d0d1fa0916d07cad7ba438e944c19b3f378a6f76f912153c65055d9a68284b2f6085225b3f214d7da32dc3b2c13aaa0669c0be90a5d3e8d48a0188f6fea28e391d8317e824e631482208d8be7cf7b18c193bc22bf118746418906fa4e23a2d0bb7b388c89583c0356a5719b0abea895fcda3f499f8791a9bdb60c77d3c0e4dfdc50156f33279ecfa8b078776c7008c26162ced7244a31b08a5b371c2e2b6c5fb08bfd64052a447286984eff0672c191af0e357bbfcd8a91c6e9062b3095995ef09695dbc9a4a7fa79945b0c935a0ddecaa290e0c31ad46ca7c9aa27a91df67d37a0684cf6c8ae4716ca413b2c584033cf2aa1609ff3a57987e690fdd3d480d765779ebb9794d46a415f288fc2d52c6dd584cc265b746c60170bed30c33deb13a58118042e84263238f0e5076f7665d288fcfc14fddf06310d3447cb96ba1dc19f9ec8f63a258ef76b8ff6e9787792127fce45a78e9bbf042c55a2c7d0e2167dac6ebb218f7844b2c9aed41708c8c478b0efc4936460bfab33761d4c2c4f7beda53477304d7e0d7ec0cf521871adb9cdd436b9457ca7856659ffe869a6338a72650cef63860880d731a0d3ed51a6ff7f1d6643d8da98b16713c7012badce39e2aa0f5d19eb86b0eddfd81c39974788c95abd732ef93d3ce7e533dce0d25584d663314176875d1e0642e4858c19df642d2866b92e40e683727a14de01775dee9392fc12e52f8e1933ce98762e8371958c61cfff86523161c6db101e9136782da819502567fb8668ed6ae4a4b3c00eee9d75a710add723458e9cd660bd7467db8570e21b3e295a69f02fddf0120b2a480076d8ca3273de406cc7229525423c9ee14db0e2a5687f5d93d32c32717754e7d97fc553b0759f77d7efeffb969dfe0fb539773e3b8b2f1108e0bfe506415bcbeefe5a66548547e4982c4422b3cb45d17a6c928a82aff83361f78563fd27bb68bd1a6bf4ac80c4b455ca5bb28b07b52b92f398a693d9b0faaa91a43b7016df645421d50c863f3d284a5ea75f262fd958db498848160bb5776e72b1365fb25568c497b4554ef56fa153851517c328b8db1648074cc8b9369dc46f6e943e229fbe80c51820abae660c8109e6ec19da4cf61510208a7082782da275e0d5a54cacac70feef115d0f21947a6f672e8b992cf0977c2f561d1fa8ef9be6f9619ea8f603cefe04f53ee88a1ac46b1006c7c589d46c2faa71e4098fbbee407646fb4cf7b148ae107a872afb8532ad7b64c0cfb0a7770b4ceba4c201174b11516a7bf6fa051b331ea6aa928f0ade68cd5fb530a3d8c456f4f636266040e0877622ba9bffc13046d82dd158d5da579b964c73e9789f10ca9f63141a48453a61a454086a3d94a41b8c78410b13ec39e73330e6df0476caf5f0f5591fea5689898849a677440e3ab812b640fb103349abfec5e7d96f04dd5f2cae03d9bf927a2ec0477e293794fdc92ab43c620bddae7a44f2e90d33b0257a5cef70993a3b5ee2674fd51012f9d4c699cd9203ae3413599a60a3d13be84c07ea13c7bc9fc86b549efe917a0503df95aee8b6f8c769bdf671505113bee89f968da307658417f90a36a81eb36026ad3aeaee5309a05edc8519a21a8c8b88fe8d9b5da019a299b63e6a09be76c987616378151f249fecbdd1cfb237a8dee3bd8ce6b0f8de13d48f499d2dbc9aec4a5a38666b475034626fd9dc103c5952ecd1a54365304e3a4078246c723b72f8c9aadd4cff9267ab74c35412a005e42424aa2c77fb4ca11289f95b44541d9e29692b9d3934f902efe12d4e6f7446043f98b159293c8e120d7c1d2dff9b13764af85381952e172727adbc3fac1feedee324b79e503d3217eef8b47a2e4ac29c7e5b51fbf4759d6c84e8220b649590970d69b222d71f4a29cbd62bfd31110fa88932392a6f6407da69f88e16587a4f9485a2f982db8d21861454c1eabfc0b57e6f37f470adf005232fe5ea38bf7870a6dd302fd2e01218f2eb08ae0314cebd3ab6f1ca408dd789bb68c4fcfbbd003f22e7f1f0a56de9c0257214559b944ed7bd6ae7e77ac4b2456fe28179f38fe65eabd55b5ac6bb0c5dd7a9df2b7df7957b9e238d5bced728d294edad1fbbd9ef6cb3d6e8573469b0c5f393f262524e45365bade9e016c27f33d06fec702e9aeaf350b34dad52a4cb8a58af6079857c692f89d49699cc6527adeeb2ce92b290d8404e175b3d682e80b6a7311aed857dc0bf1f34aefd63304718e36af6e56a5eb420f2953d74be7bad471a979a43728584c2f1451cd210b72bd0c33ba904789fbdb6a26354a5558a1a5b5e532b5b2fbcc14a973bc8dc3d4de45c0bba21d578423fcf78e15fb11b20918502f053ad3c7edb7221cddce74b4216f2aca51245ec87c3575a6dd07f39c5d3ef715f0599bc72a756ae9653eb311a7b80ba9876b39ef4a4c168372ae5c616701fdeb01c8e175b9c8f8df7855306c601dea40508e31f9222106b54a071ff601e88c5c237554b1f5d94474ad30af8f31d53d15c1fdb291f82060e0800957422aa0a38482c06da373a2e6f3110c0937ad4686746d8c5615575c3c6a82fb8e7a2066b561828c197d6bef8e1416205553c3057c1a3eccce56f5b265f325ce04b3a39fdae44131b427048b5e92b4af3d7f84e0e4ec67cfa9b7b0fb5e16eddd96af14398a8d034ca87d38e33bc73b47fec0be48f64240d08f409cb005e9b2c99b3964f6cf3d0b223812c881f3393599df843c2ee7cef58f5bb8e621c365f6d471ab896ce890a4f9a9b2b1fc08db1565925c5aadb9978a4324122437fc96240ee138d1285b8a72866e9cecf3a3cd845f898c0d064f107735ba909f6943a89c3b347bb6c6246c7793994551d1017e9f81bc336a74536fc85f0aa37115aeb89edc84c2e19685d7339c21b194bab71e60301f0c84bfaf22ce591a1c29e75bce5a881b196ff456aaaba13b1a6e3a3374ec3dabcbaa5f1069557b0f45499d069ad72f9eaa944b9c2697ae39c8f086f68a64e38edf53b142d4700c5ef9d8362261c69ae7f1432321c6f6ffaf5571f009f7e76ad7056dc9468e971c96d300bc758c53d888f6e3ccd7ea3d807bc32f5a75c1d5b86fa4ae2a57bd06c60283d707a193975a57dca75d94a1bfe489be6c04e637bff5ddc10000666cc47d",
+ "spend_index": [
+ 0,
+ 1,
+ 418482803,
+ 4294967295
+ ],
+ "result": [
+ "ba26e6ce9adf5b16d19356d501b84d5abb001097bb87bd903cfe0ae1d97cbe82",
+ "cdb2989c82559c31ee7e9b6efd00d87c51cb67efcc371e2a8839a5f9502c0fef",
+ "8afa6f573ea8e5ca2aed628fb6cc8f58e730f7179d382bb7f4311f0f205e38e5",
+ "034eeec69918a72106275f882d5d75cb3ee4d62cb8b302ae70e7178eabf14a1e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 7,
+ "Outputs": 10,
+ "Witness": true,
+ "Version": -709681065,
+ "scriptSigs": false
+ },
+ "hex_tx": "5720b3d50001075daf918f000000000000000000000000000000000000000000000000000000007da23531008a997eff90dece7500000000000000000000000000000000000000000000000000000000538f2e410073621f9515f3f0ea000000000000000000000000000000000000000000000000000000009d57505300e4d08d893086ce3100000000000000000000000000000000000000000000000000000000342e363a00913892234ff4855800000000000000000000000000000000000000000000000000000000d9606d2100c8886846a67bdd8e00000000000000000000000000000000000000000000000000000000396bf93600f6c564ae62a21338000000000000000000000000000000000000000000000000000000003175be2e003a75017e0aee23b71d09d01235c865b262c5ae164cab8ab974a731b034427f663ca7441d234e0d2f3395c8cd606f698096c03e6e7f16aa89cb2ca5defce9cb543ab636ce563fc76efbe4abd1fda808d607eea2229b3e5846ddce5234a4d098836ad5a0e1e385d83d5c093fc8762d99aae65acf2140509bf0b7ad5fe0d7518db59e12dbb02a815e9f39193abd9d2f90cfb24e989181eed2846ce3c443374d2c869b33c4c551dc76d5cf9163649d0ff11f0f307486e72a62d848bc8e7774f55addfeb573df387199390e0b17233d2d4c8fb52f6664d80a8c4d6d134f581e01c830425a7d6b904744a85df661535c10181e8a20f49789c674666627e4845a99e9b21ceae2f5fe70f6fd9d3b5414f5890debb6a567d8ff342e948a116db25463becd0f5d8bba1628cd629ad348aa64c88a98a38530e9b21c2725fe7bd303a1aae9dfc662326b9ebc416262b6bac942b9b5329626c16dfe2cbe94f72361b741089f3fd21203f093bbe4b04bc3fd88022db2339267d467ae6168d81c42f3e9f44074809bae6f7360ebe955473a557bd137ea22c357e25b2189726a5733aa13623e216b1194fcf2c13843769f42703f01ea54c86c66abc870200268b937e5a4e2d1b26c3b81d83ff702fcf271e2bc33f27b4b6dae4c9c14ae8e9231b7cd0c7275ac61d98e00a53820a4535fb4ed6b3c143d501542d5ba0678b70782aee279f4d5a1d8e72994df5637634f6af86d7c63f47b86ab4e0297577ad2a3092f0319d9b11779a22c1080fe34254f4459a73683ade01f149c3501253d63d8374670a74da878b372e9c3ab82a52c8ab3d8e7aaf0729ec8db4fb0edcf39c057b22ee92e30b814a5673ce84acf82393f4b6869a6a746834d118d96af4e47cc0752da70c687e65ee94fc8cf5317206c7db7f91638c9b040137e6023b74f68b8126952b28c14e4b538fca65fc6b1739776d57d47086bda8dab6565ca1547e4d18f524f3b204064d7cfc19b56059fa101ba16d3969f9384b252f5620ec5c18c934a3b23b8bc3b9928e6e782e045bedaa8021586f13fc37fc5afefa013fcc4ae8d80727e82259ba2cce5cae5f05d725732d16479b95fcb2bb93288263079fe943985837f4fab845d1ffe45cfac9ac38480dd1ba834780c27839ee6c0187277e0b621d609dc0416f1707385e3fbb68b2eabe5774aa6c320e60438da07c8e1ee0132659ec1f972ebdb16bd3484d220661a09487b9c03c480052cdba71bfb1994931a6c2db1502e18e0b8e9981ece76095fd881aac299d74a48b0aff91eddebf7f98a438842e5142d4724905a47968509591bd5a003448e5e3ab3e1cede5fb0c40e305c29e44cfe6f417d128054d34444eac07f5bc4f408fdb66cde818774107852e9bad1bb19f78522ef925d42baeaeedc9b26483063c6d6274dfc16987bf0a32348588a6d45632797851b4fcdd5ece841bca13680d1b422c3f82fe909d9c5878032f976ba802176803cb6792568c82e8403ec60d535ee113d1d888ad3101ebb786dd30ca50bc8e3020c4a4bf1827f8253cab95d1a6a23b3ffd6862e6715626010d1db514213db2f87d5b6172cd804ee9d1873602b023174c9b4f9066ae77fbcc506d83e9bd2c39a55cc8f19956d54f05b88ff5b8bb707e829cd8f8b085a485fe49acfc7939ceda32f8ade36341a9e98ef5309515dbe57b9b3a4aff3d65558132bca792f626684c82764f6cf730e265551d737f531295713f4221ef5c70927be9fce1ac39e93bd30ed1c2e19e9f474b5cce0771b464795d21b59cea8caa60fc8bf9391ac806671d443cdcf6e5e07eceb79e0fb4f0b89f654afe3a0d59acf673ed00a641c600086992d1ba6cb7174e8cca3f1976c7dfadadc5ba544851e844e030968a67bcdab64f5753d2085171d96e03bb4529aca0ac41079a81987001b59a564542afc0f5183c30d2f14e6d8c6213bca6d649856fd6400368d3386db1540198d74445e08acf8838bb7d6e05e8dd7385a83a7fa0809a1d715b8aa324b1438a7f649c48ba08787ea039bc513d75be634ac3ff1da177b8438afd7191b64f5c7414d2053531a6c98da8d203ba2ba25e64ac8a088c8688b78d1eafa977e80f021e86aee9c3f9514357888748887d16021068bebee1ae4e086a1c6c6b2ad8969ef2f091c737307011c5779f9722c4a8a2c0ed6b0b232f7412f296cf1099e8468879e822431fdc203c7e3e6248b0c45f674832e2ff53b9976e3b6fa1576050de3adc0baf1adfa9fb42557c574aae18fcb7b9e7ceac1bcc370771da3017bb7568df624f2552478607aa71a2ed66592db423145ccd1037acd9155aa4cc4de1db42264602606cf8d6cb76c32ea9d973ceab578479e1cb686d2dfaeb703a857420670bc5f0fc8d118dbd528786ac4d2141a231385f02cfc7693c370ab4d2c9a62bbd3187a425d135013a0171fcec67e8ecc5c393db8b8a08518240c5ae30fa6eb7890a84448ec714c4e6f148d9b62ea48abff19e039499ed2c90fc775062ef829367c3a1ee0ccd11697fade32ea84c318d9dbab2c94a28e57a04e01dac1a34391d8eca56baf60484724a6d41497f926b0c43003a85398941b8d97e95187c0cf667349cc75b04bae8d458da31381c709b7f343ab9c654cbda6478b0a0e1a71cc376da34fdd62d2e9d4625aadb0062d64c0b1a493057c4cc8a92ed4b0ff0d28793a6ccd4b3035d235d878a45d66b1448182cc44308213f0382f1e551ed559b15c5cbcd1d559432a7c2d6be60a1bdad2baaa1fd89a50d80f2155ba511037f29eae8a7d611423f9304e846af72bc3ec666dd1abdb8790592bae33c6b86150c9afa44accc72a476a390b14a59bd5de1d00a6b755096d131f6ffb17b4c276c32c2cfe59805f64b5afaa4793aba92001d970f5a155bfe97be3ea4a616227cc1481552f6f509d2f0a55dbb26cb47a7982dfa53b74ab328bf6def73ff01196b0023caf5d03ad941e2eaa3c07e5b578c2fc3d375ac33137a51997084f584c99fe97d4db97bc6b51fed7bc85a4c8cd447f19fb07f5099b7e24f8b9d2cc47000df906b0d62825743d0f077425ac885ce6773d3a87192237c50392688592027a7269e1cdd7c06c03920577e3e846e07ebc4c080f1b26a2bc83325c2bbb066f6050465178cd481b65f7e36e15f4bcfaf0fd1925d238a1c80ee2f689537b09128cd0f6eef9ba1ebd04b3af97cc133f9844baeafae1153a3e0aac978b23a528aa80d87239bf5efaa4caf1019424e928c45debe598ead7b769e062a52aae2a33c82a1afd1c08818935d1df635085937dd4a7fd0101fb14f58825e93873b9ff6cc58cacf3639fcfe0b08a2bd6709d58c03ff31486100ba6bcae81c64e9c660f613bf5cdefeeb1cc66983417462347050d6641e4dd83ff4eb40330b47a2eb58da9c4081e899a29806d25f0c1e9078508d625ecd5cd9d7678040a74072d48162f6ee8e984decd76173a3e73421ea3c2341e20fb62d7f1ecad494d041e0200eacd1a16f863ed3ea103280f9d8a0c0c007e397dd3feb8416d2f15fc40a59bbb1ea3c25ea641e6cf7da7ab3b15db3ef5c93015fe85604fe97e1cc19aaabc48ac4324893b70e2c7dc23803f03412ce6a995e149efc2af6f45816fbc18b3cea8039a433b0b4ca44c9870192171065f061d8a23edc994a3c190a00001fd2701742e4c31fbe9a6a948b3bb7dc501bfb242936b05cf023e2cc8737f90a2d7cfdc7ecd08174a286ebdf7db56b3886466ba473d1a8eb5712fb0bf8dae86958bde69b0efe02ec7fa8fd5b57eade65d944acf4e2c74551a12feaec6476ef415c3d48b464782136d13f42b390bea3f9dacc1c79def8b59f1b7a268b4ea604c0ce0dadc060e62ca6245a893e51c7b119b215e3ff31407482dc77e8a552841b16b37a0d91aa7d431f7a577d5e26bcbeb4c3ffb08ee83b2ceff8d200cca56e1cdcb4f4530054dbaa21d962852d1f1834774e82b287f365bddf56f1a23467aabc04c38c3f0180326cf544b7a2942594c204430d2918e2c383b54f306cd96525e5c613b67f1997c941f4b2b1cf5884b847c9542625b48aba16ff78abbf8fc01faaea6bfab8e75dce0047d3a5704fd6f01f3d69bf4d07de4ab6ce0c1fa299b50cc19d285dac8e5ffd86742d07119b3a52f3de835b0d9ba6ac11f7c3afab482024f476807dddc8e4eaf4f0cc8e959df06bddfcb51ebe2976066ce49067ae36249c1734d43583d4c2cee3514cd2285f794d7aba35f6ed44142da7a4b03d35bd479113d300db9a9eb78c596c021bf8d706e19e3a617ca14f897f1e3fc1f92032b872186aa876fab36c32038e6ea5a418f92d556ee7925a08b94a17cc5042fde4f1cd9c1fcc6a96fd88b84ee4a5855521c1e4480dd156a7cb86f5b8d78710d6c09c7b45e8fe99268a1ba97ccf6e337d18ade3f3a47159e3a959c6f3f9afe3d42ce210d703ddf7f12f03919e1b9d8396fa55f88b02a6cbecf8b7c39c991dc7769aa8e287725199ebbbb5d2b6d72b5910c719313826940b2b65212b89d40af36ced7ea0f1a26468c88f9cb9488fcc2ecb26d9433f4cf40d892d7118f534c1f3b4bc599dd4d8acac3bf315c2ed96c25c7b1c27f43e345f0c34133763ca673e94b4a06bb7cac555007eb8cb0065b64338430cb7abd09103be12487192489da6a656d96cd43b28e714a74967b9c6bb40b8ee39d3571aad5dab251f2e5750fd2a4bd768a0d3667f8764fce5ed82971812129f0d330b2b7b22622baf525cbafee81d309f95a95b8c5e61faea5933a810d6681294bc7ea6f879cfd026b5e172ba905ddfd940115a8a51ac2fcc8b256b9608da1132367521d508fd7565978b5886bf547bcb61ca2ef122508afd507ab19c28f6b927e1925d522c6ad01191588442f94573a80ec45c5f6e81303982e0ad5c8c20de87fd0035df40d5e2331d32d85253e9e1cfe0717d2f56e20625620a13a961fbdc6237fc3ca09faa939201b077955a9286d8c6607638f65724e3b37c60a0e4ef7623b0e7705577af8fd40def56a8fce3182fd3765adcd586f5b75963878d89b20d738a5962b3cd4e2a23739a5b89dfb26d9422c414c963c67fb8c9aae70ef5a5435575fa94848ec7efb742c2f7d25aedf2d143443a4da032697b55f5ba87f50e78168445ad8e1772f28c3f14f9a571b0d7275079ad8432d937384123fa39872c88d1a8f6b205b8cb47f305bddce550ee93fdc48fad3f18cd6d8561a1cfef9c7410dbf1ff254641aafd01ee09b1e69dfda4196d7285a4e3a8809cd498603201bb10b6bd640d307f1dda6c182d574d7dcb8dcc29094406245809340bd95d4d223f9910f8e0d9287585800a21f0664f19a10be0f0b987513d65fb2b088a0376fb4ffea57be528d34ac405e3699d7ea9e7383f03246137e35ebe578efbe9f939e850fa65c3c8b36de6233bde8844966f760d3ab8be961d7d5e92fdef2ff705e0498e2265a7a0efcd07b3c0003fd18016fb0cf85737d24ff5700d01ef9140a3bbde60127a020e1f87692969c5161e51daa74206dacdec9ba638f423d442fd7352527cd03696fa3da7d41f9c1cb620d1e6c82d72d9d07877781b671e7cd39caf63277e2869bdf0735a9170c8ce15c9474345a1a513aa204817d3f62663fc83da84ec7ef07fdaaaad7656da3d7ac4b58bee10d3d5b813be5c95a482811fceb6867ae4e518664ba3439a647ee02e8580bc178c096e93c02505bc8a43f4ff6d1e133e7f4c7110ec938d77cca6240fe97b74064824813de55cfd6bae2fa05005320093312bebceaf4ca3fe609e9f5c8a041c231b0ecfdd5b12c76cac786e8b3984932d225ece946d4a3ce2512c4646965ba54d59c162ae71383341a81c0b1591339cc8907208c0cf9d1e7fd540103990555004ed328fa827e4b3a3e14a3d1090e36fb54e7606d0645f148f6adf0fba1dc44587f2572d3307c23696ea2f189f1aa54c49e2e74d1827aa1f2b5cbc676bbff2a69754b0c6be65e9caa98275879a5a421996b212f9660cff59357af5082c7226c3ad864bde65f1907f3f0abb7a1000c3a9da4d2326e3f41920d21d5ddd22f5b04b3b45a8012b95379eb1e68d376cb182512a4af8b0b716a98f7a760b50eb3b53b30e17a9661603f6bfb52bb438d162b5a2aeb26dcebbc7182985d182b0dfc1835a4ffee8fb18bb767ab2cb07b159a333652ef15df7ddd96d22d2d246cb1d8fcb1f67976df9f6416a92098338e9173a1744bd40efe60357c8d0a742ed2c87dad4753b99decd40667f9893644e6956de0ae02d97a75fb3ae2f664eb7f6f4af284939fd7b7fc4c588e624cab5f5bada9d5057986fdfa95431fa6906beb3821dd7e4bbe53b880d134c273d44e0de2cb151ec4fdac01ab4213f9e9a33d8967e7bbc6545fc623dc72f5c8d88c99a937f5333a71d0a3e4c29e2feae67c68801f215077af579cf47691b608819504b355a26adea026a6dad328f860fd6dccedd1b555324d2eb0e4517d90ae9cd2fd26cc9a4f9b3385b0624cd5bc92fe68506212561998b883948626879da18c1066a502c089dd097be8c71923d5e3d064fc588464c66e19a7be6f460056225c91fdc1ccef65e86b1c016434b6474f30aac1df6c443a7e32ce84d7b6fb54bcf8bf29cfc3c24d771eae136ee072ceb69de5f36c0d48cda9d91d853aa7c1566c77650cef0094b613d97aed46a6111e9f76ed8f983ee80d607fef12964b2f8063ebd13d5084d53b6c2b962a7733718b093906e223982d4f374d806302124778b86678779d8f7f9c73a009cb1a6577bbbbbcd299ea048e6badf2e40ff40e66b6972cb01ca874155e46095e2c5d950ed233f8a7f04fd79abff2405d0b5aa0cfc0674e0ede98a2de90e88b1c2843dd07cd06406edf0a562fc81aa817ec208fe75dba448287affe48f3422b5a3f482401b9a43740df1dc7fe341e3e68a4d281237a351abde1d38990032c439b43e38d1659c0a19f83668819dac300b20727bc",
+ "spend_index": [
+ 0,
+ 1,
+ 960680172,
+ 4294967295
+ ],
+ "result": [
+ "9bf8dcd115918c86a90e3b1606b7554a0aed8a8b4ade64fbcf71bb7fc62f155a",
+ "653676421c9f3c636ee50a1ffa8b0d78e59171b87248f1424ed423accc5f08ae",
+ "17b38e8a8c1ef172a80aac99196bc991871c8bba4849b9ce8f76495d2a095bc8",
+ "d15e7d2504f6742cc4b97bb65a6cb63978ff211b4bea201fc241a1460af2c407"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 3,
+ "Witness": true,
+ "Version": -1391982199,
+ "scriptSigs": true
+ },
+ "hex_tx": "890908ad00010a6a475f400000000000000000000000000000000000000000000000000000000063c510490057d8d8723a61c938000000000000000000000000000000000000000000000000000000008153828afdaf01c488b682390682cddffd1b933ade8c7aab8ffd7eac633b9473b611b3c543d2d7bec08f85b60a3e2902f5f67264f7dc47836a2cbf290bf27d1602d7a6d90d2dd9552f39dd9e317c208dbb2f4e637dbcf41233132191ba7f53b65964d386133eba2d4f3687d9a68001dfa1560014d38892ae433fd1404a3aa68ab16806fe5cadd97c3b13f22499c5dd1aa3bf26a15a2ed4ece6149be46270817dacd78ce297c55a9f86be94d2044ba52c4adc21b9927d45190e319776ee41d8662ec2f6dff25adf7e07c733d9571a0370ef2f76999003c783a51d72589fde067861364519fefead40a40b82ff8240eafd48e54a19bad50e9c1b6cc75c7165a373313e9d69918fad7073ee75781958c8c1c2062e54e2cfbda0572a693e008de42883218bc3638d71c54e862f84835ecdda2ec3c5cc9524319e055844d672b972feaf3aa22e5cd8c5b4c288bab928d903817f8837b7519a25c6ff07768cffe20b9b80c867ef4b4b2d969ae50a44163c2c02ec19fd89de62f9ddc9480c7fa732d7f7c463da9418a7cecf5919b27efdc0fa2b4e3eff4b7583c768c16b9fa12f20899a6a93d43cc7da614d151343c2449d5a503066bf769f2efe803d0ca97f20460000000000000000000000000000000000000000000000000000000030657987fd5f018cb1e741bb2e2fc23de850458a10d142e801866b4cfb765bbe4515cff7bdf7cf5c1a25643e81bc27077cbe1e2cf800e97d01a10cc224328438e3d8f1546b61e86d00df12d039d714acc3c4bf36043d231aad657d48af77ed7f99024e80fa87e5801e2cab470007e536bbec630c2fde13d5dd3481b056f64bc78f30054c18bee2337a23a1ea4d19439def9662c620cee8fbe3224a5d117a944e264b9152ef1300b0aa5956dc6855d628c5d7043126ffbf5b4dab4218d5145704ec8f2825a41c9a831d0e53ee5c0607b6820f48f4b74ce1b43f3a853af5488335fd614a71c27bd4bd75ea3dfd6b8f1cbedee4aad2836e974846f4919c86b6625015ad5f97f5be8a1711b1fc5158e03d8e4cc42242c0cbf680b94f3300041dd8549b05c880140ee7c740dad0eb6a85f38cfc55be23edd782b292f272687dd4ecb326145445b86e2c7f0031daf218ecf03074235a3b1deeca85fc9904154105712732d5e69263378e86786aee1ad80a00000000000000000000000000000000000000000000000000000000bfa25a9ffd00013df8bf0124ac40a0480926d053d900cb0124d8201ad91484539c220b9b5fe5ba2e739837563eec6454b7fcb08501dda4c1be099ed3d1a6033249c2bbe46a5b1958d3ff9afe0a6bc900a3443089a8e2c7662afed4ae4fad28dd42bc917c28df54ad969d97f537a97b9997e6bebfd187d0bfc78e319278d0ce5021b9ff191af8703b3f0047fb702a964a9f280477ea813dbdb6854c2434852f81fa1694acfc6f7504604a3b9a4d8ee14f57ae65e82843ef683e57259273fe9aba6d4b7b93c539ffccf7ca9c9df9fa993e60b83f434da9002763025f4a765381270d72a176104efb54b232762511a2720a0b8ef1e67f439e84a581bdd33e2c393283724ced33b1c69a43a11310d074c70000000000000000000000000000000000000000000000000000000065cd7f7100163808f7e0b6671900000000000000000000000000000000000000000000000000000000adabd5c8b249f3e9ca8e8f7d0e926557de444ceaa6f78d9d94598010997a0f2b8de4b6adeca7fd4dd2edd1092eb8efad4690878352afd361a6ed9cf4ef3fa88c8f7e1d7eecc5f226ee6b99befdc1a870f69b9b060a26752fc84df3538a0b540d9fcc415717ac6d1f556353b3ef1796bbe5a593e4e21b7f44c63f4542da3998438c56f3153cd1da54ca41e6f04df771b88215f9be7bae3670597344dc601ea6493e55c096759a468e2d25966a1d4b0c771255571848a3900ae7a130689904bd00000000000000000000000000000000000000000000000000000000bea14f12003f022e6e3100d25800000000000000000000000000000000000000000000000000000000147bf880003e813dcef0eab32f00000000000000000000000000000000000000000000000000000000f30a5748009ef8a33b603b8d5f000000000000000000000000000000000000000000000000000000005dc8f84adead025bcfe625415826c25c9455041dc5ac55a7c4be0f7d1e1fce4f9ecd313f1806782a2b6280464f8e48f5c358a188df8b61f4cc42f2bcad20884c934eaf6591cf1a8d6e8e508b45f23ba4fb21f6d0e4c6ced04e8da7859eb70738e152a0753e769992d5442b7c0621e4af77cfaf7e77e893da483633f4ce818fe150bd5157d61eb5131cb9a3012ec24ed114e7481b25e6067975d97a16fd8be9735b90d3bf27555e6b7cb5383bc3cbbad292a77ac4fbcfe9c0ac64fe7d479e1f9a1f1b5a6a42994e80bf4f9f4f9db4a568fb149b2f1bbb2fae7ab356d3d3cfb724aeab3636043664032ae1cc41d9627e2ec8a32a30d53fa40976baa952805bb2beb4278b2bb8d7a051de49e2f36d4d8e70110e5ca496416a5f0ea82c341c4ed4b8c7f49513586891485fcf2db877c5d26afae97ebc92ef04087070a12a1cd20261deef5d82b7393806217476eca4627495a852c8ea327a47f9845b14a9d2decfbee4ea3d1c4fdffd12aefeb796f77ad5661c17315701f9021c01dff98d85f45775c680fc805c67d6a2d95ae4df65a71b0be89af31ba113af8ec656d7896ab1468f7aded2c35819fc348237a2a493cdf7b9f2b377cb3a17e400fa4d42513af235fd62c8ea6c44ffa248a0ab33f44cc98fc166fe72715f8c21e6168c6f96be4322e0611eed31b1edffae929912dd497654e63e9399845e79ee866079cf3af2845a5f130358c27470ebb9241969898e3458d9fcfed3ef24c31e8c3abe2dfa541ea5332e6c056ed8f0711b023f4c545f28cece63651227ecb00bbd9c7e1fa1fb307bc87ea5012dc47722a9032471470d82e321b5725a7074088e3ccbbf2ac94ec47e3527429b5a7a573b7bd6ba18c9dfcda52d28894d292fd160401f2cc5e0514d1f01b49bd512c7ed8945be840b5edcdd38fe8d4fc8d31ca12256160e8d4134fc6215baccf06f02bac979c84136f9dfa37a81ca6bc9b93dafd369fc688a0c60218475cd687d5fb35c6bf5e969c6e8e4c564764fd17b9db562493573e907d211ddef2ded4332b5b9754845925f525a49145e04373f39ab8e26ff525ca5ac08e7e5358c598b4c399bf7f4747d7e76737e46f5c0467787a9956fddcae563690e41af1926ac665604ce84600d07c5b03d058466322d6281b3db2f0e938e0c7aa2d0ab8c9e4fe16048ec51fbbf1477deacc8de18a98d4d6b5a171b9f1360735f03fd7d010981f2056d4b289eb228edc0f65d71d1be42fc8384233ee944ea2ff6d19760a347b8b6db7638ec1445bafa9ad1b43486b47ff6d846551c5dead0eec84baf4361ee8dc98b60654e02ac96094b10078f7cb1ba2e4bd306f740a37d4dbea8fc4058ee95822e85979fa6cdb24895eaa06dd174c5176457fceb9be8ceb7c6dee01d599aaf930f1c374a191a4059dbb48cfa948639f6c4770735500931db6c5d7597672b52bacf0c4a80a6cfca728d0a98f47617161586000cc86432bd0ce601fdf5f83fd953dc38d83460464afd5d2ec44bd9cbc649195c4c71732c06a5886a0fe2e772715d92547af49ea294c7500f1e5e030a8e35b45720d729487f218e9c2c5b8d2f9b0df9416df1d1985965d509247c8ff72aedcd67d958803c4a37230447fd44b4506273fa2f236b031a4656552d24aca9f97946e29237272b9cdd0f5cece3ca859f548eb4a35b996fa6f5b229872b87f718209a4a5b3a5922060c30a494a22e93ae52e473e8663924d77763f72c1f269ff4afdbf9c31d50b0ff7bd683fd92010aba122ad38aac797b51c3637ee942084e803e531e9836270a45541f2d9e24166ef8b735ebdcc827ba0285d6e1db05e4fa155367098458764abcb4f153d9175eee8b8692a1e4b0a32b9717f3906a173ed23cffbe32d87b4d9d457c52c827676c6c0cb82b057185eedb49d37f73efbb05f5d4f6fb6dff75efe43a4b8058a5edfbdddb0f55293030489499f89276954d1ad2de34b066c9bfc72d33e98854d86a7c7e1187031e088a169e1845aecbbb2a47b5f34225dc421b6658c52aa6a926fc024ee697106e7f282849522706832be42f78436143993d4e4e8a6fd77f6c6b52947a6185eef3cb7a241562f1feffdf33b3116a9f1a28d542b2c6bec88b133c819bbf6b2a26f8ee4970364c8da41707f0bcd1644320d0e2b94e35bf3a383a53966afa80a161ff4d81cb58b1dc416b80ec71158066114a570fffc37ff2da7d57d7178773dae7455d878f6eab7d4f697eb66d8d33ccd911d0d13d4cd6c093b96823e83a8fd6a4917baa2aa976757a49a8be80d00011bfabaef4219efacaabf71e19b32582826baffa8df4f0a94211a6e764049b8c473deaac251190aabf96e3ed30019e3ac3a778699030fb9217d792d380f89ceb44d2c9f0891eb6f78a50d293c7bc67a3d7d1a9095c0c984acc2ebe72533c9b3c6978b9a8a7b23136013c2a7c69bc3d3fbbdcf3294c7e722cfecc8e02e6873b7b10ab8c885ca5f39a0ee1f16e3225a0b74c9ceea3dd4764854cda08d5b6f46b6cffe9c9743c6801fd950129359a1fe365e76c55839e720d4f2c56caf4ac8470ad71dcfa04b01cc873b4cfd7e15c36ef856134b97ef20ad53e708741ecb26958b7f79514ed18ad835d8bde79cb95fa2788c1ab64a3736df96533acd9dccc03fccae92414ab046bd09f40f0bde7d31904ff622aa15ca13c69fb11d9bb70d904506d0aadb871c6d7c4099b994adb094611b86b2c828525db80e83d00265a9c4bd20ca153b6f9d0a107a6a563191106f3e6ca3c67bbfb48410aceb2c9534bf877b1da27c70048d4236907d919a1fb4fefa6415f369f3fd71dc39cc69c72560c76022ab200fd6ff5bf7999a798e59b1948fa01684f648be7aa40a6b2ffedbc9c216988b8b41b0280fd754be8249767ad3ce4581fc9f903ae2c4405588534b3693f34f631bd8d6f2c25614ec148e13cc91b067461ead92d04ea8707e1e2e8f99dda14f9c38d9f7474594a1cf3a75388746df5f7e569f1f2ecce24319ac8ac4ad3b5ec7b1e886298d3ff52d42707c7eb7838d56b0992504eb6ae8b4794132009ad7cfe16ffe10ea94f6f37928d339361e226ec69bb75ce7a5f40e4011b19f0c6a8292e0004fda6012e63e3ea9fcc3eabb3bc7888b234ac667e9098245a32aaed19178b29ad36d7a33465a331ccafcf9a8c2b8dac0442323ace7ffc7a2b39f6de97efcf261aac11f984309cf531c7b6254e1c6062b4a2fe7cc031cc0fb2b46ca1891a7065719059490a2e3f6aece850a5aa9f55401519dbfa5af5508510b8f7697aea2fe13090e79c848a3a087536728ef24ac0f1448bf91d1657ab9f4cd11a08c86e146daf6b6b0396c0443ab5110f6132e7c6ea137e20c38c396e10bc151346ab3482e563ff9220dcaf31c2a6f9da7dd220df26cc53fab1b5bd77913c1c2cd903b2f3fa4fa3546d66f7ef2407e441006c8a8bbbaad10153dfa57ca03029071f24ac30f476012f92931b997b195fa60b431eee4b232a1392b3af022a285dbe1062ec9dc27bbbb04df70000e75d7197fdb33ac476b0a021bc36a1a1e92d75ef35cd376694feba14396f1283621d644e0537b0db0b0c61861ec168e749cd7b7ee90a29a51cb91a23af8e154fc6b4d8fcbde27ed63233aef655435624c84065f6e4e1d161f86e81982d51adf016c463acc15313aab3d7efed09068289ac5045374fbefce8dc3a1e24d66d1441d1636cc1a460afbe177e807ebf88c1ac4295660688c77c5c5c60bedaefcc0f0b6fed5e8f4ea5efe22c1186d302c29d32ac472973eed1048484b57a424433fa6c3c2922a9fe7e82131b19f667744d15d81dffc81bd84db82f118e3a965567f8f5d03033a46b7d3346caccfbe21341838ddd477af81d64a1a4c18afbb489615acfe94cea5adda21338878db3d7070ce0f1d885676e9c568b602ae72964f128fc52d6221448b359c8ecb127af09511391426dbb6e8c5135d6ae482562feb9cf2029ec17bd2b31fd9d01dda34002bf7930870b2271fee4d8f4fe32796b3e6123c1e084977b170ed9c776a8c9c8fc04d07d4780bc8635b67a7e8952bc01c6690d5432eb2d26f2c02362322ea7f1cf110b0a04eb655fa21aa221069b4fdaba35d4169ff4a39fb0771ab2553bc952b75258c1557fccd196d9f48d3b79c135fe18fac94333b36a0da5579d17bc937aea95f92c45ca279f8a79be060a5562c3aa38c6fa772b649905e2ab888d11e97b6fe5dd4d536825960c0de58f572056eb2d5ba34ab163e83baa7187ff304b370611fbb3a28ba6319df332cf06569766f50398b21de281a03460cbf94a9a136f81770de06031bc61eedabcbb0edb0a41420125f334cef5adf19d1a27b4a0af94835a3f91d1d756b31339201dbd433d4684c67a693a5bdc4fa5b440edf83cd5fa9bbf07470dc6ebf3eb7933f61e5abe2bbbb859157b7c47ec79dfef591f7cb435b1f7b48afea14cace23b3a25e27559233dd8b5a3af620bf61fc26221345f4356b64542a0eb2b99ad3389ddc36e843a6d6811f2e0b6b8dcd5e4afe87524317061acd2f01e450fd8add48f5a756728ffd4944e3b917b661b1b99e44580aed8c803f154c32d0036bffd9f70361160725dbfad5646c89f3982841bc199a2ee8d33a12e8091029703ca151fe819f1472bd5aa5087f2f92ef8b58cba3a794f0344ba301eefd873c4abcb98f5d2878b059513ee462e94e12cd6d2892f1218614622ff02e31be230ae7323555ba2116c81d2290704c1e274cb78e1813292c63103ea401b48ae93231c37c7e94b8b8b53415c2012c4a960c8fe683edcfde3eb0a6113fcffa71b41968c78d0b6cb5151001a1587e6fbda5e768c78a692c6ed8c43dde3d96807ce11c0111ade6f9f885761ff9fbca66e6ded3ccc5436ecb0cb2c1a31fb8a04bfa33a26eb49c76fc98aac74ebbf95071754564bdbebe6017310338092c94449c8742dc79ec63dc78ac3b3ec4f0604936212c4345bb545d7d396d9119039072de055580b027fe0870385012b2fe949f9e2e3fe2df3eb033c38665bac40296d351ae708dea4219d4d9b7799281e6f4a7b03969412f7b293b18e62647e3930ee942bc671c6b12cf8d7852b934cb84abba15f968c9286fba2c5cf6dfddb7ecca1734f01c27ae6cf4d340e19ee0d7bc76ce47b39b185df00384855153c5a332db02fe441b26d025fae80f2ff490dba492abb5cc25e92d6bf4502a45a70b35b125588d940dfd26f7cb115f890c3877345cda494fc96c04a81983f7528ecd08185b8cf290b2da7da49638df1c400ee4bd4fdfd00eca96e7d3f21853d83d27e410232b750c9898d4bf15d5b253624469d027e20aeb643912f87a537503c68a6a084fbdca319ef0d3a64badc883ad1a0c48c163a1987c753257fa66be3ad69095aba57fbc1308c98e1f5df39782680f24791d3cd949f765a859c36da4158edc184711d74470d12eb4ee1d45a6ff2e7f0979e11d434835f1010f456f108bd43c2ee8672366041a9883606a11dc61a0220eb5fc620985b3afa852a0d6adfd80f34c8c0908112b9757dabc303527a04e1bd733ea03dc64b9df0aab89d2a3c52bfcb6cee2b5a02db9bd3438d9f8335fa46ae4ce4436ad2aa3de93970fb2caed3d14c324891a617da6d0d86c7676374b770505ac302fd1901e43420c809945896c873c09b5bb6f43ef497e9f98f73a936dff371f1aa9c15495bfda3b0e562b8a677abecd74a7318f850942611caa66bfd29dde83452790f2abedace64ecb5fd07efe8d547b7c781f02d1ffc540dd47b9f850713e903f1e7b54edaeff3c73eebadf8260181dbba2505b21e0f1a6e809ab212fbea3c94e98d8e35b139d4feed9b77b093e71969a2d61c1b11a9152fce2bc7b9bffbc7e6e2f8c1cded37950dfbf0f300ede9ef4565aef82e6c4c61f030a9a2266aa9629446c7b5991ac3eeaf31b52fa4cd22bece4c140cb22d453774f05a62a73d45f6ce8ba96f629d85fcf5801ef7d4b4c3080e4cb07edd031e3697bb429f5d5fa71560b748f6696b624365ae5bb821a9caf5e86ae20176c18857bf6f4efb07fd4601a3f89c3fa908f1c3552ff652922582c2b798e2051f43bf15eee5b8d865116418ffe81d7ecf5aef7c1c0b0a85b437b4459fdac54a5d69bee0394b774e2b77cc0dafa9a48f6398fee17c154ddb5ad4dfc9903a2a3a35461b8547b56449fb4e552e52d93b09e774e96ea8f733269f118754837ebf431b082f97a4e9cbfff1ec9048da25901e592160980776fcae68b9c113966844635f8ea71715a940cf9385c50757ac5787e49d30451c6ce04e87a47e49e6fd054a63d364a20919b0f8508e5a3386903112307a58e59f3bb4af7bf0aa75e63e858abfc52055c5e7f539b44c661b3411609d58c4447b4fb4d01592ca020adff514057d0db6c73d24ef03327d17a860c3639c05225a4a574da6c8879b1eeaeb260d32d72788304b05a2c62e0c7119fca55f27d522b55863a1fe8d48919f8ee58c9944b31be175bce99474bf4aab57582f1203132b03fd7901f219f1729cba8171b741a33b8a163cb7bcc80b2894930c98f36f695860290563cc90b1f044af2e0f78e0491eaedcdb33c71b545f3d2839939fec0f603c10ad9d868620c94fb4d477790e657f5a624c52a80050d0fef5df104533371c2348df517a470a0c6e78c974b67fd598949c81a56cd0834944556764480cf6cb093c85338d2ebb8bf3355f40e21f2944932bbdb5ad09f453e5ffadb8be2ec163342297ca157b0688bf4f896c5bdfca8b458a2cbdf8102d0e65053d688c4abd4d9b3a238a7e88cd31ce932e06ea351ffa89676d8387225213ee66ddfcf2f4df32c11c369ded6ec98c4421e5a63d5e2c6782a083ff514cda5bb26dd59b32058f104dd34a6f6d129c11e3a854a1310004053140963c853c0a6805a164cf443127ac326bbe43238e54d14032417b7594d4ab3f433032f94ff7e19bccf860dd023a8deb94872413a5850bdf57b1d3543637064b52862dc4c55d8727369c2135df9697d80f8ce23a990395464e500fba081f438778c752f7e0b0d07ab4607ebdfdc2017cc7ebe0cdf3a079904dbddd27859bef4f5ab2992ad55acf27403f9c226b14000af970b8d67ba8464c54470d5502de88f84e0af3d3348d3b481f75ee8a01ea75082ba910ba0ab7bed4c14feab97033bff8270d7f5a286fce30fada23da9e004acf0d1094bd85eb2d3c378b18f0bdf96e6fdfd0c73d5dbe27f6401e276f99a0d247edce8225028b8b67893775f430cd11d54aed13514c41ecfeccacaf7196285b2d9da0f9c0da2e56d7012da39958d5616652afd8c18185118298df9f35099f6060bb8d6cd8d1462ceba20b98541f1024a1dfbaca9a4278fd56b7b3e9c61dafb8f1047e2f27a141959d1a0f6e53dffa8cac8e9f64b12bba315acdb1fcf8a1a22feffa3fcf863cf9476c6d54fc7f527c83a327fbc5da4f383040e44baada6259d25763792a4032a98b79e4acd6a1ed08f55b2d8e6d8dbec505bc03a8bafee6659ec534716a9c8dc4a5694056ba980012faffade4bc08a2a85f19deb2129a22c310f828ebd9b8eee35524d4d259804252646935ce6e7dc0258f4fa418a543825cc086e1be69ddb1fbc2b6c2426f8bab8169334bb414d4e6df57e83f871e68e7e807a982e93310983626ad0d866cd00c7f2183c48ee206e3982a5d35e1c1d7c184ca5147fd5401385b4e748b9bcc0459ae3063317bcdccc3a441340dc182e804ada77f99229ef5c8b2ed2c8440e0bae5b00243372af7b5281b335b2d4d09c254e32f0e4d1512946c27e75f305953de6db711482e8f47e18c03e6272b0fa376b3f6f87fc216838e8304eb3f7b8a679b86cec63963c916b66b37fc86d71f55bec1b97a6f7b1da406e67107c31fe3a6ab5adee16debb4d9d6729d49fa29a7944dc1dc4887e69e334c93de5c09b0b571f68003f1af05d6f6568846b040fb206759c5f13b34bb93b8d39409b945be7e812829899b1cc628bf579ce86b615b4184865612ef05c2c5915c7af6c64c21e16da54b734e999627673624ba3a93c41b5239a6dfae89fb73f85f85e09c40617e8cc080fa797d08124bbdf947619a3ca5f762a4a1968984008bac06435e39b980680e5ff60345a02cc66f0e13566d13e1aa2f815ee9bbbdba2d79565baf8915ca0167c8e266077e557fbfad60caad00040ad7b91583ade01f6b42cdfd2f010121e30d383cb49ae707b52a00b8168354f86acb099db4b5740bba3d3841214dd7eb78c23fcee6a5025d0759aa0208932d2d2a75106689009344ef5d03693000d88927034070c8d78f5d77538cea539d6cc70ea5160f4d362a6fd738c77eec8fa7d076fc9b6f9197b86ef98a6d86b298ffcf3db86d8cc01fa73dde6c103eaf18471ab31615f9d879866266ab808d52c7d893ba0aca1be375aa2479186a0714df84ea727d537beb4994e2e50130224426f2485d682a92127bad522df6c392348033076de514621ce509f8a6f88b00e1275d5e585fd4555e29271071d6aaea1bb2cdaae9d97986db82b29c6715a8dfe843c0c1cf4ae40c57d0d78bd822811801f203b9598d94413be0b4cbe0b8c833a74c084b1ee66bb6258ef493ba4a096f2d1f758d967318b0a428c3b8b781470c76fd970118c02aec90040d75725ea3042e08de9a77b9b1716a970905c4b50cb63402533f4357c3a697d7a24c578c096fc67bf144436c57e8f68b88826bbbf3f4784de0731c26cf64828cb9557c2e7f1baf2631c4fd848e9ac4ceeef6109f50528ecbc7da35341aae338055e62663ce0a3c43d9662d6ca7f58590b8ef8b19343770c7fc2820470e3b969e90e8e4adae6070f392d5d6472afad455b69300c70e5cb37f7e9e35e6de31532e660c67ffe67f3c4fa8279b15c323b89038b8865eb64f07b8001b75b490a8cf743b04370b6098b0ae9dd26f84e9b96751eb4bf88469d12762f268df11012950d4a2a9f9bdb48a6397e7491c22b64c3fe29e01d0a098df92f15221f73df80d2650621a36bcae34ac73a85dc8a146a2e0320a0a84f164756e352eb770ddb438d358bc85b431ff846fcfd614f62caeb6e8e5c7c33931aabd6cc9681012afc096efead404b58a4e15e3540914332c8a0ccd0d63233cb07a666b1027a0d0f4c7e6b70410486d223758b4ac006668cd4bce09d29aae796bd49559fe86daea9c7801be3a030a17c8ae4873f98271cb51ec2652effbc86bf15ddd44835ba01fe3fd7d6df43f5ac2dd2d3c56c9ac4445e0fd56e43af74714ef4d7377549cfc65f7fadc6276c1d8db5e7f9426c4c2c97bc6ff76a90940965305c6cec17bc25b78d3ccd02e1e0583ab7460b7e289449a330e2586c837c1cb01c37052a94b4f71323aa5e285e1497bdde7fb5faf8894719e3eff4d8a9d58ae0ca10228334edd17193881879cb0d3416a9158d148af2da3c055b94bd1106f88f745dfbeb6e4fd634102ff81111d255b55bce3cdc0c5e542351a0b4dfeced9a70b2baef155afee71894f704f",
+ "spend_index": [
+ 0,
+ 1,
+ 2256832467,
+ 4294967295
+ ],
+ "result": [
+ "7ece1b4eb1686e819785ed780e21833c9144696c76978bbbf7b91542482d7dca",
+ "907562fe9c4028db2a209fed33d17b9db6b513c617b65e08fabd61b725d10035",
+ "7f66349b5ae68c930d9aee9a7a73a57ee7a793d2ec17af127e643a5969bb1a44",
+ "0e5fe7af882abc6dc8cdcab52a6f06d7c8b0a2c6979a8b0925e05cc097a1bb39"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 6,
+ "Witness": true,
+ "Version": -1121365080,
+ "scriptSigs": false
+ },
+ "hex_tx": "a85329bd000105bd273b6f000000000000000000000000000000000000000000000000000000004aaeec4800d1105217c17fc93a0000000000000000000000000000000000000000000000000000000071a3b5b9005fc09db682cda04700000000000000000000000000000000000000000000000000000000ac46a23d00ed774f8f67a4ea170000000000000000000000000000000000000000000000000000000048bf169e002d4145bdd05a4c7d0000000000000000000000000000000000000000000000000000000076ee89f000c4298670060a0dcb4af14fed1dc827d988fe2ec385251a53bb551ebfbe72c53fdf08058ec3e6d6161e5e2a7423a16062f2e4639808a785c3d59ee3f3a69d02007db9101ded18f687f0d10420caeb2400fb79a78543a76a171a99b75d3b19fd523e9672208555a22c3cb619751c1aa40aec38c21a2ddc3dc133200e07446bff0e806e5da2bc891065648818eee19c2edc57bfb62a33f8bf46f347fa8eb3e72b25a36cc011f6aac189af5ab9a17b8b8b57299dc086d519b000eebe986e29d29f236ebd64da694eb7d2d02942c28425c9faa46941d271e4ce73905ca06c615dc8bb355541e131c80142beb9629e3d2eb8b9c61891aea29b67d6b0d2e01f8b1a9b22bc72335284ec3e93fb919d62ad743950f877598fb2f03f80e45e3bd24405afad57e82cc4f71d1936c8f1ac3ebd91f8641d7bd90caa0919a5948d59b7c7fc81ee5c3e38c3daaf1cc6288076be779b0a72a902931e253d81854de11dffddace28c8f88ca85be9436dd5037e4bdb1eb710ae59b2053530190bf066af04094730472f9125faa096e41c77658f54aa4d7d36711602aec189089d25cf39315f5df4cf8d11e964497d1136b85eb3e8324a12fc899222204b2df1229746ec2c9e5d411a11550be538ce5af13a6c176b5504f2cd708ccd8424069470b1c43b15ba1e8bc1503d01aa45d79c6e54c408459cd922d812e6f4a156133c867bbd2ee85ad8360c604961c8a1051674292d02ec48c0c497e33f772c022c139cde50c750cf84311fd8611eea3cdfdea8b16b2d0e9ef1ca1d03abf9ccba85299fd6f115af72bdd0c7da14647d033bfc8402030cd170acb8c90dbf54b4c530455f4365f39b85070370d0ff4e938bd356bfdc423eae36ff0c02f64fe11f7c610f2ce8f1d4a2b45aed32cc80279c8367658b0d003f0d7a6b3a0aba3bd18eb27c43a5b0170bb5c8f12316b2959ffeb87ef520c3aae27c2356d0cca3e5c12be0146c8399ab410d839f61c82382c3fa8fca2941024e4b6f3f84d72dc3986095af476021c8be1a7e42573f00941c849cf62782c0ff36b7a7b5497bca47b9b1b9a46b22827eb3fc53496c409907026fa942f7576ef948db31d22fdaf871a214166717c0109769529c55ec3260299a4f240c20874e3216cfc7b6557ef64fe3a74032a07b9971fe4f927e4e95a549df4e0a3494d301c637fb6f4d21ce6e36dc8ba40f4e2272443dc713df51e35ef69335cef0c382261a2417226223d8e0e085e457ea970bfde510ff6a076cbadf31042f9cc16d60d88f952f3518cde04c1863d45a2e1b44a2c230077ea1c62bd56bd2cb46fcf37ac22538a60ca77637816c2553977b8a8e55ba3bda6076698056fe2be0314a0eec5917ac78d6399274e2907946445ae853101569d395f6e8d3d5816b6aaa3328aed955d8627684415c1bcd284bc32a078603c594a06b5ecc214488486e77c0950e2355b28f99d442d12b41fc583c1036e254816b9bbc15e5498121222c81859344c7746628c4df946424cba87e2d1a97dcc8ee7e64394ed194df3b5e78c3e05587720c503bcce1c40490dd154835f1f5ae98306a71822f0f3a16a1fdc8366a83fcc24de976cc600a5b050152ecfa9fdf9702945fa33d1c8d0e51011da4ed316a20ed46d85d63af623621f490dd7df5510bd7b5515989753025fe6e26074d7c254a9ae38ddd6d91210d6eeb7696ce5b5a9264ffca2954a26fd6c3d7391ce9402d755d45409eb31f6fa3c5be14f30c5e3586f5354abc245eca1f18bf770260063e0ad116f667903fd2b019797c0c6f8da47f4a7204b1019c0c5449520f3b152675141af11985746f9c26f4738c4577d4f833efebc11071c7dccc13622d55f692bfe3f56fdf1c6b54ca598e7317eb35d14d1230f93a8a6de2bfecb18fec35fc61af109fee8e124cf67551951415e71cbf78628719657c3b180ea821e21278f4ab030e31f5713f4264032ad81f8f2e9ac1dc2581bc24ccf34baf127ca8d636032f2af82434d9a76144aa7aeb4d0e62bba3bb6564b1070676be310fbc96f33c7cfc749318d6ac90f64196ff89dfa08c4363a5f1c211ed36038cbf5df1aac3647696567bdbde61513be983a9639f5fb2a6084d0b0e9657b0b0b7d735ebe50c5a5e7fa0eceb8be0748d6f7ff257441a417ecfd3c525754728c87b228a7771ef0c11e200738121786b49d11994ed58aaf276db014c45f963cfd3d0137006350bbe52ee7816c885dc9a4b560a84b12ff8f010b0296641da8fcffee360edfd8a245782887ee3cb369c99a1693e919a9e1ad0519f5974f6fec0355f3e9f3669acda3d9b37d0eab9c7823e02798fa8aa433194f4812bc328f37c79ad3d5d9fc225571d74006c958b92d91fd026ca3fdf7ab8e22869f17041349a9463cec66691cc09f100e9b7064425b184977861499bfa404f773f798aa475653754fbd71f004f2aa98fefeb9f1285629dc00c00ec1350038630fa0b964f9da49fb6c603f161f344b1ad2f321a6743de17b5b98d6f7fc80933836bf4f569aa1d7bfb8c493c289208a8dce556d3b6f2a64ac44aba3e47ba4d23f588feddb456b6e1389b35cbe4021f1ad4f240f8ae77c6e8c1567ddcd995ea4b62a3fc7bcfbe1c8bc8b6676ea89690db799bb9762d242d67c4d5a8f98870c8ae683dffcde119a364c20cdcd0a1b055d8ed43cb127d43e62b1871fa8bc87b308ff5419d60b6c7b80307d11e93f5719b384a97842a7a1543a62923112239d05e797b155777148b86ee2ca55515d238fb0b38d61f76f00042b21f785e70e481945235ea7714f267f281f7dbf86af9c49e2afd833c2b333d889234a81d7f8bdb5aec5f45b3b2d1933785dda2877d98bb8e7e2b79b0468cdd51c93601fe5389b4ff66cec3fdee8a970c57d4fb5d43d56dba3e51df41586258cf4de53f5b333658f1dd9b3c4bb5e881f958f5892ceb9baacfdcd74a8f00b302b438692c1e5bcfde50168dfc8eccbba89d7f930ad3022fea15249cfd94dfae54aebfd3c14a6cbefcbcdad6389b1b935e406140ce98b59ec617ed2ab62d70d085cac1a703f85af5afa9599a0591002f3a2a6bda8d991111526dbb8bd1115fdb155f58927c74f936c0bd2824817ce718e7bb12b1b9ada1f8e150f05f144899b81a96cea71527e5ff5a71fca4bd4edfc50aaa74846f0970597aae8388bdaced656fe24840d4f8c29624d33b3622d00546a1d76a2b533a94b5bf8455d7fc24d5f22329486125a1877ac4538282da12c6b667ec1b46ef72f365e715fe17fd295c707144a33a1db8ec7ec4fc80985685a31b2cc785b1bd5fb15d4254dd3a70aaabea50b604e39d7c4429707d89de53da0026877b675a09d34d23f52b0feb8f3bf27eaf2dd381fd17f9cb0b984fbcd63aa1cd073c6babf589ba34afeb49b456fd741e9d6d91e9a8c1e4488fba3e57cf23ea9451c2300b1fbf0652f912fe51148b9b2cc54b16c454b555acc104bf90f6ca8e4e77575dda189b08864ae1dc9405d08c6e20d6d609cc315a27f0dea43df7a3fc63d5b28a43cea0be0cf41dbe364f398a6720f61f6f5a4befbe2198b5f7a634c8c8d1942e714014c2b80a46095fa5ff5de0eccc957b4b85566de6cd59505f9a69d9eedcd410d263e243165d2c8a01c9fac4f0e86403bbdf7e4120472aefa3d1c62035c7e270d49dbd0f51c49c4f16c4622671831a9f96911ab7a70619b49b65e50abb0f9a40dc88aea860b9340bad394ee58030e3a58a17a82210425f8a08a33e9ef0e0547f4980258e1633c35c2d2ac3790825bc9fd7a5d40dbedd1d5b1bf00e5c368e6972e3ac8ef7f5ed5b7a3c27595b3a296d73b204352613bbda155234471bacfbb6bdb7d3d986d871e1bf701b84394b9ab1f9646c7370e1b0e6b0fa26c9c1539f617f7325df6c9d6a7872cbd67447cb8cf73a0adf3997e83d4373ed3525f938d1424113d94d4eea2432f76ef9ed805093cf57dde55ffea902daa4690bc7b9c3728829fac59b018c17d23b2bdca64fbcff5b951a796e504a32c7ba8776ed180046874e89d800bc2408114e82007a7190f8f937a9a8669dce413fa8910a9a7325487b2d3b6cf87197141459bbe38e05959c24ab74b9cd3fe3ad2e84b730fd80328651bc1002d586ecc",
+ "spend_index": [
+ 0,
+ 1,
+ 1966205163,
+ 4294967295
+ ],
+ "result": [
+ "e621fea8972801c609584be59f2847a8ec50a9faf91c0e17ec32ca8e8e165ae6",
+ "9d938fcf5a87e0c748031ae2b11ce67eb76512c5b7f627a7be40e3ba0c4b656f",
+ "365258ed1ed296bd7011d1f5fddc452749352df21ee50d72d1e02cd3213711ea",
+ "856fb3d89e5d18d4e4a12dbeea1366026a5d1a155ced01d743048e78edfa817b"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 3,
+ "Outputs": 2,
+ "Witness": true,
+ "Version": 14177900,
+ "scriptSigs": true
+ },
+ "hex_tx": "6c56d800000103dc1d957b000000000000000000000000000000000000000000000000000000002769a2eefda7014fac369f73dd8922f35850393dabdfa701f6d3ce48973cb051d46b59b775410ba0e80285f48730e8178e4d2417cd58a3f779e1b34eaa1eee4adfe2264abab895637ac5d169cb043c5ed47e43cf2cb8b9772c4acadcf2775faf03e84156a2a6eb0cebad5d8671bff45dd7c96f8cdc01e6404ef78bd453fde86cd46a71138049df57b55894fb927af05a51924a05e9be935561d72141293a1ebcacec08c3a1034f51395599f968d2fe34ce76916977a5e27e33b9005174ca5e39f5801ebe0fa0b0c4ff303803f9fe6e9cfcecdaad5d92f51a1bfca0ba679f5a10a1c33bde58eaaf5c920b31799818b15e0212bf3c8882773760155d233e3ed093b7c9cd1fb2400f9e3ad443daf835c587d2ecfd4280f15790d4aa51be2a98826e630cffd33873c46df52cb50a8b5e5fdf791c3a6bc4fbaa10e6196df4252236dde90c03d42eb98d1d86cd752f9ddb4e5b99effc659e8a5c2ef2120eaf532ac03e35bbce791615352ae6756cbb5679ae748421daf6bc1a55df02672928b903cebf860efe165beabaa078bfac2625c89190b987c36bd56dc0d04eab01663212f0e89143eaeb395384e4fce5684c4a36c1460e1d43d00c13000000000000000000000000000000000000000000000000000000009e9e7da90057f6aa00d9b8513e00000000000000000000000000000000000000000000000000000000324e2466fde701347b2a1a5e83b3499c3c233a256102da9017b348266a0fd7b0f308e53c4f155cde9d5c006a1249f38fe70c6c8df6f47d2258ee470057b70ae70da5c9d10be083d6e6dac732254b2076ac3f64caea7365c6761d74079b7ca5eadee66c324f36b06c3724e2f6b65f204c9c1a637e7199ddff4e4a916a607a82d529abe5fe33e2eda3bf6dcf4af60c1e497813788d2493da4730431c91d02c03c98548b89d23998f4f6e129bead4635e5d5c4d68666965ac496071f7922bf2e157f9b3dfdcb276774d7a08f1e8f5ff0e282e123168e16833d1cbe6c1774cdf531872405f2ae69a07ea44a83e100771baa28e304b03eb79fae3767c4c4f6b6f3ead4c05daa4e849ccd898b6c822efd7dd6a031f213ce4e0da322cabb60d369f0ea79465efb495434a7e69705541e0b02080e7742957cd6c5bbd986380fbfb3a74772ae248d00364354366176fbae18809179911a47504a8711ed0e2a1a4a5a77164d1674bfdca4d3af69eb13246aa9d89ef859619fa4cd8f513c79346ab4cef2e6ff5f65d302ad3535f58b8e0caefa24914a62deb6839013e07e09a42ebe9f26661480958b8cd82b8c385adc240f47140ba560d5c93b06a1e4d79974ab5847098f7ad8b9c8cbdaa6edc0a639963d09b78dba016a2ff41dc2728e55d376cfb197ca09f58136978a3cb149d796b915e258efada5d02b89df0f0d827d82bc89af85ea26bf30089498e1636b711f9e6f9204ad123de8111ebcc9c7160bad2249ea106120844bd64d419581515fa0d5492bd4542f26a16151e456253e93d0d0d464de3ff9cd3b84f571805b43f88c3f27eca3abce06d675fdc9f505a83cfe496a13dc668756308c8366fbca951072cbec7140c8e92b687f10cbe35677e10fea684f45419b925e135624a072598048e81d9381323783ca9211594eb314f657a82f22c4bfd4af426ff1ddc32b9eb736aff76a1fb488376fa6fa2376682192a8d93715ec7db49b44b1a4d4cc8b0e62a6720c8ecb7adbd65c6be0dd54f1c9e5cbf9dd39c98376597eef0f94e6a207507148e24df6657cb3ec7ba43f0ed91523de1e9f0c8799e709a9ec8730bfb4352c1a21a34417c3a58f74f665525259d6285b8b0648c20683ebedf4f9e8fb912eab253a001bb2e28cc79daa210d43f36309550e5244ea9af5aa62928666edf42074f7147eb26605470f4c4916467128d65dadfd63a48b864893af9b3d819ec6fae68208a836b5e8a77a81fa08db60d7f6e9775d942d67953df77e48cb74914b61b43016bb0f54afbd1f98472050482475cb23443e6751d82a0760a51f91b8a41a854a8ecd0b7c1a839ef784f0e7287e2e8cc03324cd1699e7318867330d59461888289d1b8fefad56be6f6f129270c000032ed7a0cd8ee10e50e0fd9e7056941d644d25a7daef27eebafb24881e114916c7c545ad6d16f74e653069cabdcc655ffee0f60a1406c813b4c288f793a48d86f6690696be47c9a544e87d1655bc0e9e8048eddb90217fe9755fbd029c5b1d08b5dc767a08c4428a9d8eeff0d35864d51a4ad8dfdc776899f4a563deb0a24df87bea5ae0799cdb9eeb0972641b99b65643512a60dec2a0cac676d4c0bdae3129443dfcb744efe650fe82b6c16b60a55c69a52d4e5ab6c156e30fb2d8f8c2b680848a217d6b8e85129cc565930d4b913fb2376f23f1c8043ec7cc0ad45f2a99bef965e948c350c94726e3255fa6b8035c6eebce7fec5fa54899692ba1f98459e0b1dbe355260e2315f024e87e993d265521d2b6b49e642a1488a6ab201956da05e6c0e590a60210004fd5f018dd55831ee67bdd28c30054e1ef609b2ee88897d0c814aa1898978a299315c5f3509a46aa09735ca318dfecb9be3bf8801aae72d281aec64ef2fc210df7ad3b8e00bf494d462c64ff4ff166c4404d4cf1e24fda5149486f1ca73783bf800bbcb8b8c1df06642e7a89b6e5dfcce49a2591f971f9db11fd5628afdb22e12228ad75d053d7ddb6487f28a537d245cc3265e3f067dce2fc0d07a4cb9650b066f895555909cb9ce9569a516d9dfe3d1359f6e4295d2582572968898b5cab0363cca1dc9cb85bad37c9269cf75e0f0fa10b4dbc18ae2a62e9bfdbe441da9a2959730b17011ead2d669d5f24389a66bccad6dc8df0e2e7f5d67661c394c221faa1073f6f3a05bf1e6327402ddf6b815fded475f5a62406ca52548be25fdf2b894718ab237fd0768f9d56f31e2e3c29474291c68b5b709a0cad5ea97266243c0870487ee79f967061610a9c5c5ff8595c948937f17e2613e415c659f20df446d39a685e87c36075726b1f9699cba8bae12f4ef28e15626aa47faaa4f02216e077f3952ed1ce5ea3df1dad624cf33ca7211a706b245ead08f50557959cbb61ff1dfd6c15fb5a3ec1ed1acf3698c7fd3c80e9f1ef3f2da656546733b800c1c334c0096f200e6aab1dd0aad63f5c56ef353e178214f589e1d7e96746eb7305bf6b819930329ddcc1878b0f192fffa4d8aa65419a01b0ab4b3e4093c5a693a3ffa96be3c51a7a56ad66be6b3cc6921f6b1d82884caad4e258b68623bcd0b59cd8b42bf7ee95b5a300ae9b18cfa8885a4364d93e48c0058b740ee84eecf2bf0dbc532cc9b93dcccd1661721eccbdbfd0b01bc0f3b0391db6eb8e92a3f67969b1ba815b8285c6248f8979e1fe763055991b306f1770fb19944593512170e6497f14b495a06f79fbb64e180d7a44f42bbdc94a38502c1dc1beadf0d869550ffe3967772373c4fabd8c39a812c514f46ba807498a035eb640b9ac62d168ce79e91117e9edfd3c9856497310d7143435d9beab5384394846f0851dfc6cf850b55f3ca527a618115e858bbeb70c935884b4e16a613ac188e68522662f231b5d41cabfe1fcea1cc6232671e3bfc0d732aea58450c1f8c702a76c76a8affc45eaa7e1221601102a84bdab425535cf2cbcbead034c8f1b2bcbc42461ebdc5a8f6128f19e965f99dd4ee00e2525f7466a920b68e33f499cf5f05d931fcc8d6f5957ff624f2296986ab5f6a01ee80b9bb2f4d657204c1aaf819e469b54e6850da7d7508ceb4091b9ddbd86667d6040e3c38d8cdbfcd826b9a6c8937d7b3349d56e4f122ee5c18600b69be4cbf752a737ee327adaa1192657108c94d61911e75ed95c6c449b002013ad4be652e9c824155424ccc4a5443472e5ca195c1907a2555ef453eacd0",
+ "spend_index": [
+ 0,
+ 1,
+ 991402756,
+ 4294967295
+ ],
+ "result": [
+ "69503af7f18282622a773f8aac4289b12d802e301d45b969f6bac81f9a34868f",
+ "c303e94cd581b06bcd2aa205d10aec0b3ddb9977e8251fce846bf4d3158fb071",
+ "6f7c04b8b44c20c64453256d6e4ce5ea8d888b4b8a74950fd9f1777d0f54c557",
+ "b82f362d8be5f7c0dbbabbd9b0f9a908e1d168416c0fa6240ccf6a78f5225100"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 8,
+ "Outputs": 10,
+ "Witness": true,
+ "Version": -1517733652,
+ "scriptSigs": false
+ },
+ "hex_tx": "ec3889a5000108c96eb4cf000000000000000000000000000000000000000000000000000000008f75b167007da378e1c0a6d665000000000000000000000000000000000000000000000000000000000a3b015b00f2f3cad92e460fcb000000000000000000000000000000000000000000000000000000002257749400ade11bf4bbb59f8b00000000000000000000000000000000000000000000000000000000ec109ab9004d2aa4f869f1a73a0000000000000000000000000000000000000000000000000000000090aed3c70034e8ed89e84edf2d0000000000000000000000000000000000000000000000000000000092ddffd600410e2fbabd3f807b00000000000000000000000000000000000000000000000000000000cb2061da00c101e4a981daff2a00000000000000000000000000000000000000000000000000000000b65f3cde003bd5190b0a187c93202477d158c855b325eb1c284a4354dc20059ca77ddac89a181465f083d0f075c80e7fb5c34055a1fa99623fa3dc7d68ae6a0c6adb3d4a6269673d1caa94130c5ce080928d53d3fa72335966f1c1b32d8fc016ac03f2575507683f73f134c73be43df03127b45b0fdd99528d5bedf4bb0a84fae0e86f6eaf5f7767045ab9b82e42369c13b76b1d12301d7294e7aaf9d4fae27627a2f108579807696fd7fe7228eab650492aa342463e17830a6e04319b9e585b3070333c04f03e63e6dc62824fdfb25e6cd0cd831242321ff438d8cd5029f676e6a147c8db3f953415d38451a3bc393fecf61d4218ef34fd80ef6a16e9a36a247b883842104e19ebcec7499fe1f35fbf7103c93c9e4de19adfb26aae69c1e539e11a8c66c5da857a59dc82596ed0725cbb61b3fb56ff857c084c703f0d7398016b2d7fca28c9bedfda40133501a2f45c52516ca8681026e5afd37246c416b79d087661a36f25c415f9add15e71b4e7018cc58ffa96134e6c7a5240e30181126d05d77d83ebaa866fcf371deb50bbcc4acc682226a0ee2e100ceda76431fac7654735a6ebf13f1ebcb0328ecdafa1e4780b35fd5bc805f320f9681cb70ed13395ac10cffbe2b2408fb4b8002df23ec9cf7ef59c2a7cb708f06e18114135a03f0fd4b3476a71d973fce042616b188b2c742a5d169752d9ef4ad5ba55453e209b994916972557f46ac3922d8503dc6f86f4ed7a39317d8f7c079ea709cfe69178deef35a12c9a24bf0b72fb3740897a47786fdb71c42893ffa002c70276ddadfad9a9551485ee24d1e3b323ba271d5a288ad575e691660a330f6fb0d18165094105d9bdf18d4c5b783668a97804f7002f3c75df677474908bff3743cf90aaa04d47ecc499553ec8e0d516ea52b011489d4ff3187e4ee821b1dfac82e61b1517dde3a757adb067243ce34bd3ade7ce1cf567000e8e049bb887f669b20dbc502ea74caf0212e8780a70e75f35b298c5e43fbe3340471d9678f76cba3cac3687f24c046f81ee9276160383fc4490044e318a309a6f4cd2cc8e32c56c2def96341a22e3d999ecda67de1e7627b98baab7cf5ff7731a55297709492626d449ea1c5e95a51edf210c27b7d8bda02a93b28cc63c9ef122a50c1727f1c7c25039667198a7b9b3c004131d4346b5013f2f7af9505869bb921a2aee2bc8a19961efc91d923183bb59b8047af9be7a7c026c58438aa1fd790df2b14e5dff7c4d20e22b19a4a2ba0df2728694080d0cb5fb8250083aa44c7952d3a048e127cdc34f0d37c8ccf2726a8eeab88cde748be9182c992ab6945a6b14f72cb792a384e3faad4e2fb29c1f1a3e64d5751b96a333c6a44051559bdda15058bb1ebbf0b0be6701f1908915d8e3b7fcd93479506292ef83a1f7a7a2b88a90ebcdaac824ff72688185460901e6754827d853a9fca376ca80a2a17c7425066ae25edd6e45ce5dd75aef01a613f65b11807caa7149c878cca3710401784dd20f21acff288e24e9e5bf00e22fc4446f83581896e6fd42e520b6939f7785f990093e361be1d5579d30311f581fe9e63e5fe15420b5503fe446a33a48dfa950de1fa7998a20bfc5154e088ae7553fb8dc72c30824f8a6eb895d6fdd244fd0a148ac6da438160b89d2ed458c7979a40ce4adca8caea7ba397ce51769341724211e0b3f193c6d34fadcb03e3c555fe47a4e65d69cfbfb24be6196db8428872a1e297e587edd10eaa379505bbaa85eb95e661cd4e864a15b800a09063219751c0d50b3bf615a2e630cc88297794d575db5769bc69cf903d02bdb587fa305f4e1aad02eec007f2eeac5bfbeb6f55c4321b759c4c4194aa7f82caf216e4c681fd1ec8baa441d47c62ea6ce78a762e780d5fae4e16eb20ba217beb8cf094332584cf44e3156d3aace6471fa7e34a047764ba02471cfc2061165b6d28cb40ba8a2a59ae4ab1b2bdef20f55c943650718e714ccdce2b2848a97615aac28bcaeb2372427154657f9fd265d2990a728bd7858e82c60e7f19f40acbd58b06b6ee64ec6a1a2f4c3ce530d28544cb8c8163b6f0f7b4f6faf95aa69f0a7e23dc852003c0ae9af77fdf579fb796e6671b10638af2ce27b62a3af5236cf0f35d7f2e2f77243e1c18f40f1a9bfd0d92bab26b8295a6f8d1eab9182c46f520a741d71e7c0d4022997d8c009ebfe59dbcfc7456953e4d6da1b58d0cb43d591f26d976b8acf29541fd5b793d3d3611be820e41258ca09ac4301a8b10f75fec6a3eebdf94215f5fcb1fd5a8ad268441ebd084f6fbb75b6c0f35f56549a2f8b2131858c22651e19f555bbe6b62e81128984541dd1c4790968b51e6f6f8b4058b310e3524f0b843c9477e180e9586d67800e7f9547c8fa9d75bb7125786a629794644dab2b4d697f173bafea4e2fb9379815d9630d881883ade829f1b43d7713cb4f556ea20a27e22ef67c8757f6674228470177e9ef7ca3bef311c2c62c9e1c72807863f6f0bd0d027667a614b2b882db870cc61bedfc7392890f76286edab1dbba2bf624652ceca1c8a0e4054bf173cf92d552ed73de2a267c99c6497985a08b98dce77f272aa2e8d74147bf628982ae6113877347e972f3b06cf8b8aac0e678592c9e1cbf525ee34076713d5a0a91e3a723ab609bb9123ab02b34df16e8b84dbda2dc184cc8a271bcea7126ed62e56c21c86c4d7cd8dfe25e9f9b15994d7770e38f5cc38e0818283cefaee362fd36fb484c81198bbb3e210d9e3ed5555167efff4cd7317864d9832472993b1a1dd50bef045c7be42fbef8e38e13400ab34a5d51723af20ca1cb50451b8ca9cadd8281fb97c21ee66b8acfdedcc7bf66ea2ddb50b3894f1b65c1f30a5a52ad94f0bd69f3a949222c37dd6e16f6ad03a36e69eb29fab7bd0ce087a8ec9e54beb98fc680e1ce3a700e2507104a2ce4d7589e1378a120f926468dd39c0711958b567f02fd6301b983e08ed2a3cce2b81a15fdec2e8d8b2af45e349fee5e94d7358dbb212c37f751e47f68a7a28286aa59153d997f68ec1a22a66e793f02932ca0e7052df82cbdd4f453bd2f310658a985c35e0949f5dd0e2dc6b3cd42a1b8dc2bf903d2309fb7e2f482d158216c9c572c0d35871f5e8f30b951360b9c9f36c5cf8411acab4357a0c939d8d83fe68aa1be30a686222455c01fbbb5e13ed34b178479aa7d57af812fe3a7453f86eaf1db4765b5153fb738594d9e75295528ca9834d42c7cc8e574766521e34632c93f1d62d685aafc8131d29ec5cc1ba92da3ad041d854b2761b7f8c87add9664ebecde68a456c008b91a9c66234ca61d984de78bb1a96cb581f4721a15a5065f8b5cb033ca16139de594cc9e2428b677c50affb8e1701ca7daa0be8e39390de35656866644a9ead3a01808bbc9e339820063c5eb3358e0237856d8fea6d1bebabec0353cd168260baf6fb3c98f8e4aeebd23f4d0a64ea92b6ce908b7bcb3c4470280a37e07fc1ae5fca251ca227b638a23c77bcdecc6bef7c4755aa5d0685e7e36716e4fbba09ccfeabd9591a480b7afa363eff247e96478a7bc5b5b6ff799324b1d1b4d02bdda001ada861f73d34ae6532e9616b2d1ad676c0c0588929fa08f14375451de5b19cfd21b9c0cedc6aa9d8a1f9629219ea86390a9f701b8de9e4b4cff04bcc9db609bc7f7fa62f666afd849ac1677e882cf6364557a0908413b0659fa53d7309eb2dc2bd94a4427a51193c403fdf001f6207ffbd6605ea5cbd56e604f2d7220c976de52b8f5e39b7e3f72a90c959bb8ff714b06b12a84592a731fec4e0359cdb53c0029d54d9a7075a28ab92b143e39b033f80050d1ef52a00edd8600e4a0c3c8c227f07af71f969ed906cf84e9cbb0295666c728ea5dc10dbb8d27e81c837502b02e77333bf387c4357563388d240234a3f102f643dec5c969e3945cbb2267d0b5db30dd0654a51aee237663dcf23eafd2e6d633474bdc11656b9843295214322b72fd79348fc84142ea521a28f0fea1baadfe7a52f4b12f302b9e34311bbb1a2db10ea8829078babbc1b26a3c50d98a6bace538e5a865799135778c31927902153ef12e06b8738889943f411744d9a6559ce1188cb6b161cce6d606de96f2fe49f0713eed1f002718c5c2150b2cbd5ab777e2b8b9e968f1d4877bfa70f59d27453b8adceb637b7b4b4c7040842006a9dc5124748492af969e386d36d118fe110437b58c0008c64d08f6922d5acfd24866ad20d7b9fad84afaa9a15a369812e42e2111dd0def0ef599780a8c5f9fa7b577389369e4517ca685a160e2fcde1cd47cc5bc4ce907bd481b10a1a8b91b9b6a9440bb907ba3d1534a25188ddf7e80808104209d6a2aceff457ab62527e1667a87921dde35528edea619875677f0d16c148d1e3c68a40c89392a79e6e162cdfa21e9700d948a98d84b80c72bc5d6d86bd234282555ed39c51852a886e31b08bf6e75f98247965364ba59322fdcc0744bff906a9b6fff6b8c4a544f3537b3918a3b079e6a5df59853337f4000f81780a506f463690ea3f07d96046feadec0b7be2dd25e539cb65df7a336af4329e53bcb3708ed5a1e2fdba737dc4f2bb66e587190326d6d774b20620a218c2d588e346593bb9b2b40818f33f606853576c2983fe7fedc362ecc860003d99f8dc43a41ce93265bae39f46c3f371c4b0dda97c700e06727fc147cf722fc28c95e0909011ebea34a5b6c1b80a58ff312f4a64cb502701c3585653cc2b9acbd35c5a94d04fc646e7ef1f9e96436b937f652d42d510faacf4d945a856426ee7df0e4fb0e7b116d2d07a84a198f2641ae52b27bc52bc555bebc6bf6643417640b99c242fbc9738c9ed6a5d16f7fbd34dbdc20ec583001db8f2ceeaff7a9c8aa8e66b20f97fa0d523fbd35ba6bb1b6a62d51bd2b36da8cac1e9bba4566f0b69e180746ec8de5547d24f8314c7780c455b115a65c269f2f9a77ebfd8d011c7b0fcdec9a7b7c86f5058bdf8e00da87c16724fac4d146ecc02cae8883be767fb6e1c78e829219e2396927ab1b2bc3def1a42cfdcdbe5240474dc655502fa72e9eeeced08584edf1f03f128b94ab2a8e9336cede8ea5fef4c49bd654a237092e29e5cf550ff284b5d12e574dd20bea8f276ffe53251547e56ca4cbf8e511e3d369a003fa4d9869a3bc99b10f07fe410cf1a0051668dfd1b4d608c3bacb0add1de34024a5d37676db4ad073a983694fd4352b100ffc61b9b5295ddc9f8da2c94a2ae3025fcb344ea673639bc24263f7df5dc6aea9ed4dfb4bd8256bae274973201f4f70f9fdc636b731ebdd7568dd7dcbd6bda8855a891898d49b3d7a35f0ca2e34c5b485c36c9ee5daeb50849a2ded8778092e327d8699b5382aa72bdcb28c99d992e7700a59c62bce1f5186028102414ffa70f004da7f9bf79a12ce9afdd3a26f5215127ee419dab7de9faa8136f132e8d51f958c17e54e3ea7bc3201d9df814a79780114ace094057031c65198c2b2fe223a47b07550951d26757e8613608329b09d030eb9ecd2c24732322b1c18871976a35588eea616d6d4d1f1cca70f2a3951cdec9857b33851183121da07119c30f4c40b984a90bd03a2a2afdc2ab10928c21d2de853355eca48c9913aa98cde53f19561c454c88e25073e1df0725e5f08090a012eb75c7e0c35705175cc31e05829b8db8c27a3554d5ce19d9d789cf4c49efb97aa6fc83bf565b762c3132ddd4b3649185fc6d8329c78b07ac1e24d8411a2e0a35f761c0fe10c30ad3bb42b35640267574831f41e61faae1628d8b0b1abf35e3470e4d042a384e63c3a7174a57895d441d5395d52e018694a4cd1818118b4aa23c8633aadc88995c332f6bfac8a166349ebfd06171313eadff7c9e27deca63c0cbd1f0f4193762ab3f8fabdf5a149c9cb8d03c6c0ec40e9b78b8c7c95ed762b42b4fa1644a4fd7201bd67c5512d13fa2628acb27171ac67484c45f70e5f20b56282088da46ce92d0bb03dfb15d872ac84bcf7f2b03c2856687d203b5ddda5878bc0313d181531fafe406675f02d47c18cf07a784524116dd565e5d2615fbd746bde4a32a9a0fa0eb47a00ea4f8b8e11c6729c4cec89a09b5ec7b3113dbbb0bd68c29fc8af943312492770e1db2dd2c025f1866ac7b4684919e5b1041146554ef3ed6fb940c60d1747b292b9806e7db92248c3d006f70ba3587a78ed08f2248d21989d614d8bc3f3eea2cdd4f5e866373a16ba2369b3b6d909b3cb597c816e20e4a2bd7d3de74dd640a340b5bb33eaaa6b0c79f67d1b4cfb82fef380d13f71f6f5f0d5c2dc12195b2421467ea95b329cb31dbcd031917a99687efa660cdcaeeeaea67cf60db745593498fbe9aa461bef67d8a3363d00b187a637c01674f77bfd890f1888b01ce30035caa30c54e8f5bb82358206714ea7dee58763fcb2305de749d87b13d40b3f910270e9152bfb17a79188fa470903784c58816201fd6601aa569674ea2ea296842a7dc54b87d8569a21e549614c5cee7947a74a112ca113593af2aa6a3865effc6e8f0fdff570de1c7587ab4b3aaebee043502bc78790f327ed735b03dce237300adc6fc20d972ae01a627957ccd011329643facfd736b4a64087a55d19ef855bd3152f71700644e08e3074a1f6078c7b67e8c4cc11f1b03bcd71c80eb873dc1fb8551f3b2e8ea5ee84b21da54f6ca9cf5c6555ecfb14c18d45013c72f369f70fe57ace7ee047b4f14713ed0199687faac741ec9be64ae1964f823bc912cba04032b7462942d9aa3e1a69b8f02af3c34aca59d87179f44bd13b88f9f74a1599d61ea60f704ecd2031119a5e8a1e27e719ed9195956ea19f059a1f5300ebffa35e72d3db017a30170cccfd961d9f31a22051fb72b2e6c3d9d7fd58b117d1e0a22cfc43c1c43936d04511e5be1381ccd1a6926089f5e5defc751aa54193ef0731c83ed726a2e1d01204548d57263da8cb0aa2ccb3ec1951de75208bff064b01f1414eadc3b335a162eda28958f69d81729145db18962e396d4df01a1ba54047da4da2871bcf00ca8b217397e4fb56bb31ce46f68339d3ab896182cdd2946dfaa7cd7238d3b8cdaa687fafa406f4b68a8f673561793e8c4a2c53f34a06d6e1188acf9453ed290fde14e70fb9445c49fc8187c49428ac58c8308efe059860bd57889e2b4bda7545905b32029f12f1220bbd06ca7b3e7c86fdf715b420e2cdc8238d8cbaa4d7ebbad9400afe831bfe0aa2d5d13cd37b1c67a61bd4349742e0f6432816acb2a74ff89280fe633ee5db7a7d5912e50e2193ecd62e271b118e2567d9314a72ede75edce8596bf4207a0d1d20743c00675a04ee",
+ "spend_index": [
+ 0,
+ 1,
+ 1832806418,
+ 4294967295
+ ],
+ "result": [
+ "37c32ca712f78c0a2b79cf694fcaa1d5b9507f340f7990c9cdaf302e49115fd6",
+ "d35774e6a3de1804d0a272bbb9ef66aad6cfa0d8d85168f713e8564cd6efb18d",
+ "f4542fa05da4f3d65460dbc6d5405bc53e598b7c705522acad7c60ebcefaa820",
+ "8f7e23d545bd6a60f1163e93597898fc7aae20908cf6d7fe8234f938accd962f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 1,
+ "Witness": true,
+ "Version": 1048648188,
+ "scriptSigs": true
+ },
+ "hex_tx": "fc19813e0001057919f7c800000000000000000000000000000000000000000000000000000000e65d7e7bfd32010fa794039affa3f3e9d96e19bd2307ecebc3ad309305dde575999a26b27b4262c84cf228e3ebc3d0d31babbf8759a65d0345a8c2bf61b9be6a2af584ff23531b5bfd0f9b662cb66083a0be67059d5ce61255779f53c7238c3a7177897217579cc2ff1d1eb2f80e29de5e4b2cb15b6004a1a08bb0bcb84c4086bf3448c14432fa5f0bc38f5dcd1b8bed4b5f805a79702a5c0085f68078d172d5b55595f19de6df3d2dd394c7ff16f07d3f6cbe26f016777467b252fea9500ba2cb395d9f7b6f20060546b6794f71875555d16f657502c02256bd753cda81822ad51759b5790ba5107aba32f0a7e91a9e94ca2603cdccbd2ae090cb081983bd3df7cdbea890fcb854dd1d917161b225322ce82dcb199f7cb93f66be068cd96ef99d4ee79a6b53b4c66a22026baa3055d2eebca3c0e582d49a1ff64e11234dea527500000000000000000000000000000000000000000000000000000000f0eb47f700d9b7f0b981d8ee7b000000000000000000000000000000000000000000000000000000003aa88cdba15df59d58b7f3d9273991b0037035c5cb84016ec440c3db710bae81a7a7162f8b53831c32f16337eebe086b882cfcfa56e989e46014e61cfe190f69d2adf7ad89fe29ae997d5d3d83597ee980493ecc54dd04f767c57aa5ff7f4e7d44b230dd4e1a7eb535849e0765430afcee14861640c6897473f36dc9e685d50285e1f431d602f02ff636c62184725e15da9dd72e113086db1242b411a5450b579feaf8b85130b4e2f8167e5f6646000000000000000000000000000000000000000000000000000000001d76f79600962246d98aaa1dc700000000000000000000000000000000000000000000000000000000a8bd311223797d73a99a97773ea1c65ddf29e4e025bd6d12f0d12da4146dced8b40f9e9f58e011577dc0f28e01ca1fe9e7c5785e0bc8fca81f655fb193c3cb85d9a0a1920457a7c0939de6d52f5abe57686d0b9b8b826170729daced19309b4bb74dacfb6d3ce3b66e332f249cb92158e231f79f5e4d13e82fbfbc4e943dfb57e13c68c8d0980aa49e135a53875c0479434684375c255739c8e256fdc943edfcb7276c5b0eb18e9a12d49b0122547c48534013b06ae87b9cfa3879e56fe2d729d0bd7a71c5cd6e9c0fc7021789d634068f5140d2482a4d799f8ba6590b2fbad26afc05ec6aab0f9dd741ece954a841770e0d3e68c1333657fc9ba7ab5ecd03fdff00c4aa694fbf47ab2d7d6f6cb59c44a81d3d0f7809993078acef49a26ab47dcb204acaa9f15de4bad7f7b066889ef08a969153700a1a12e94ec854ff26c73523ab66a4f993ceea341b8fb36ae2d0a4403ee93d6c06793c6762d2b70806d4d1ad1847d0be57413fe255b382af298e4801062f51cf7e4903b80002d75d6472bce7a548e201a54d227b55b86b2fbe4e99c021916391942dd0558389c90599318f73dbc336369c2feece76768fb4ca0e23baaba952b96be66d6f3c7d40bbb254f782e9b1edaad4aba094cea2110a3a563c4da9ea50f579e095d01aa52485ffd27f46f376b8eb5da3922c65ad27da94afbe9da4e2ef143f7b7204f5055ad631740e4ffd9e01766c13a9bdc924430ce32aa146bc075a579eec1d5ab120036fe39ba33b32ac6c5c0280df3b3e67103913255a4f2bab80e39e50f6a25de1bfd448128778d36534b5ef45a35caad784310cc7f60692275c42799946befaed27ce8e60f7388c39e5ee32b00b1c9baf4f2b3dea04ebadc268bcf65b694187b715aa98d2e7538e2b4f5adbefedc18d6965920ac4f97ec926546379f13562656617970b7504351056963e2e8452291b4e26364ce3298a27fc018b421ab2b3c0f4c08215d450194b8ca8aaed612f7a60e2f1a0de54cb616688e57598aa6608c65cfab1324e74580fc44d8763379f85cab070763d4dd177f29e01daabb4f54e4dd0667e57b0ab5fba7e2b455f9eabfac1f6b1474a097db21b4ad8e08c788b2d5609016985b8e1318c431cfaf2897fae7dad1e56e1eb18f95009dab214b20d328c24bd53eea3ccebaadade7c60ca23109937dd7eebdc31149f1c0c425b9b0bb1a09dd937775f284f01c391b13a7507e1b448e1bbfa25b159d6f11dc6143d5f804f4aa40ccd623258eabdb4b161e148eacffdacf6c4562f96147affb315332d094a25fe688647aef1fefd54017218f7a9aed63a7468e04e2e7a5c5101622f2a2947dc730663680943b9b28c21ac147ea83fd2ce98df5d029a3f2e1c49d0bc0b41c65f2cd559f0131eef6867149b72e42f1d0aaab36ba92ff28fe6dbeddc8caf96aa9b261cb9da990f5f11ceccdf6d825634effe623182b2f941e399b0f02be0bfcfa3d9a7f4f7ecfc805e8193974156b1a075104185ab4471bafa751cd0f8b614a25d79e3e5afe017d72b0555ef44264921a5622a88912e19b8a44a403277f31fd462751fc591493c60891eba1ec19e1b1ddda2f9ed1678b612908a65149b34c365888485cc47f4484f6f4ea4ad5dc11b0769bf61563ace4e43e47f3a1d5eb24a96f17a8fd4c5e6a65493010d0436543dabe7ce47a239e69f1724c1dbcca5ecbfaa12ba09ecc6627464e8f490ea115d3037d2fc988df238a3ff0960ad0a2f0a3ef83ab69e08561301f2bced3ef64beb2e77a6cf7d1c8f2bd8823772bb0aaacaf802cdac226222a36df8fc1d2a36e1cf4ad433ef61005e9823c90dbbc541755358ec515ed4ea951addc744c8b49a860718d08aaa5ceae5923117ec236ddd47747e186e284b4cfe5e3be29a1c0f8dd1a4d5d1417558b3652886bc382f6cb99c80370eaeab9ab77ea56301aff7956539df5971bc22dc22eaa10e46deb5c3bcbe7ca9d2e98bd9300d7510b1735c9cad57c38e01bdb9785281493c2ccd5a596b729f3c2f78b1e53ef8c360300ba1e3fddba198afc29dce9ca4bb35c44d34bdb2fa87bba1cd46e8b9b52208c84c4a02d87d57be9ea1a5f8aa2fd7d6ed8c04b73d8dbf866ce9dd25b537ff7aecf7496374da878822c2fdff94a4e4b5f22095ceca58d0bbcfa46d234b25dabdca5f372112a10ba841cf9fc0aa2f98f3149736d3e37f75f167e90728174b74afb8d14951cd217082dc03280db31ae34b71cd3b92472316a523bc8cd5791bd60edcf7bc23802244669e7167f8860d4ffa693a612ea8756637fc03d77bdf806c411aa605c9fc9f47c80b5de79d51780381aabcdeb7d34765a29168449eb7ec25164b5facfb63170002fd77016d0113b330ba114da0e1ec2376fbc6e0dea5d13ccb97e91f07324780f92bb4b4879a4cfcc62e04ea41ede08c420c881ac5a04a5e865cd6f39102fca7fea650f31f1585bb551abe4b51e06d840094620b09422827443a8dab11b89e5174c0a76127231ede40daf3fe062ce63b6c39bf9f502ca8f43fc385624033c874fea14a0bf8af2d0e8f878c65e12d4466bfb1ffa584f5122f9109f2e06149676378d414aa32f5d447553ee69fb5f182dd9038aa7f1e27d98ef5a019a870d7d9b8b0b4ce518f2cba8148a86ee53ccd74abd4f65277387681ff486f8eb9ba0dff07747fd42d64e3e0e9dfecc3c4d2c904f62355d07f3d5bc5cebbf4ab6bd5892667a135ea792cb4670ccb1e85c738638df3c3ca3da23798e3bde0ec1bba7c833480c0f79ca237655867fc86d41b90fa1accd7b0849140188f6acc0e5c0886adcdd0b0f69b3d5e0eb98fafe9c4d6e69a3e6c83d7135f34437712e512410f70487471a30d67191c6a30a75b278ea61fb9fac3607ab088a52ae54a39efb6fde90139c71fb9cc0c673ff4606c1accc1b525cee174b00aafddafd80cedc70d7818163da95f38b887644cf9818a35249058967246e8cd70a5676092757c94c9739190ac66b13b79fa59d86e2c9b100a65229b637fdcc040f4ce14841fa72d5169a4b7b4deeff4cc85ec6f3ccda4af982a3714ae14c6a527512e3e15b7f9edfa51a6869394d786867e946a0024ea8c8ae4cca888625300de49eea2d0c54b73c3e000ffb51671641aefd6089f4aca68ea5f161d60e4b9964f4f6961dbee646cbc9658ac1f0e8be238f0e23c472d699f998b7f99fe5bfa5191e5fcd7ab3cd62c17abf7ea2da7ad384180f2e81c30c347f3dbdadbf88a1fac852b5a0b504e5bf32bccd5b3ac0e8950af75efb1d8b7c2649e433bbe9bfe38dad16b7ace8f94c98002331cfdeea45e7c93a55f5b37a04b790e55c01cc377fda7ddc272efa95ffef7bc9f30e30cfa13ff1f423484b6eada061883bf78f970521380e39cf8abac77ea7f9c17275446031d2ecef94401e1b8573698d1c91decd47bf727f0dad4827141f8fc397476ed00eeb6b30b7809e53f3a0c28f698b18d834513f04d81357319493dad3128881606468978cbc0e7eeb7dc60337ca853d5b577745c0bad4ab4958da54cb44544377a533881bd34e774dcd072ba4cef31837e90d8030698f7aca565c8d53dee22130872b30f0008a203fd1601929a9d48a5e334f3e6ff49f395c0f070b1c6bdd244521f7b465e3bcdfcee15a34a7fa76298ff78037f8b3d2e8813b4b388905da8fb019863d11ecbd5de55b4c87c87d43260d706762ed2456d7dc73fd660e1f843007832b9c1110a73b74c484a89e09b5396ed59b88c56006bf111e2d685d30c45c52e9c95d3e9fb4fafedc73b885f56bd0d5a549de64638fed8e73dea52a27f589ebc61a097e67685ee93af6c34fc39fed019df6a22df2d08d499be6bd86a410a64c6884ceab9552880893b3b34421eeed78c9fd04109c02efadeddb7d7d53f6d10e3add56059cb85856ea2ca5a27e15b714558ce7ee2150beb2774e988331cf48653b85a00ef9d2a1eea097240e36862652002441e51de78d450c382e34ef6e46862fdae015738b3601582b13040b7fe6fbc6de4e456734c53e28f8d14242555d3316b2122e3af0ba377cfbab52de62bcb33dff5cf6b20a6ac2ec69b4fa6b7c2e3ea541c75dc9f2cb85a377c2d8eda281735670d567ac52ce01187c90e4a6a64d5280019f830c220df13336d77f957f2866119453d8505f28e794e7eb4f3147c87a6707740bff8cd569bed1758a18b91294043ca784d998763e7b8e3f40638e4a4bace7bfa0d8c37c1902fd27833e07cf3bf3dd2df6f218990ef22b3788ec5eeb80f6e4e0f1eb8711853fe6abd0e1541768f139ac59e621611427bb155ecfbc29a1e6a89cecde10db352d9e47fafe131fbedada6b88cdb8be8450ca1ffe6079ec465bb0eb09c8f1fddc78b1e3275caa337656cf9d950c07a5b4352dfda1aafdfffe4c1ab0a2f187e77681ccca41dab610784669caf96099a4ddc642f3b25d9f32cbfaf5a7e0fc2be682b053d1ce5852836eb5d92cc311bac97b15644bac2a976cd79b98af208ea418f627f12ec7cddcdbcea2af39f4142d27dc082f62e72dec885c70e5a9f0221b3eaa530682e0cdd94b77162bf7a754b7af5e66235b8385818eed92727d692e663571cfc05168be1022940ebfd5701023fb4b0525dd9771341a3cc7c30e40c4b8cb63b6ce521d5f2dffd78502cd60366ad656f81c062fc9681e816fa1d2996ff1781a7faa15434bce60053911ead81a4276b5286ef6c4fc275cf82f70e03321670a3711debd9af75ffe89458f6ed08030e72f3b1009710065ab123e7c1e0bc59def831366737ed18d296e30f0a0b54864c8bb3ea00f78019cddaed1f9fa04904bd95e90d325ab38636b5ef808e642bf723bd908b880a8290ab21b517edc655fc5e153258247e86da6cc4685bfde2cf56e67c4d2223f4ad1ab281e8fe141770731666738dd85afc02514b6570f443034fc13366baa6d93f21b4c0c4ce3890c2c3318f499143cfacae2399e2a0ea631c7abbf48dc4fadb9344e541733be5a422a2e8bb3e6c191f791ad3436b985264cda9413e1ea3e6d901ec9b415819c070b550a56e1be07d4e2f5f5d69cd0adcc82a02bdad4ac97af83e61507728be63b827bb021c4ceadbb255a5f1f2",
+ "spend_index": [
+ 0,
+ 1,
+ 1745923530,
+ 4294967295
+ ],
+ "result": [
+ "a304cadaef6eb838f6df326869d80c806d58a93cc20c494b925c726352683c4e",
+ "eb7176fffdf7912174e560a5ff54e1ac08395a806d82cb455519c2a3fc55b660",
+ "2f8bf5b54a8d1d4aae6856c708332f620d186e0189330269c20e0e39f0329004",
+ "422e443fc02afed28b59d775310e5bd176429d7ff35bc6cd1023ef209e2233e6"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 7,
+ "Witness": true,
+ "Version": 535452497,
+ "scriptSigs": false
+ },
+ "hex_tx": "515bea1f00010459b69626000000000000000000000000000000000000000000000000000000000dfd2d400062fa8216f775ec6e000000000000000000000000000000000000000000000000000000007b683498000ceaa30783f09d1900000000000000000000000000000000000000000000000000000000006b76d100612bc5d8ad80741c00000000000000000000000000000000000000000000000000000000ac4553fe005ca4b29c073c7a98a88aab204fc83b558c87eae04823febc0d62216f8f50e8d45c6f63e6d271e9a55847541bb8856658546aedd79563eeade644d8ba23840ecd1f32e0e1b9da9e74c6eddcec47c6e547b9d59560d00ba00ea56fea17780a2415c97a7fe356fa79b46df5c74fbb26f814fea704a0afbba57dacd18551b5790668f0fda2a20fe32f6e9734d9ecc8c0f8d356e800f05b40e290f059e2cc0c9408a7794156edeb6cda5219a52516fab0feebd6f4060b5f616bfe5977404f37a0e9cb7b15b1403bd2ca9db8cee82e7b2df1d9c791167727167c014b917e00a912c837957b4e52619b1780a59fe0965f157ea9eb445e81ea5cf2c6b46b797167cf6e590ad4e2fe2f0c0baf47844987b690d5b1a4b433df5274f1c923273c441d301be9077d600861433c275466e5cddcd77f4468b0fa50daee4636e2669425c3f9c5b5e1bf8bb93b73051aec8e11c35d1d25917aeaf4b01b8e203359cff019a9bca8b8faa25a77e6658e1eedbd598666f7cc0f9b5c485bb2d39afd843e4ebb4424bd80d7fffbf8413fa8c9589c87bc230708cc056fb1a47227a44ce150ee65336c6bbb9c143a4d7989a16fd3e91d546c9178c8145678056c75de5e54e71c7116a03d52d470721711d5f062dfe7dbe7961798941445fe1ef4c7dc95f65f43af3b4d13de55f0de7e3fe90b1b75e8fe44a99af1b9cc830ba635fc410b2896b1b92b5bee25cb6f4924cbafff05491b9b50e1ded3f416d0b21ea074917eb30247a725b8ca9833b944484913795baa96c9c9acff901e686c505ee1ccd05290b6c1f69965fe029924b03ea086f772a82f26388cc799d45e6002f42b4bd57a9be968a0576b98bc4de89b67512d4d7b763ffa9f22a128f52de0157bf03b16e84e9445f1946f7a2ac8d36d656f71d1c292b966dc621b687c4f1a40358309363213d971b61d6153eb7093ffb96c6fc53070c6f3ba203be741cf669eb0458b0a32aa8f31c72b16767c68fca193015059a906f877c2d332ddc2a7a9dba3d0ccb42642791e40920cf5c6596f34ddbfc59322cc09c02cdad94e39d7a303e49de3e6e2a54a1598754febccca739ed188a7d60d61268c093035903eb2ee5a754414d9d03ab26d0575e88ea5321154c3191ecec3c6fc0a7e2f7e05351750e09a236f81eeb792c37b8ce475e47fb1c648877abf1ab00f7629685a812f6bc82ca6c53302228b6ccc8d5c9fc763ff2f1dca827ee487321338c90d0b81051ffa2da2370d34c928527ae0edfd5b3f972f4cb458f4cfcfc1eeddc9bdc0da78f416bccab97d75461e3acfccf8da45da0cd56e0e3d9388ceb1b1466d0e85a9a5c262b6e3f5728863c72d1d62b5294c954adc112dd7a6b93099e1157d113c9fb6f5d3aa92f3f90e2fdeadea2cadac863ad304d35d0ca05235484fb3439798b689746018f02fd032bb573808b2709c7078b7100f2d40c222ec9a30ef015a7956e8dafafeea28662ca4cdf117c5589dede37a6fc8823888e2999a853c5531daeba32e578913fc8e49ac6f57733252dae6e208bee83c7a9dcbb72dcd228081172d05b858066a7a8d7e888efbe47410ff0539eb83d9bf032d95a0f705d2869f06ddefc31489c9896ac79560bab1293b7a2b0f8fbb997f3a98f173e3a3cbb29a648128903340642a3148a0a1a5b8f33f615708c5b6efaf4ce13bede2e2751b7a20829a7282b2d88f926fbb1f23e44e26b8ff665d6d56baeeecd966065eb0db1fc0b042ad4339f1c1f9aa091eaeef7089592dba546120ad92d320d7e001a22be2337d5c8b6566c83eecb73af5abbfa7ae3b1749191dad4f5b7ff0288cb2b5373bc96ef8f8f429818ee9489f3fcffde8e58432b601a62465da63ad432490b97f9f83aab7289b93347c00c66ef55682eaa80e0fd3a8eff5d4388b1b1aec069e627d87c5db55ac3bdb43fac73618120d6b6f84c45421ff322477424252ffe2aec5b3bbbcb6536d7a5dc39813a1bc530ea3c9827ad6a474fae6ac4f09ba3cf2197a25870f7dee9033a10a916b3264f4867cad04f970cc3bbd133d43cb50045827687c02add9d4e5ade421a6e021f188474f02fdbc01527d824809c664e54e8f4b2fadaa4371d88b0ee4574ad01bf803c4ba806225aca73e858e12c68e0168bfeae8bd9e5cc961b798f14560b62f6087eda65f94a2fbc3f9917bf685709ebf3280510ebaf2893b656a80ec764f495d47f51649110508ef7b5762633fbeb205ca070869b741716c89859a91a0fabb35b28921b6c5a90a3c21582617039e80b61bc00786cd56bda070f1cacd6bcc92093230000ac7a7d7187997fb5da934318d65547cb9fd6355f34abc588ae76442631d9709db6760889f20df6669ad4e9db3e29065d0502e567197a0c6bc496cc4e9af98c15d74b1932b9e22aefdfc2a70941c5e3dca15b9c83f5e9ab66fd165c857510ab7d1814b562b79ba913ae004b69a048873a83bc846902a153b08b0324188bd75c0e318f2479341dde3ca8f81f61b33441a760bc76745a70ed62858405ae087b6620fe251af0a3ed8fa831cc204103eac583ab86bd8d10e418da656d0b6139e0d4e2fc1902161b6bc2ad28b82f693340ba6e45f3ad13ba8fc52a3a264723d285565a518b1af1fd46d5277f63f159293e686dc767b9c66eb95da37aaab4c213564a6093d94ba16b85fd71a473ff4981e74bcb61a4d7db1f4fa575d191434c10e34cbfdde01c3f1caf949d144abe593b9a52524b3aaacf8dff9a3d4c25fe2076d6a264795e52de382f24afc7373635e26daaae7b80c43a1a285c7ce3598045139742aa3bfae0e4004c030be8254f8c98150ce1c58fdc69f219be6750925ff6eabfe8cf00d04cc22560f9bc083a7483593f22803ea92cd567a1e0c6fe0de2b09170002c4bd5df3194cc29409bcfc88c49248093fc7b2fd1c812a62454d3c16c768cc1de7a9dcca40780f88432a1a3aadf2d6a2f5126de20e54caea02b2f00e770f3c77d64e764854f101c2181928a4ec8377f0fb861467afaf8a32f32412202d69cc95b6f1ea6dffd9f08709c9cafec3547b44c20073c0e2450794dda51cf3be2824bb68fdd4610d671285a1ccffac680f211e37c4074f6243b16c6d01fbfd737eef125e60acbff68e7684c63e5db89e2e056d5e5e514fb897fe4be075cfdd26cca3b7c8a2cf82f0c4e48b96faf04c4cead5380e57d19eea56a658388596edb1ceb3caf2af98d080406d72595df691a785d98d505347142fd7ed2f60d4652e656b7fc912a93f259e0595c7138a7bfccead7737284409b7d1a6ef2b341d1484161c7e069add654b9a92a426eb8408b6a19ee42a4b66b9f6baae81b117899f901c46d048b4756bcc142363bb637e8999079c0c2337100f33c51fba350568d322713b9aa45f01fd1901c919c7c579b233b9eba2cc93ec17504b87f4669eeba782a38c4c16fd62c6333e0934a72b580847d0ebe3b91d6376c1123c5923adcfe1746f87cf276ccc15674a32d7bd26940379fbba307d0afecbf564c8b7e0437b77128fc5e9d9d85ee983cf23d4c8bc69e212f24e0e502e762b418dbaa6b3a801041f9f8f0dbe5a21cadfa2c04675f4718dc795d71de2cc844b4cfb07d62edebc09727cb2487e31c0d908629c4dbaad67df2ab072a1da00b94394ec434993fd89cf68bfd61d7493fdd649574a554ea9ccc9b1aa00fa249a5de7d0895faff2b2d91b89a51d37268ec8f60897ea22986c01edb50372621dd0162879f07b9cf55cedaf153ae14d857d757cfc7e1d365b11101042d2d167103051f9b1435bfdc80670c8cf843100017863e7141ff0546fa57cbfe458455a98cf31ac368fab25a2db87f7c1ae7d3a6d83684f8560050cc8069039e796b68fc9edc1d8501ceb19e6b593c773022adb152397cfd8a9853afbddcc2cf3ec5c85dbba43b57674eb63846265fe477d25ed98c020e88ce914837d23922df78ade825388808798bc5e5fd949fabbf820",
+ "spend_index": [
+ 0,
+ 1,
+ 2274644705,
+ 4294967295
+ ],
+ "result": [
+ "f879ef7cb7f507819bce8d6dfdbe97541312f1e2549dd441bdbfd7ed6d5932c5",
+ "8921764ca88849594762727400d22d26abc18a9d3c960b6888dabf529de31d8d",
+ "510b2046effdf94d4c171282607e83bc20312d9378fbc796805a20d95c97bc8f",
+ "b7dd2560894c2ad5e70447ad231ff15591c747d30226d26b0c6169ce9717c11a"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 3,
+ "Outputs": 4,
+ "Witness": true,
+ "Version": -888944471,
+ "scriptSigs": true
+ },
+ "hex_tx": "a9c803cb000103251b783b00000000000000000000000000000000000000000000000000000000c8f7c4bafd7201729fb4d0f26e4c3e5eb7360935e9bf440566e57bf40f0eeb83ae10b9f435e34d38a462a1935c6b2ac739994d78e02396d81f82c51934aaf5511870351c831b4eb97c9aa6e827ffb6766d4bf10e678ae1e9667df40810132f8421637d4a6e7c938a800702832739d6727198f52ce35df1db5f970403d1575706e2782dbd1c7a8d96d51351bd21fb07db8a2cd913850e818ce1032bd2e048aec5fe9423e86f0ea12e0bbdbc129496a9808aeb5f8439ffcdfadb09b03c3c21016061a559851ee1e87a88a19ba4a3ace6c025bdf4478337fab304dc1291a273df17ad1a3577d74c87af692f00ceefb8ac81c03dfd563f84e4c58fcfa0981361a4ce8dc2ad49ea28792d889f725216f0d15204a6603aed1fc330d88415120f83b839e546935e3787bf483d200af99b9a383200967471068062da36cb23af2b5e902d9c8a35fbeae15814d1599f8d218c049f0f5f3179d680dd29fa3301679cf9dc58d52b2901adbd2ad75f1cfeeaab4be057fd8ea5ef0b23fbff4fde88afef730ce08900000000000000000000000000000000000000000000000000000000d3e5fa947504248cd0ebf1870672d1b488d6e685ab1b2bbd5fbc3c80128dfc342e9698c38c912f69018c7b41c36ee8019aa4f08d1fbf204111061f361eb2e0127be0a7265c8ee7537c68d2f3882f732590e4c63eddeb1ea2a2384b61d9bb25142980b87a45a9e3ae681cff259e230f15235b5c121960fab6087415ca96389938ba09000000000000000000000000000000000000000000000000000000002ca13736fd0001a25993f1314f5e0c90ff7040519a16b00a0cffab57dc7f70b91c10e5f22faefa53c4878ecbf5d21a77f72888e36074a83b8b444852c0f05ee7d19a453c0b08d83ee2a6a326322a195a47c1e2f7524ce5afc13cd1fa14fe25df6a3e66a4cece3a2cd54a0b5f8fbf37d261e9e29da3b9d3702865b39d3ed4292c1f48d578600134df0efb3889f22a88060838591f2b142d25117627b0b343aebf18010557e611373dddcc4d7f6411a8c02c593cae67240458eaa6c833115d5e4b753726a0739bf26becd66db413dc47207e20012244b171b12626a1cece8abc3069ad0d45d68330c46269d260421e310c0a5a4a5efdb1555c79536c0811a642fe96d9e94a5fe910f60dfdb104a15c9baa71593917c84fbd4d265d202b34393df6cde0f53f4ff6ed825ebede1758c6367907ede27e473648824cc7853ad57d93df391d857678ba09318a8f0bbaf3905dce6ca495c1e96c77ecb3dcce0131ebba23aa297533e47ed3fa21b2e6119caf3110b1d3db806f823c5b943b69b2c1980beefa82b158531812291d74c2695fe517fe78b9b6586a1d64e94a7a9b1e75ea3df9815d60657abc47cf5ee9af8421b07ba66165ca70b3cf2390269e02d147258dbe9e9fe0f934abc38a870a31d77c97bca4b0632b606fbdf08a3a6007234e4db5b6ca246f6946c8d968dde8a10de3c6c0c6e8629f19d1b3bc51b582949ad67ea54620e3bcf364906692162135c1da48d2e8ef422cbef344b9a4d0b957efa77ca5778ba95cb628c541706b148b4ddbb5e4b340a5f816f21905955cadc022d10389a356641e24c429baff1db3b30ecc6ab39dfd2eda6a6b3fc89b955be6aed5ff35888de8b3d1a41ccc86a62166a610f4a831941bea7ae2d30153071a7a9336f548c051a61d58915f2494e9102e0fb37517e69e35b41216a02cba836354401b5f4d3bdc6f5dc15bca49db4dd953a5c25cc34728e988959e00c80cfa8eb6968cdf0f6c76496397902420c48aed0fa610c4d518e8e3a8ca3e33148292c266dc2c2b441898fddec53a6295983f97ce751dd0dfda8713291be81ce6d12ad8c4dfeb274c33c323645fb78fd11d63f3548e275fa5b7de6720663c68160a36185bcfa86ca4e648cc7cac31115b04e55b590d451945eb28e787089afb610a1bbb0659dc4283a1130e3db593725ab2bfb98e3a3fd00f05949eb566ff8dc2f3788cfd1c11704fcc9b54a6da8daf265d7811ce9a206b220d3c4af63a67c5a1cf2c2752ee0054c4e2e8c6d647262b57c842278985faaf1a8a567fb2baaa7cebcace1c3b118c75a695aea39e91789a3b68d1abcb82dc94904d7b25027c92b8a3761106d9f1772cd5068707c4d7db9493339a9f175c42e113ddbbbec61db98cea297e0e48044a86e91153a13b8b8c6cd870ffe44f6f5f0a45971a0f8f7e30157855ab5168b9eb3152b45186a2cf2e82b4b2854197a8268dc2e90ac94245aa11d4fcc2016740bde768ba2de040f1cebdf3554a9492a83fdd76378d05908b4031ea74eb744878c31c6fd508edb5d76bebd8fd9ea1b35fcf7aa5850183e7d5b779a11eeef0615ebdbde6947e92ca39912fda2602c817e018816f729d6c093b201dfc49d731bdd52364c128af248e8eea1a09a86ac386c92fe71dca5c357b25b2d6de613b0f6b6cfa538944a58d3b7ea987a78d33a0e6cb371ad862593b36bb336a328cf655be8b6f130010d59b9a02543b50bc152874449a2d50310e8d335b2b01e8996e04865917c6344dd4503ff6f8cbc587f97a8311d82b81bab515becdf3dddbacaaab967d65d2cbaebf8a3d2fdfc7426bff579ccc377a3a1b269f3d678fa03a1f1ce684ec85f3d8ca636c4d4f0caa0a87fd223a9ae4d690ff4cde281644891b3b569aaa5258fade59540e96594e78beb8160339c5df01564c797b9842fcd44b0ed9cc2e3d78fdc249b4abffda51b8f1e59737b520eeeeeea89231a3f5f637468520d830d6ac314df4e81228bff017834f64d6789ece25cf47ad5f9b72361d41f7b164b26141b2150bac4aaf56c9d39e319a1822720f5f97da745f299715523b4496ebbcf9b8b0a90404ff05604bfd4c01562494a70e34cf93bcad4ab44229231d261b15da497df316a8a226db63428dddd06aa6be8ef94f6a4f97908af6a4657aaf9e291bb8364cf00e96ac73ca638c25a9ce35a686e4483b4a17a1c11c143fe0b2fc6c30b50843d27402b1f6c5d5ecc474e239b22f59be749bb37a453cdc19fed02a6273fc85243eb20c453f4db442ae2b193bd9f9ea8da49397c0adcb2a267927561c1b706cdc6e91c6358dbda5951d3c4586448b37743dac2bbefe3ea79b3c453b30e99b1cfe21b694d85ec4854057ffc8cdc71f6bdd8df96a92dae2197fb1251c6d5ddaddf0125fccd569305b1ccb4b4fe6729edc18291d947faa64f7afbf74e0a11c0da2849ff4444eaab1e296f9de81b6879c0d6e14630fd73ec47b0c5808f7445f257813aa12202748a8cb65ba35d6071ae50cbe5f9117c78c84e389e1105ff0874c19d43ee2ec622204cd43e2e81274372407dfc7466c6bda6603ac18be46e527073972f958aceffe5eaa9c8d2101ce10a79b7a77df95c319e354db74eab5960ebe5426e5be31f9c79595fc29dab8ab1e40cc1f52cb2b3adb4c06719d68fea391ddaf9f96c5ee18e0052ea48e4f7f0cc7f792989b7f44a3856b06ddc52a094cc5a8fb0a562a79ce1b92178f57680f8124236d40a0e0b6856dd78d18b5ecad5c4fcd5abc3996b29ff8ffb1ce7c5dd877700e6ce9b2a7e231d5baf9b1d0b163285d4a0fa02f5ac93e726786202d5078b4fff0491241d7c7d945483e17ca661eb81a5045b7ee6b4e175270f249081821f7440e963ca43f0b563b2124ee45efd1ab7c76de79264fadc3b513ea641034a11d7b294084d9c4a31556e8cea777059415be90302c03f8f0a21ec651dc1bd0728589738cde4e30a9daefdca882aceadda3850eea452a0c356fd53e",
+ "spend_index": [
+ 0,
+ 1,
+ 1153863276,
+ 4294967295
+ ],
+ "result": [
+ "5c8a06db6631bb164a1f5ceec23ef45a0db6f21162d737b94e502453c93ef43b",
+ "90c55941badef257688e2516eff289b8f0f6d7d4f59392e6c2ab23983010346b",
+ "fb1379eec6a0604e711556897ba7af46e15adada80d34675964b20a2ec4dc52c",
+ "c6f673a6d3aaada09196c8bc72bc63dbf0657a1e623370397f2fcab93f19f61a"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 9,
+ "Witness": true,
+ "Version": 580803147,
+ "scriptSigs": false
+ },
+ "hex_tx": "4b5a9e22000104c65d934b00000000000000000000000000000000000000000000000000000000bf53673f00058019c490910b2e0000000000000000000000000000000000000000000000000000000086ed708100922d724fd631303a00000000000000000000000000000000000000000000000000000000e6b4819f0035a755681a1881e80000000000000000000000000000000000000000000000000000000033da8854007801ad48096dcb11c966fd0256c8fe93130a73f2a303453dc954b465760ade7ad8900c35cc91666158e193bbd2c41be5a02519bf5759e47054db65c0d2fa395c0ac8f6d33a850cc3fc588a1432af5ab6c1efa8afbd812a7dfe0f4c6e22b77cf973454894ccd88a9ab6c812e249515efdcba78d830e27c4c0377198e7a3bd64c4a8a69fa21ddec9036baa384d1980ed9fecf8f54577559e9119f806a65570ed6ef54c56d0054b550675b7f18e1ac4ef6be2cb82b3c57bdc92aa273ffa0116450e9454c450a9e28dbe68ea756700c50548831e234f5beff8555cad7620692bc874d6d18d402476964b3c6faa9c39772e99ec65ced20b421445bd577c8316f64f560e278dbe89f595498fe39405c045749482c71f744b94804dfa414488cb19c79268c47f8fbc208f71651f4bc7c0edd892229a624ef8d1ec2c39c4cc76323f984cb2859abe3e5535488361e6cfeb9a608efd8b11152735e7114ab9273f96a0fd4b14b5f27d8a646f6c6053b3e62d902f7ef559133aa7a00a408f9bb2b2b1c659b484df8762a93a8acd67bc78bd0ec14285fe3e0de18cc30b74cdac50ddbe5a274542fe6b26afc17acd0921557907e257c86381cf9e0307c3cd37b63b9acddfcdeb4fda9cc1942268641d5ccf320ca5ce28de57687565453d385c90d84127f0004de6d7462af9c400a394f623657a0f6c9ce4331bf11cdcd56a8d84c45d249c21837ef50d348bcd221372ac7a3d4c79b29a20fa290754980c96ac54d701a20754d63c4a9a4e065e289ee9aa02718d11bccfb61926d4bdd165d1ea94ba55342968b89fe391dfa8d6fcdaa4a7d1e23ac230ab1a3ce163692422da91b80f815fa0af697d40f26b304cece4e399ca9bc79874327ec1b7402c2e338df54092d6419a554cc85edb919ba3fe6ac556a03c8e21621ea1415aa6170d7724a3ee66a1a25eec67452ea2f0feb0d6a8973b916e259b0868a242caa425e9e04e629985a3d3fe6ed92e18276d013ee33765ef03c66b98739303a8f0121ef2e7d49f84d578740f46ff60fe7db6dcc71f27c5ef2177e90645822d512cfe704a5e7fa8d8241dd4574bef509b18581f5b1ee916130dc89e0efa35beff49077f449b22f9c1d8712312612d2c59eb0c0f19d138e4345eb89892aa037d3f39a8dfc8cbc2d034be9dad2c9360012568f7acc2de7591dbfc5ddf15836f1ec88f65073e185a60e1c833664f3c843ec5cd7b52dee3035dea7bf95bdbc7a6ad865288b83dd7d446ce4f8b543b790fabe3dfdb90fa6082e5e9f33d343aa3dfa76d0083ec8f398e193ecdd8bf9701b539caf8f6d7eec356eed95999783dcbc97766de1d93e04e5166748c80f71069d467485c94d4904216c6594c7698119c95418d84fb2e9674f2098dddd439ddd0dee560d5370b40508a74f883cfcc6ec1bbfb1464bab1382b168581484abdfc16fc7b21d18aaddc42e05b9de07645ad36c5a3fd2b34fb1d92b47e64dfacd23b8bf3a150c8131348eb04f53b9104ab0949dd2de77d3f881ec5963d6a05ceb5b657fd950ac2ee021bfeb8c58cca30bd731c2f41296c821af25a393b5246f6ff49a5a2c56f9fb882a0ce5c6878f60aefc598074235fe6b55b8cc59e8cc92788f2022688e2b8828c58d45f7663ab1aaf5bf66a11f07632716bb503b1c6b3753c6ab82fcbaa52a0c30e8ee6fdd769e21fc7358c4e3e65f6277da87028a49b8b985b7e0a9fa302393f81f340a70a6ee5127ba5711e351e67a588433bd14163d3ddbd41e88f79325d6436c2289cd37521739f728f5caf35dc8fd6f134f64c62155ba9fc49bf3e0113096b42b938d17f992f51facc4f5f02457bbcbb8090b72a0effbc9146cdbb640e3620c33dbc38726a517ac7af05242314f5e7380fa4cc40ec7a9a2158e26c217cc51eb7ca093b6425e9ecb64e0dfafd4a7d05a941e9abe755fbefa0f44e047a9a7ba9f29fa0488de73478c94345c55d3883641f85e6549eb407b7ceeda048bfa8b5711526cce638aa8c7722816c9202ec84940abf38ae4e77172b4792118b674a842c0be40058d856b44f18e5e054cdcdadb38d143d62f18df307817955888565ac898ddf2dab2d813f2b1bb762d027660387af38882b92d965c6475a9bf0b4a4023512b9acc1767c9d385972fb000512b44c11bf1c3e5a7f263b61f61515388ef77c8bebbdfd5e858dd6115c154a8031c7c2a2dd6e2b6f2b4622e9be8cf339db0da594782498b950bc85733c2eb12491fb881390145a499c4a3b78503e9763ff9096e4054a0e343d247ae1bf56b2082e6043fbc7d0fecfb59196827083c44ddee9e21ec18e8600b38e1d4a56b564beaadbbfe99a1ac774fe83ce7424dc5267155a13a38146b701ff9c37c4381f0e5aaf31bc88d694a5a978f71a9d2e536da58a64375e9ddbcafad8aabeba5f26de48458cca691e4cfcfaf26a7f73091fdd06b7ed4ad9439873b9c7350bdc4d08178bd6502ae6b22f3d62655efa5f973012930f6c8f7a31c70dd7820dcfffd3cb860992781e730d9fa0688cfa6f8496356bf5facd6163a27c45ce66cd1335bdbbe139d4ec2b43bb2a60e12a03cf4ea045523425babcbc0f75f372f53a6ebc6b55f123abe5d4490ba62b10a9c0824a2280be6b8d0d3b67f9a18b8a8d83840c5fe44d9d13b9c99e080c569f379b4c0033cb28a92279718c225ebac555660d044f51e5261aff8bbe9c7a4571d377b111950b8dec8c55baa839b8b6cd2d3598a422e8fe482a1f9f18b5826bc3d84fdcd018394b85a87880c92caebde41be7e325ee598e0ed0d92039f1c6323288f554d5c1a0ee68fc764a37b3045393e500109edb1e1642e0c214f5d447cf938a5ee02699ebd8dab9193f80ea4efe5c5e230acb8b19b09ff21b478be15059aa6d5efa8e9546baab46a9251ed688a30cb143bdd92687d42f55ea112d0cc25c9e7d03ef7c6c551c3c44867b9fe4b4330b49a7223874304b9848396db39db404e173a6d9dd34862840fa6b406be38323b706a9bca9f9e964c2d2faab77399588ecd507e264023c19c53107ee9494f1e229fe44a808a323f863663cc9d1d397dfe39432da73b83b0a892d468727cbc43be9d20953f01b0d3a486152da5862ca258fb38e30ac01035d61c21f5ab45b6dfb51c478e35e567262e242b8b9b1e84fb650ee09f251e4feeed16ef83ef61c3b3a7fbe628a05577b284167db82452897446be681c855e987c2dd5334ed5d24979d9b7a19ab43e4913d815ab24b3cd5b802162e66ac3b05a77ca3b5f86f550f63b945c3bbeaa98b1b44f28c8d26aa1ca3181a4d3bf4e209b451274c599f5ffab358634c7835b8161937352cb9524776086c6bf4f521bb4e1f9ac95a8b77a4dfd80c02aa03e4d951a0bdcfaecb466337ced74be5092ed681d700e69413b9a3de7c4bd5a41fd6b0157edf746d6c5b7e04bf22453cc2f497aa5bb014972ca85145416540b6016412dfe9e6ff2a9ca522849b349800287d3f4e67c969c6f4ea93748d8de5fe494a59b2da1be863937d50e175a54b1fcb092e95db4756ef7601fbf5e52be7ac3c3550fe4fae6e865def4b7597780d2aa5f99b3b3a9415df887185e31d4ef5cf80a13034568313cbe0282b8057e1c5786b4cff765250fdfd0bde410b88dfac0ac3b32213743887eaf44c27bcb634979c8969d4c769e4ef1bdf632a72e654f3eb34bc69977cef88869555d6d3b898ea46c9f6f571a2b41c87246a4d1fe1f44438e683cb63875ad2422f3bce6f310e6aac1d88fa968348f085aac0cd17c7ab79dfda29de07f8d968847b34c75bd6ce8c973183f5a95681b8ada5eaf9f4041430eb1997e96692a43ac4cbd4680aab2e67e49a37b6f76887ab3acc8ffe6b680117f46730c06cd3ecd8503e828902e97fc07c2b3fbd61f3c566c1efdbdfb2ea193afcc9289bef4e74d9baff879382ead580004fd4b0120f8956120f011da246bbaa1af3b62e78c9a35911515b3322cd23d0e56c4e827a0a9e83fd088c6f08fdfc59bc55621c40fa8841b9291dd40f13a804a7db0777d285cd4947e7f6f83f7673aab740ea69d5a265e5d303585332e3cd5300de52811490316da607fecea530e5660c8601ce66499657feb1cd53f4dc1deb7af6ce8506db0faf0868ccf4441b23365accbcd7045baa9e0cb3dfb824689750f144fdc614000a51b0d39217704ce2b53d7638824c6bb06922622e07db5727c1a33705087c7576942ca03162e161e1a0f9df27fc12028a4f8495bd9f3050b740d47a3b675aaff8734d595213d58084b917d1bbd3e1f204c1af9ccdd9c180b10fdec6564119d6302831ccca8c60450d6bb670f0ecb185b0fa27ead66266e19896ac4d4087a18ae159fa622c400fdf6c88cff0a016d788d5351bea2e51bc8788b08e08e486e99404231289aa7ed4e9a59fd2b01b3f52284c1b0ba242eef612e8cd93fbaa20dbc29ec3d571c02de4592e35122cbf251160241f47ce013a9052be3c4ed3a80035408a5df87518877172e1d76e576b651feb103e81e446d82f8ee34f7340cff28d2f44228a9e9f3ad1713a384abf39229f8200e025e09284c4e93411c04ea1a10b871aea77dc155fd272b94bd2c60e858194842bf8daf8381c747ed10289b83c0947a6d6e2c9d2b735740d6560af9e8f75d2fd4e72df8f2ba694274f4eb84edd48827704a28154032dff2cd5509debf795d80d0d1f23bab219021321d50c774291d99fa621ca6e66bf6f3eb38f2f5476830cd5975e1f7382da2a1f4b27fd0cb517e41e50633f370705ca72dea4dad03f12a41f051cd31a1fa91c7dda603eead5394ef291e4c00ef4b205ecd949c7402bd0983db716c38f974bf86022fcaadea58223f9aa1ed4de669aeb7ee45c26cafa185d4ba208bffc952de67abaec90b263fadcc5c884a13eeb446950e949ef3eb9ccdefcc461c49159a18035a16aeaf16921ece02ba62455df77a2377b83f0f509b936f7ed867d7ddbb1f3df288c4fc9b3cc80f96bd607fb3c84807a83d610f1645b6aaba175913384911621980a6e3e531fd3a018641c629ad7fb6c613b42f9f6b7de2adfe2a4d008d8dd203a5f8c293d1d6191c728cf71edc6b0057ba8818d242dee43dd02722142d6fea71310ff0f822b6675f2c4d4b49ca9987b067d7c094304295b027eb58e9fab52cc4b604d56391b29cbce2fa7649a760cd8e221b878668ac6afcbe3f35cbeadd9d0292de04407da3519a185504730c42c90e338045120774bc3856b0f4b97038218a0ed0adb355650afa77b08270cef2ff292e0e253224d9d9a2a54da473b02afda724dcc79aca703022f577049ffc1584d4edcf803b17795082cd398613c7cd1cf4e04065389c43a1b0ed11eba916a17cbfce8f3036296dc8377ae662ec2b25bff9e2c0020fd888674bed90ce5f5b74127b34c6e6867e6ef167e8ef346c9f87fc8e89e983f416e0394f8161f0cc2c3ecdb5671d4b202f4aa4b76cc89bd9d497bf2492cb03c21bcaeb0ece7aa1f1c9040524f218a95b9e1e4cf8b0e33cc9ac151ff00bc9c25748a90c7843deb84487163eb12b752eb670a852079394da01042def421bb8e6ab133663fa9c46df43856e06d08ece1d2f518b4e60bce03039736ff60d1bf030e454b845cb0b2e38623605e4924bc98532281194772ec6988b0bee8142acc559ef3bafa6461f4445e6b2ac2307d7f48fe70efe6ad8c2fa9a5e80cfcd8f93dadd55917a054076426f25b60b09c466d0fbac45fcec52267b2da9a76731bd9834c7b9f67bfd9101ab8050977cd56c6551f8ef7307d978e9ac8fe1eacefe970a29b1445f18e6ef70faa70d5c6ab964b66175e7e7271ee0ca85d034c56ae9f374f9136cafe897734749697db9c9a1c20c6887f44050164e54081daaa5f81d3e706d918023b449d252e718d99980a08eca45987412a99a0044321c82472ad2655a1d0f537b9a312311e0f5f045579b2d011ea21908938a33b45c5fe32ce9fe3ca5b62ebd782f08b38f0a196c152e8e117c1075d3c4fd02e2e0d36a3b0269aed464840dc687fb385e32750addccfbfc75ebbad8b05a2fb8a40665a516e505ea9653cbb0be63850aa49067a13a1b55f6f625d1217ba67afc5c4ee62ac7d38bf368a4ef915e08878e2c77e1a5e733dec8e0d98c6c58ae6abb1f345cf121b1b47abccc6f388ee7f84db7db7fc7f1b2838e41e634e0d98627878e200a3c906dbdba79d31d205baf73cc60f07fd0458267051ab48293d5145b2f0f48e46051107a671570171c48d69ef56f9fc982d360da9825e2c75e42dea21022f6b63bb3d2606ec768e5e76aca2f0ed3c5024a10396bf397dcb73c72a9e85e0d29cdfde4016b1fc6c6df04413d2cf71f573d302295c3eabb06b19963c2725a1d96313e5b6aa6df04429fc61e8dc971301aeba91d5df5e78338b37599ebea007116805f849668b08ae005ed60ed21380c1423deba0946f96ed87e6fe7364da77421b08abc5812c7f01c60a56f4e6f7adad3d7f9c2750fd89a2adbcba7a8adac20122b5689a04090640d71c20005fb5b80b6ad0c6b49883cb5cd2050dade8beadcb271d7c33b7e1fd1b2a94c294ab10a0abd4d6804e7f9c5fdde9e12274da8518eee580222ee582ab0b9f4c357860447a1693dd14e1fb284aa6a651ddc7f2c942453ec6ae5d16634020390aa8ce3d681a2876eac4cf42157f48956f952d0f05437ca5fdfea4c132a5aee42189a667e171ac6c2003c828864100f90dcec8dbf1e11d574d008853961d7afb8394858f370b96f731b862a44ef43d4161aafe08b3d4ec58d23318f7ba4470269330c8fcf04846be12c291f85b38242913c36e496d99b5fc642893c76498bb09b2b7cb620e95955e4fec18df39e626beb790a812ad2671539172ba2cbb022daed43349e982305e404bac7ff698027772cb6f24e3747376a30662ed88dc797f1c3ee137aee5f33eafe19c3655df618c1a32e8e16275173dab15079c6cc88c7f055f548cc309087f30cb788516e69fb3ea9ae4b00b1a2a323c40e78bf93538be6caa0304a",
+ "spend_index": [
+ 0,
+ 1,
+ 2939854918,
+ 4294967295
+ ],
+ "result": [
+ "fcdf47a1ee4ac0d669e3f28b02780f79e19cd82d966bdf50f9b767b76d59c471",
+ "f8fa3225821bd05cb845052d29b83ac971602c314690dde1b28a83dfdb9d475b",
+ "822ab57d856af2294bdb1f4609c36abe15aa2a01038d1ebb1bc6bea6e3bb97b0",
+ "bb3a5942ff153f6f57b3db493e78e3a3e591113a563abbdb18e2bcacef8b3773"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 7,
+ "Witness": true,
+ "Version": 1953367418,
+ "scriptSigs": true
+ },
+ "hex_tx": "7a056e740001098bcf013900000000000000000000000000000000000000000000000000000000d555310ffd7c01ea056fbf3fa34a33ea5845071d769bacdd9223b15887a365d5735ac9fa2aef798d067e0e48c80a6ce7adec80a6677c0a8fe36d685e7c97bbd10496844d28d72deb185934c6d20c84c5af23ddc9e10bf700b7b46a587c519a097e04ee57ed0d62e1b1a726df811d81d84c4b7726369c79710ceeca98cdd7bca2b37226eb1fd7818346590f2ef5d98d0b789bac830283e70926330912a20309863c3d67345a2dc35c49634df7b32ff3add43ef19b010f59b252bf286b28d91db3c98bfc0afadeacefa97b15f20e9a7b7f5f10e60216b5a2b40e72b2c142dd5cfa6e19c7293dfcd38a944b89fb8168f6bd13fc45d7426685c753613feba034cbcc46d6da0e9da4916bcc68058fcc291f8c68fa4fd07722159ff348c2888a6cb1d45d1de52be4c3ccf22de16fe6a3be6b46a44a5e516de79ea39e00ca62ea08a4b72b7ced5fba7b172b4d58413ac4b298f5eea6ce738721008f3c4baeedfbce01d31c20936b36274677fabe387c973044a927ab0949f1e70dd341a2e010647f519cd8020a8fa998e0da68ccfc000000000000000000000000000000000000000000000000000000003a158ab3fd3b01edcbb535d5b64a7d6996bfe17c58e2a5ebd3ff252642c05e2e1fbafa1d0b66fb4a28a56b02f0d6016643644b5be63eb3a5343c8cbea11710cae3a1eabdf122ac1e567c6b3d415016d06aab5349b0bfc7685956b87e89c7458fbf6b86ed302cff73dea07581398319e35676b7ab00df8b8c7a250fe7dbe0636f45cdf9865da0f36f5c613a60b4805c6cb0a45b3f4955839856f3e34d629eca4620b7095071884f6e07ee83afc2351c9b87073a80e0fe196826626230a61a2d250b4179eac303e627c462daea938c90e0fdc82a2f1620a640e3244f834ec59dad1195ae888c97d6c6028cdbe2ff1e185825d3dbcbc5e3e0e0598d667549041377bce0344ba166f4074168f787ffa1cf1e9ee03bb32382ed2ce2949f7b6ed75959f48acf0a4bdc1b154f580874a78bca650c38b728d19238e69170440273fc405399476b07aa086168c99c000000000000000000000000000000000000000000000000000000002ec4eb64c124b4d540d391e34f4f6a42457d87c5f45bc7f8c1c73bf51d9bd49e0295a19a76f17698ded03f2fc58ea2326fd623e4585843b105f2dd23c5f92cc350628a4bb731951234ce97b2a2b6239696425120c7c79d071b1e12e88394c72c0b47f7ede3283d8620a912909d04ccfc41a4ffbda31d7469fb0076ccbaf359d197a175ecf368ad278f10eb6945842710f816d50ba0ff0dcddfa82b93a926f0b7abf534c162915412eb37a177311ed1b4f3832f8741ddccdba7a6fec008eecf80c915cd7f6f23b893eddbe2905bf300000000000000000000000000000000000000000000000000000000deef88f50a4d1436c03c15c54a01e47ab0a19ce75ac398000000000000000000000000000000000000000000000000000000002c0ad335fd0101d18c5eeba066aed82cf79d250f693e64db9fe9bf370b6c7d4b83a73c61fe3e58dd94960b9c084720c4dbaa8e6f1c6477e341e8fec705f1fead295aba3a39fe8df2ecebedaa5ef3f625b9e09cc81bae99faf232326c4fb9574b4c648916a33ee2a9d513d2c581ab688a5cb2151fef7a1e7ef1efe1969fa86d0564a89396cfbc3410840ba73cf10afcf8603398494cc6238be2dbfcf060a7b80cf8590aa8498486c397e88d947ebe733b1e1473db3c7e35463d43cb926c9e226268a9185e490c39b4f2c595d1146d4545e283807225841a84afc241c1462757fa61f8166141510f6c0dae771ffd5cff4fa63ee57ef9df0e160132a99cbfa560d6f0094fb51db9a58e078c6b5ffbe28cb60000000000000000000000000000000000000000000000000000000043471405fdbb0133f2194de97ea27663309e1972d1124cf6d7529727a99ed9ca9b4c23f190710a5fedf38d07e8b9abe3753ea6559bcfc9ab1778d2640085e78db387400ba692b3a70c84956ac0dbb27a1c5a668a3230323970d19035c28cb05dea6f349e48411f85cdd607654217a3aecb8b5d9d027fe7d52f01b44eddcf4399cd5e62e2eba24eac0324ea405e9571c35b193ee907e45a2d3c4ba062eff6fc3196936a96f7a70a2fc350f72d7d5a0fed32f3222c8a45da5cf37707b3ae37ad0c2948e4510f20e83ddb12ceae3a607c631a82fff8967dadd85efe046fdf51361692a9f3cb0e0226e90309f21c5b76016d9c83c80a290188602ba8d1c85676b03354265148befb04e32737b81b344a0608793c2bb3232d18f560a607e557cbe8336e4aff395892bbf1d459e4ed3c61a57e19ae46849e63d1335ce19b656cfc7b366f89865403bbe44697311623ffb4c4967d190466f5e57d85ad9588a40ea9df468fbeff09bb1b30e77fb12caa074e1deac70d32e51ac56fa80a73b45c94a730cb5399ea80a0aeb6ca1ff84b1be8c6cf5d4ce1f639a26b640d993255a9a40495705af6f08088cfdb902f8a63cfbf1a7d305946704cf51f7328a470ebcab3414201539403560def7d73d885000000000000000000000000000000000000000000000000000000005a17a5aed9e7bfa067da9b2728b085c6698489ac84fce97583234b2bce8b025df43903db6ea89229b14dd458ff28b3ca944c7c03c69de8046dc43b8306c12c7b9d04ffa1b7b46b8bc06fe070433e98f679f4d6102bc804524fb69ca710920443b2eb018ad58c280140e188e7630ecf759e941eddc40cc6509e997876b4cc95d3b93ea694a53f5bf2154e62f45cc7fbc53161012dcf4a36d205137e6669079f24c8fe697ca9bf295190d9fee3c87e57c944a3d7f7967ea26b7d882d08a0af67c84f35f79312d3e65ff491ff8ca48ef9d52bb07d9508d4ec962675ee3f5d51c129e23f69f1eed2000000000000000000000000000000000000000000000000000000004e14f231fd4b01bab43b885e98fa91a306c49a83f2fde5d6b565b2e92115956494dd265dc32297acaa5aea6dbf1c08961484cded9936c3d454e959a1845d12d847c4cc58da82528daed5fd5d36049c38c5197026ebc3b1695c67ffb3946498c85861f7883be6ac36b51ba714f9fc6b128eaa06244f4a5059ec01227a7c96955a2aed854c3cb235b2a0469e3e9141501ed55ffecf01f112c78466578136349e942eb6f49fb7d8a8d02329990ef3b09ae966050ebcffcd18b96e82245a50731d483e31e7aa71d48e114849ea12191dc800189bfb49e1a9dcc7c066ebe4194cc10437b1fe7567fbce122cc5a7802fa2be59ecf276b80c9f736a15a563572ad86ca2e65a5f7db89a8c8386197161a53598d01ba553af7e3e8d4df7525ed51f0329df19bfe09ffc5e61ec8990dba96c0624f171415c31be1b4f22c241782fafb92bc1f3848c6cb62da62e8aa8e84ac189b4f9ee0868a0447d6c93b3df000000000000000000000000000000000000000000000000000000006231097bf5c68f6239ee9ac7b3241cd4e8e035d2eb5c2b47d34e9fb6dbc6f2632e09789715631a0902a22d6634f74de03b1109f9904445293102d332dbba8a33aaedf645aa6c48e180ddace3cd3c1089c4ed30ba45e650cbe0b974e5ab88a18ad86d568cf5e59f28d80a99f352388cdb7184e15b63b5ab596de74592d64136300639e5265f7791d779af16ecfe00d22599e6ad4722aa6064cc44d7300f6da03bbe4cff1d216da1908a6ec573e661feeeeb170ea28076ad16e33e60a9de378120616c2a7d0b86d40aaa6c18fe469bd52ad59c8a49f97cb7db2a7c59ac2338f971621ab2fafb5353002aff8908610d980fe9187de1da45a37c03f90a1754fc07c8870b9417662470c88b09a482877ed9c2f6016dce329daa87cd9a601fd13bb6517470081705ff21c69cc3e052eb9f945ef91b62284d6b1a9145624317542c79dcad22306be86837318d07c97f398f0bda29a6ad0bbb38f52345c92d5ea377b81c8b59cf2f00850ab79dc129885b1acae8388867de3c64aa5fb867c3eca6d9b8e82b750f40a248932e068e2c959bb5ad00ebb5f7ade72ed6e6cb7aaca6af49f20b69acbbbd1feba026730f3e96a57e4a199fcc2bfa1620107f006a3f7852b24b9bbd721adc92f330121dceeed778395cda3102b85f2daaa83ec85fdc422012a0c63d1ab193c9548ff5eada3393d89aa73e02cfcbee0197c47649b55a0f1ba0b53774ea7318f2670920f5a3bb16a2b85cdd41612b7c78514334fe44b732353ce9cc37f0662478269665a3e297ae500f5243190e3d4852aed0f977fd5080a149a6a9ae08c1db7ff2e45fe601994f20bfa7c60c744324b12ba6949474a6eac8fc44af2a8b5319a0736490da32fbff34dd1205519a845bb6d25e1bc7467456615f536e8727d1a7c4658a03c1b779b6fa8774705932fdb86c41d375d9dd4d274a9da287e9345111e2fc912f6ac82b9725be4b1d46998ceef310b364b05a0253354795e276eac0fb44a64f5978f7cf19ddd0918ac5639c85df690673d7b365ef4a438b3a81fea448fee96076571273649a86ef7a5b7766eaa2a072e6ad585564fccbac18d2fbf425e4ce024c2a6518250e84e346a96bf6b6abdc1a66114e7c03dda2bbb47bdc501ef2bfffe4ba69d28df907bb93ef009f77700e96c5e85b788006be37c56c8d4e4a396ff5df743b04e5972125436dda0b85be7933156edcf6ec3bdf9a72a8166305c6f5524dd7931d127470e56ce71327fc7a6abf1e655ac86c01e4240cc0e058b1be9c737afa12033425fef8d3a0858528559071649d47859f00a9015fb0b4eb7b2a2fefcd49f409e89951e3b4494f9a09eb7cc24b9696b71e226cd21cb4a4d80fea507b1f67743ab8f273fd1041f4b4324714aef580f7226529973958f8976560ef81002df6b5e69059d7e452173813a50ad6c1b5701c7ac55bf911cbd8ac29a650ab8dfd5e82d98d3b1d9b4548b1dd82264b246dc6736e242de99b4fdcbdbf2b55b54324a48de99c04ee4ba8c0ae86c3fdbab3cff0a01304f0296f59936178f54aad3d20f9c31fc82c7c9621131cfffa63cdb37852249bb8a2aaf89d8b55039b98a520b912f64bfc77a1f38e1eec65ca12fe2f7735dd12bf66cafb1742a5e32ce5943293ea0ce41261e56cba081dae2055acb248e5980c2c097b5d73886e877c490c6da67865c2d92aeb970cdaec3ec8191b22c69bf6ccce28f7c823428297f010cd4be2d024cbfcfb54e19e7cb70b543b9fdd018e3601f8567d2dc6a9a2f33ecf69db93a1317be2173ea699802907d2a638776c9f696ebd8aa823e733978fc9d3e72cc65c7db25db3bdb93c34ae2afd2e878b40aadab278c890c266108dcc127cc81594c9b1219a50143a2ccdfb1682c930af8d6909da98ac581c7fc09e7f52adfe20fd281422d38f6a167a22ac2eb389432aecffb5f86da603144aab6bae28b05e8f2a795b821d66ce1c306e87a3f6c306ae4c4ab6c7c43c99cdf7723856d43cc06c0c6ed5d7f11942428199d77928db18daca6416af014ea4136da02a8d3cddc24866a82f717ae97ac84588bdf716b59669fb1644a8b91b15ee6e4d27a1956b59ce0bc8e70529df27a965688971ab7f93c43299d0bfcb338550d49a717d58c6ecf0ba6061f55528c842575c8f2aeec23f1f08062fe8d0a40409611fb0280f43acb624e65cb72f8a6b46573ae016a194f92cd29d8620fb51341e716020081459995c6fda388e51ea6f7125d1c94ef66cbeb7237c385ab51a29899e96dd91f24d3f07a28d0375a733636cb71fc329089e1225827d75c1b8261aa583462b92baaeb58cda6c7fac91bcd3bce111a7d6ac21fc571889aa6d70e33e5c2dd5b5c9c8935d646842051496a40f418a660225874c9e9ebf8deb8552cbefcade8e053e8ac92ce39813ccea9d7a06aabc6d12b8efd4b30221de0e41fa3a7414119366edecaaaf5c1b6ac4f54ab5e49263e255fb42f9ab883f2ffd98017270bc88bc9f0833bb4a2f8ced470d5dc0dd1dc065afcd05945057a02b8feb229df5057ece018175b1314d3088de468c9f9d4bf2ef6b6639127ed2f914c108cb1a433719dee25de9bd645981f2c325682fa8ee611812ba947145c522ee8827f7fa866db908f350b52e30188b68629ff877db1bb6227de9fd3d4491d8244972a0cacec3d87fc6f419f8e57fcbf1ef274633b6f888f3a9c172faa5f8a3dba8265ed8da16f9bf5ce6f1bc34d1119d538d8a93b76904084df4de3d37b96682125d52b0ab1827108c779b64198e6576d250e37b9bcbd5af4ea7586068014762345ebbf3a76584a84066bf46f030bfdc08586ce0c124a745fcece664872076377a60aca14cbd48fd6c7a7c93ed1d576304b73e5edc101215336a9cd7381506b5d3d9746fb10c5dbe34c23b9570feb87a67b440f0078e45f58f18f62467c74ac3697a06511372e33360860ad76005cbfd3ff0f0c2a633fa7afd3cb3e988e1895b6d91027a258139eb8e8cb63b5385591872262162742b74cbc04edc14f1d62d67c9391f220931a12f7fa9b9ca7d5777e3b99135bdd430cca745f740000003bc0bada0f096e4c15561f7ce2ecc64717234d8164e14f61404d325e537cdbfd809437ddde0b3d2db9dbe1b0048453513ba0d697212a61cdb642ce60f308c109dacd2a862faac4b8a02b2996954629e6e551f852379e337e3f8f94b08878ab73f235b7de618fbc9891f1a9ccca3e05a177b0fd380404a17f2b6816e7195675490fc179b13b0e59b2355d2b89a7de0191d891e6343bff318d76da2a00c87529ece8751529b5d2ebb3c35539cf61b22027ee31d726ee33d55b1659c4952fca5bd9e9d37637b4f7218e10c78a4d7fbafc2d3d6fb10f5d1a8f9806551df1470752356531e366fa47444846f25f6a51c400e0b025cea081ac0e60ec9efaacaf6ed7bce53924931eef7eef5a326cadf0b8b11b304fbcc79f8da8dfe51c3ca95990062d9608c9d082aa9cbb6723f0f795b354ed37eb515875f8e89b8fd6c68b214e8b866947aceab79cbcb79e44bd46afa10b47a5542263fcbc2f76670475bafbb2b904df2352ffda001c5455c79d6ab4fc7d0fdee9dc187f07a06c50dcaed6b881f35fcc9ef4fa55ffc0bd3e8abbd9b1ebadb84a33d2615debad7e376513f3771e3035b836525032973e3460ced64b42775f0b227a9c8c94af423e6046863bcfea28056be47a0051343517e79383db0cb7b59372368002af6ebf0716ba5f46270f4da955518ec40c92208a152d961b12f56a7afcb81010bf22fff3bd252a51e2cc0ca03a5d5ab0a066d58358fa9b7370d28b4feb95882d9168aa383d0b4268b7fb33220bf1b34e273ac6d9cded7f4fcbae743b0b61a5aaf8103c97f6caca8e6a111a33e92f83cc4eef47f1f93122e0e69bcefe382f98d296082659fd9840ccda3a009df2928f9379e0a6d9faaf6b12151afe6542fd0c84043e8e6119f6fe85f264e6a0663e23a98af8d9d91618f4530f112719bd48dab00ba05fe96e899506f214a3025f9e7c5c91204fc5624216ac03e1e59e613e91434c4258c777bca28f836b457ed3110f09a24951dff70e2e654b232f25f89d2dabfe82b7b1a9f5b855202868b60585742daa4923c12a1aec177f9d5e9503f0e3a9cfabd38c12fa6bb7888892d7dcce2551873ef02fda301c8233340f2af2f4f18547ecf84016cade28842c060a659762867e8a3ab6633416ef03250021fb5fcb9917ae6622108ae2daf6723980f7085f45ca612d0993aee17cbd86e87d980bc746555b5aae1c94801b2e370ed4b18669f225d5f3e3bbae260e15ce1d4d000b431691f67168e68c8495c7a8495727e58493134025337a76b3a5c43ba2a9d42040687b7c89e69d660134afa51ddd4b5aa10b193ff33a7784badd89b6e8c3461c4e45ace4b742576767a7b01872f1d2f4cd1ed81ac921405637dcb69df9d716f8805a68524f66178987ef1d22c737fb6fcb7f69c9f62efa5da3fa4a57c6f31140211a162dfa15c2c9c9bfb66b7d2e4d1ed83ba2ffc77054f4e8f666b002cb3b6b0f392833790a04ebcb5b93e23ca16e10c4a7196e2fd2ee6234288e09f75fdc391a42cd08ae359927c6e59390f037b62d699f6c97160c97f591cfe0aa0c9b3b456a2f255cccb6a2f194ad4b48d402f9282c9ab70a413d70dc68f4579c49d8423330236f4ee0a1c4cab393179abf3fc41402a77dffbd86d3b367c9299894967b1536e8f0173be72b3daa9f3eb7b5fc6d48cad2a51038a52e45ae94cd51dde3c902b896b622727e1208ce5af0e9b8573e5da400ddfc13ce377622a02fdb3010867c1fc45591d3de4f3ff068cd23aa1cadbcc60989b6825f3172464b8fd1a1edb4d8206e7b29cf20c558b35812151a44368f186843cd98536eb3391e32c71683b0e4db1e546a9eb3c0f2923ab74ceee6651ca04f4c92096f885dca0faec18d703da056a88020b60ec41229faa6d3937447abaac80445104b53eec7f6defe7f592f8da374cc0184f374a9124d66c44d472344e9ecad7fa880973ed6b56fbf69dc851ca8723b08b77ed46eb6a1a594a1e52090f481cbdecbfa83af24c4c7f0ca321f4ff3bcf501c8d6d546e98bd7d403a8642dd8f771ca5f9fe077f3b2f0f170edd16159f0563cd992add3f525d454baa3217fa890a760fdf1bbca528236a0f6573ac5871078d7b31497934f86575f2898ef89fa9b6736a3206d39fd08f3719f7b2db2f6f1c494f859051064a3dfd60d6fb2ca5eb78e78d6b1f4320de131c5085f76e568b8ed31cf4284f894c61d3e132f2f41d4b4ca7973a0d0b4bbbbca63de88f54a2a491639cd0578ec20d58872c6d41412c1e5170dfb6f8cb1bf8834521d7e3fdf2ec91698026e55402646e8bddeb0661529787822ed988da572088e23569892d2eee4344d0ef0b0866adcd7ca925edcf09fdc2013bc4ded3f67e787daa64adc519597e194e7ffb72f49f82a2e26c1004abeb55f1cfa97155136f1d7456ed28bc1ebfbe69a11a1b6db5ca902b8f119a87287a7c0dae8ef408418f5ae205c40c4287a09ef1cc75f1dfba156c55ce2feeb6435dcb681c3e82c7033602905d2389d962a467e71546414a05b6b0bfb092d5d9b1c07371a8ac386d4f69d9ba589c1e406018ef5b8391f39c97c3d19ca0de767322fb783ad16c6e1d054fd7ed297c518eaa8a994d937457c5930c40ddd3d5efbf46393fd022da2e21d043f5c168270ce31adcc737db97da32ef103033f2e6dddc8baab30b47f59f18479922ca132605f808029113ee161fe07233cc33e4eb81af221c3afd2585ff08f40b58395cd5946c516035824076debd016ebb68344108cb282303d26dec5f9792c0b991c7a28c6caa971fc1433171b473d9c74322be502332206709b481dde8049a834ef255858a1a90f5512475d8abf3ad0b94146b85d1cfe10e2e90bdd38d035d09a4dfc313b4e8297a66bb116c6ae1c99118306c7a672dbcbc6a060241df912fcae2fcf7f2aeff5ee4e04ab6afd3ef9994d5e97435587cc4f8ecb5e7115a26710e9ceeefec4e87de6f75bbdb9a0a64e582de9299fc04759d70e49e420237f23440e6dcbdeaa70bf6e453b41baf386d62328c9926aae352f415868def8c1f9d25534faa94596ed1644b82ce9092836bfde1281148ca1e36ba8879a414f28d8a0a9907c11d9e01de3390c3b86f97d5b04355fa5e71000473532c17a1e71402e9e17b4e54552115d67203cea6c09aeef06d0d975694e3247b347100cc3c6ed44e79517330cde78b96f6e7c6a44877a96ef46e60164fea3d21f862bec96b5b78505f891bd3e49ef4a5616663ad21ae5f18e55dfcb3903cdccf2033945e67e8c5cb3c20a3b80c8e3860321a6daf65d9ef5ca7671cb585094e2ad30840d6a41f05f285d482ddb334332f4739493643421038fc649b2f6072a8d2a40cb4d4645a2e805b4d2f744ad280c4539ea5c289bf6a5d1a1c8fabda5050cf27595c5ea1db7b2f3045aaa2a356dcded4be22fa05c9a4cd4ab722a2f78baf8b4882322371a16141d9ed8f9473fa74b35a10a168e27f847fc0b30b2e3cc27997bb849aa5e5b34e03477bd30cbc6bae727933e3cb7ddee12e8d9aae7f264c74617a571dfd62018c0211dacdb985870105f1318e4a2a126b5c731ef4cc6ee8818922341d341110789689029deca3d3500d43993f85716dc05bf20bbfc6a73a1f340b96ecf4c7060527a9419b6b7c9df411c2e3622326943998f9f266d1e5245c3553e19ebd72c3eb1b6f59716aa77e68313b08bb1592c474a03c965297a572a6b82cb4806fabc3d1683a7f3116dcbacfbdbaf7342f3e607bc96d3b781c4ab593c8b58e7c4c2b45b91cdb8566b6821191745bc6ba8a2fac339b127a1586ce8776903aed2af57ee65c70dbc6b8734fcfbd7b0a622e662b98714670bde5b3368503db2b4ac5ed62e4a220e5b664b6edc44af2f5aeeff01c6cf0bc98433cacdcc1607cf9aab14425365e6445a18ca9365d0a5598928ec92adcde6c7877b80532b74a5fe02cd924c419f52f528cfc4f3fe109b675e95d07e48aca35af09d8e02a247866cfbcb50f0f85ad5c264e0bef9fc8f97dfc7db26ee7f395378a92e89693937d4281e81466f9652078a0421af5112145aab5f3302a988028a9b559abdb026b79191d14d8d56461ebc1d56f0fefc2f82923b362bb0cc7b5a4f3c7a4b639f298c00378b2e055c4f61826c511e486b1c806408f1dd6a11dd69757db9274d81694ca16f3e8834dfb75f3f206e9127d57d42782f23989f53968038a74737a19e606a1e504a852842a1c9fa8000e606743563e246ff039d335877fe0a7a5ea247cd5a579f375410680e642a7bcea7a88d9",
+ "spend_index": [
+ 0,
+ 1,
+ 2545058932,
+ 4294967295
+ ],
+ "result": [
+ "b21decd167c0c15adf50de7115d216dc4aff160c64cd0908786a1014d90b5aac",
+ "3ba1e67c39d2a00e6cdd4cbe9520944d598dc4f2d2a2d4997eb18e26b910c14d",
+ "59096f4f95ea549c91c386ddae56658b2c66c3620fc7a810c8d422c2c38e5138",
+ "3e0b6fac06cfedd27ffa02acb67384b1a6fc0a0dfc765554d6e6037e1b2fcede"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 5,
+ "Witness": true,
+ "Version": 630616049,
+ "scriptSigs": false
+ },
+ "hex_tx": "f16f9625000106c4e8960b000000000000000000000000000000000000000000000000000000002b1a1e3d006f32e6b95f1f0fe100000000000000000000000000000000000000000000000000000000023fff7800c8a1eafd82c254a1000000000000000000000000000000000000000000000000000000008758515700bc8a789dc702497600000000000000000000000000000000000000000000000000000000e91c043100c7cbfaa15e276a7b000000000000000000000000000000000000000000000000000000004f115c500087853aabf66003ea000000000000000000000000000000000000000000000000000000004d81ccdd00b03e130405516ed0ef927f181fc84da3c0ec6b2dfd78386c3c30c7f681b1c545aeb71c650485bec2fa9426deda5dcae40f0fc556d8549d354a9df2f94ac0ae5f88a9e49367e76d94c75400ee35de99d9d004b93def51477c61074a123d8da4b8a712371a648761e3f45f04e7cf3dfa8edb9c03bc269c96df0fd9bf8cffadf6e7c0ea74022ef7664cbf0bea7e23255b011c1e38cfd0cf88e237dc48ba755cbed112ff4990aec47d8a96a1e054e3c37dcd7886101a3781c1ff1d69cfc2a0526a82b48f2737c26f16de3fe8b6fdd743bfcc57ec093264f478f1b60574c9371cc85ad8a791e77859cd92e1f29a9205ed1029a01b42eeae74b04e34a699ef29f7ab1302bcfe56767d93c5cd21c82dfc541ce25b32e52d8cbd024a9604f7184ed7690e9fccfbdb9c08c5ca6997e98785dd4c377c8090914d9fd9e4c6ca776712784a1e735766617d8c14cd9f47b6db4be3c8df87af33f2e7d22d687f19b4b1ea7a1fb2924ac07a193c6cd46f7d6317c8565e93e0896984f7826e37bd8c4d2b413b0e8d80fc376bd03a9d42a37dcac66d0d0149415486334d776e9a868ee0e79525e58a7d41be5300dda7efdd2ae7ee2e2449c8775d4de34eb01417273f1fc8abe8d57d8b8b4bb063539179e25e47de6ce5529c25e4daa85f726e2b70c3e031cea4dea81489335bef20573a516bf2ecd7d7a2e2dc9fd7f9e0db328a11576a625135b34314dae5e5910c447c423c6016629fac87e93389b6cc6d8f6bce7cc8ccf32e9f4d69c21761fe806db3a096fb2e1813c514d48b8696966d7c5d802fa319d1de252f37115d972e747a90ae8c38a3b0fafda5e543c600b9a6ee436e1b5feec05704e14c5b452d5996c20d4f1ead545d998d4874b4471b4613818c85657c335d3ebd05c8a5427408c7e10d9b8fb4bbc5c135aaf09ac75246d5ae69bfec927a6431957c5c25b4e6db4b958a7478e556bc4f603bca4d6fa66fdd28536df2cca8377cc554863ee273ad43f6d183bff1ca6f43bb17c62334149b7cc4db172cb9f15a19c10072d1e066f2949bf531961e7a16be98cc922be405b8e45fed5c2daf674ef9a51bfddd784bc092803286ef89d52ea27a6f4b2b1fb590026116d39c976deff446215876c110beee0d844924b417e143390422316026e26036ab67ba0dd5f6def8281af6146f0aab7e0ec62ae5daa701676d67c82c5d686a1cd6f3210d77dae6f42a3ee658ad95c35612748997b60c3b70cf6a4249406e5bef77344455969c45068d1364d215b11dfcb362108ffb19159f46212d5a2fd372633879a39bd16b9ddfbea2c2b12df4b792cecdfffdc6aefbc76f3406645ba75ccec13c8ef382d94a9db9002c1b1b4fd99956de17313ff5268792639d4cf40a122ff5964f5f1aa1f751f0e206e7c36aede988bfc2f94b0dfe180ca1ba462ff5458e12bcf97de50bbf10864f171dd3f1486f3a45fa469af373f409370f946a344249bbeab30409a06bf47f6a2a517314fdbd017aa9806a84afe9df7eced734f5fb11466aeb9f90b56f7282c6cbd538d1ce599140d622452e562053e76786ca50c2ce10adb2caf9fcc424888671d5839eb770e6640255491fcf8e605fcfcb3499354e607c89896b25b4703f99864f2402171ebf2326df584dbeb660eb8b21aceb0fc0c2b40694b0e77566c871095e038d67771be1e6dd45ed89521a41b4581fa836d54d13311372e186f1f44460782fb4f48cc1f413c75ccd6385e8bb698f0bb96ed0d5d11af73ebf6e62921bc42ffe8ad01390ae1c73c4ec7d2e613ea6ae0c275f03d0e98e60adf87bb3c2b76e174f8dd4a3d3bed6c31eb3db2434dde9308c79a1721ce8b386c1315526e33335fbb81582e715e23436173337daabb4d8b39dc0169743142a86272bdba71b310fce565a1063a87556561eeffe05c62d286d3f29c2769ea6517d75cdffeedbeb3d35b18a1785397eb36b04c050827745788ca8e67c4ca259b056d6d18273899d1cb7de2df7234b1b2562e700ece96619d9d4e348c0c2d96e4b0d4f93d9bf35ba394ca622aa83128b0dc0bea4f582e2faf4dc7f6d61aca21f99545386c345918ece8ebaef15f2e995f85b75453def81764fada70d29c4361362ce44e839e38bc619e8fc4ffd5a011389a5de99e441b2fe53b2f2e987c82b99ed01f93d17b9e2c93075710b7eba3339e09486732b6d5e3ac58c4cad4312b4f3c3e48b2d9320603c275eefa8c3023a3934192a813e60925df980525162b493c3787322ad5677ec3847d8ea574599b2a8a328a6869cebd9b66f54a478d31e8e7ae51d3e49ebc0148a5828cf30b234027176f04f105d1d78a0d0618079709808e73b86bd03417bc3525b4951c83e6c535d1b10730ade1935b97ee0ba5006fdd38ffb35151d93221d86ee2dff16c4353b057d5c5ef250b0e6414f1447ce6895c397d933276bfbef4be7ff7f65c3bda5736df98fa7fc34b48e174305970d11cc8ba0866e09e7e8f7d6f1f4c1598f6fc7e1b39c948d99c8b11e5b3228bb65efc9c1b5be37a485864022b7e987398164114475a920b663da3338b5acd34bece3d8d3037809fe55d9ddbb3582a4d01a56249a6049ee854f2bb8452b2294f9709197ff95b158a270b4e2bff7c7debd3a9e40ca669b65416cc6f1bed4c08ddd0b7184615a0cc9a957ba62be95ca7485f594af50efc6a8d2d34cc542558a6d791f14b0f044a7037e948b16ebc392e6425fae93cacbac326bb7ce94880a2d1619148938388f9c47ed37ba12e92cce581049138a9a59dfffbeb7721c84ff404f4c72b6388ebd19bd1fb012e5e0b07b3af2073fe15b477dce1176f13cf35e418bfd7d49c55f6d4ffb937dfc1af832aab6cc36195e7609262c1906a408db52b9bbec2a20874a88f472446c6c9817c039f254b59e501787b46e76a8f1d7b6f22023a864b511c00d7d4ac18c1c41c6c80002fd9a01a804d8ef9ae0b1e5a6af28461709bb34eab4b9999b4a26f50809b900df6e4fd40ecb7544b3c7c7d36fae686a0273bcebc4cc554ae6a411f7f3b4fe7b80e231a39caad54811095f0e80eb6b7e9e6e4af4b706180f0114326635993b39a2e203366d1faaf274496fa53356f358cd3c10cfda67e2abbe15f987285d5fc16d5410f47190fada98c4835b846f30bed526d65e538a66c6d271e5785b683fee5999f09c765cc27c54e7f20ce491919d369f17f4d74be36543ea33d7d03a0bef4e83939334af24968e6df332facdc7cc18b826be57eeda8cd4a8af4c1615ad15f16933ba0f6fba9bbe3d708f250c99c050d7da0973e09c7c7ed9bafab29f0896fb8238d05be5020ca9f7752957fc2c2bebfaddcb50e206baa36bd1ec0d7e1ea86f366b1bbf4d37952863bf58b2be9db7fd75b6192bc08030189877869f181f53da3e8e5a77825cd3127ee3a15ebe0b9921ff2d446ff3ab0987dd3feeded5b28ba6a75324c847c6ebf4c2151381fb7d0a26973b836090c8ef09f7b8b4a629bd69ae469faf3e7dc3ee08adf202d9255f6fd3c9aaa3e3ece03ec10f3accd737f2a5f24483eb722432c411ac33b0c1f001b6e20424f4dab0931ec4700cbf5d55bdd44f9b169b0b4a07a8d8003aa65d3b6ea489dc014f6c0f9747178917c2820d91407ba38e1026624103924ec6177e3236c72d3a46c62d34d0c19b11d85ed4aaf56c7fca4fc2ea0c04c3cc490b492bdcbed3e7adb16a61cc419d9adb3fe02d10f4c0734af90fd39b72d717c8ef6d2e915278a8b0d82c727ed1198b53a0981f4dcf370ec8a0cb9a0e81c8c46bfe1843a8de737410aa44781ffa838eba7a51f5e935f7f18334a30032a105b7c92f19a070912366321602b639ac402e9292701f65045ae24d246864b5b84594668c5f450d19eea704fd8301168f8b6a219e8b7975688dea4b79dedcc8f6d3b5f5eaab93c545aa1dfe102ebb5dbdd802940513c720ac0976743b3f6a55887e2c8f5073abaa81e30e8ab212cc2b988d0851a57f1ba08a204fd1549de594ed0f0e7475dfb6ec57d88229e6f3e4c24e8d87f944c8b9edd6f305c3ceabe569c05ab6d3c95126f95a2297f7494689135e11689c3cb3ef46ad912b681aa8e1bef2c9ae6f2b4a753bbb65bb2d9ed71bbf110675007989eafcf84ea77c3a182c09cea35f8b10ecf9b1c6ecd21d1ef13fc2464bbf933e104bc0390a869bba7425fbd62df1bbe72433553ee6f5bcea01cf168483a7879c523c12cfc0ff3e60eafafb18599155f80856087547af10c44135f867383312f84918bbb23e8bf212420e2f771159e4d7735005082843c1d3be1404d4260583179941821a85d002e955e0bdc669642c5a423db77888016249fbe218d55b8312ff9fc6582b90f204ed6d18e05daa47d74bd59e215a89857790c8fa5ce51af6852f8fdc5efcd5556c99bafbd6b3494f40a100ad373d1d27709aece45a9ed089396422a331fe3e1cdafed115d662616bf5ba7f6f16409a4575785f8cb2d7332d7c3a43d08a4fa1ca686f06ec1ab8528b822b9381abba09148858d6856a3f7d163bd2ade4b7bd7ce144a81e1bbeb694c9906d500bda5d3bf97afadfd90e4262d799f14512cc75f06375d5f5eb8cfab332accc4af481453078270850b4ec9edb4641e9415742a53b8ee4fd06019d5a793b440ba4d6075288d82b842ae6c231c73ee48f8fc1cb829f6afa764b64594fd6a790e1daaec2875c48775382022b7b4e26f67d73ac3d0e35f44d66c83c5f68537ebff9e1f72c847b2584e347faaead6a66644f49aeb4b1fc7cadc77d64c47353b01e078b0602ecc8f59bd66ad2a5a94cf43b38056be6d8ab9c2619f55c87bd06c9c57121bd499ce147878082868bdc47e2e9e692328bfde5ce32b46b7ed4ce8541c88a39a56e7e0af8577348d15e46fc8d74ae4b6c918dc51a0863dd8438efc702725c764e1fbc1cf23cc70b02033dea863637cf6ae9c0ca36c0a77efffdcf1224eef3148a2a3ea5d36d0e318c7a5dc6fff4932f4a5ad146b207a2e217d5cb99fc898815cc2d8ee6c94e838a9b235bc7f6817abdf13bacd83d032c86f3b8ef0531cc3bd92bd65de0c22e4419f85264266051e2811caf4e41ad88f4788e23dd5dbbe2515b9be400fd71010ed5a0dbfa116f50e82374ba2b84c250ec4a79384963218b66da1f33af1378e24bc1db878dc6e10c5c70d7bb307cff4972ead4a61d2613bf7ec6b5289401f9d8b8cc770b90ad895c454dfa4876cd1d7e506fc68551c04697aa3fb29ab065e3206fbf9a80afdcde05add51e1ff5ea00c1c78eac1da84e3d7eeda5e384f10b883d066e7a7767b25db26142d3d8d0438b71475a082c9cf7d8d01d4b71308b4455dbc76705b2eea3fbaeb800f3639e2f69ffe7dad08cbc008a737a0be98c0ce0e6d6a42ebd2fe5f42d2348cc464e0d56db295c813ae3a6ba8bc5589444d25cbb91f2fcb2c50d2e03e6941e61e88f1c6dffc34fe3298072df780384243cc27c95a2aa7de72d321d4b764750219936557abd87b7b2a39d5d33763b9f6567f9ed24eb951beac74cf105d6b61ac94d70bb2c807a3b75fe1ff50d5a381ab676a296012fd5cdc2258a68a49a8ae2b515c4f93191ff3bf0355037ab75b14798ec54125b52654942dab831fa76d82a47ce50e251b82a6a4ca17925ab310fe492107607cb0c765819bad43e09240026ff932c385149b21d1c1559dffedd512c2a0b19ec6a2a1b37412135975ac0428020723950088ac508071e4af80eb96bff1d34a9272803fd360169e10d734e8a70ab7ac002d81118dd34fa4ce154d3e80fe6fd5c1609fed97a6660ab41edc364d02435152986a9935d293f58995a67bf17ec6a7ceeaa804c3e626ff779cbf384f41af72a4f64e8eb451ad6f77f1ba89df42708f57db978a78df819baa62decad76c3b4d90abfec7ab4c9c5c21c6db7825b971d9f4c2edfd4741f7c709b04a63a694d3881a2fc721fc1753a3de2de0e616afeb6426a66654246f70494317cfbb590c0f6409545ff2299d2ec635e552820701bdcbcfa97116bae779c1c5ba922d4614d6f1c57382c6f403e1c9ab1d226f8c112892c27ddd40912adbaac96ee6920d8bca349edd94c565b7eef7770e6354e63e6bf676881b24b5b50729a0c3f44cf9ff1779686c0f9fe2c89f746f0dd3d4d63770bbac847d680eddf2d81cd9f5d758b4469d73e0db38e6bb5ce6b7fec6868ab9d5a3d2235b8058b11e8371878e1fa8e6764b163371f2cd549c475896bb4b9ecb2d70b525fdd968b9d98e56d087d9fe9f584b056f098a65c0ace43f30ab9aba828a912432dc5a60df9c2c8ef5c4edde71d6b73844130434965d239d0328085e3da928f0eb35fcfaaa37037189b09c8ff9375367c5db5c6f130a4f594798671c53bf5a8e975d31d6f2ed8443f357402caffdb157f9050fd3ac530a84f086ff630e4039f9e1003c9530a015b29cfd88499d2f29cf682633c73aacb1b3da3604990ef08d986f7911b92f23423eb5b762c2697f559a5a8b0f12d51",
+ "spend_index": [
+ 0,
+ 1,
+ 610513232,
+ 4294967295
+ ],
+ "result": [
+ "b8c2674bc1d4548662609e349a1ecf62051c325eee442aa92e00cfc07427c5c8",
+ "a860261a7f38b0ab5fd7bd9b9ea5a970dc25b9bdf7706c3dff60802bdb0d69c0",
+ "0447956b7c977512ed421e483dde6d916cb3e6932cc0c46adb9276d73517c84b",
+ "648f6285ea779c7305f3de17c8bb329fb89716855eed576d1420654b262b2d9e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 7,
+ "Outputs": 4,
+ "Witness": false,
+ "Version": 1680436768,
+ "scriptSigs": true
+ },
+ "hex_tx": "206e296407d438dbfb000000000000000000000000000000000000000000000000000000008d78eed6fde501f48b577503b35b028206809323b7198b8d731b93b79a5aa133c23bed43460b9f95b3ce5b8a990d3bfaba0b89cb471379f065cbedd9f3bd3008b96139003e82aa700236cb95591e86551c895eb35fc6fec035006c059487ae12401dc194515a83255ea54ea0083477e7f569aeff555858287d30295d361cb03c5c2d37f68909b571b5b2ecb29ea966ffb85a69432992eeab288120b6b0139497c1d6341911fc3df5f0e914a86c8375f78670ae69106e6f144ff35eef7cd840d6d03224af060c5909427c1549fa6b1270db86fe79a4d13cadd7c77ca30512bb18f63d9567f05b7e03055dd716732669b808ca2abe4d0ac6e583ba23e8f9508d629f71652b5be7e8d717dbb8f0b4cd91c97538e187a6f920a252eda4c1f5b96c44c189ba9fbec3c7016b1414bce1af8f05002eaf384c4b046f52b4f38461760261e1d747437583d804c9eac273f375444e955383c0fb914e1e85eb09f883da326f865abfca714b6013e8790f2c9a9732781b2d3ddf9b1a9ccabaa31b02b0644489800b6472b7df991a2d07d18b9fd09f7844274137ea612e9d41ab5cfe8b639c344daed18db26a04f2692c5ee90098e1acfef7f4e73b8cd3bbd4c88c252f02858f43844d4dc564817a35a9523defd41ca995d198ea29e8aad498b8aec3a257d88c76694a92ff7bf1845b260387a2620c4092df1ed20000000000000000000000000000000000000000000000000000000008cae535230e35061fae2856f238646642efbe966618520f45ed8b9c1b286ae4b7e1329ac914260a7f151eb0d0521d1400000000000000000000000000000000000000000000000000000000b749d8fafd5901c299355f926b1694a1ab345d44fed8da1a5eb67df88cc11cf9acbc3ee7e821dafb2b21a4763b1c8910bca006f499db09ebd90221d036e6d09643a06247a88e6ddedff4c6d42af78152f4c3bb35e4b5eb6f11b9b26a1abccbe926c0107bbf0067cc7c82e2de639fc2c927171798a5ef1276f316c800f8e3a2ddd7b2a1d10b388b45ba6b56d0700d51ec680f796572922d3a303ec9b7d12b3abdf2f3f7d500c6d1f120b6e073d5c2c69fdc78352259a25efae6f5a13bed818507c50120f4892c5e6d5dc2e11ac6e52581079a66fd62f83e91c82c8655d27323e6a945b576322a173f9e2d1acdb2b032c378f24cb0d1fc20bb44ad5ea1aa7712a50cca3147578df58185e002564708fdf3ca635d742f811fbd9780f4b2900657ff96e842173eff864576c23d9dfcedfee2d5826b8e4881ae39a81712b34ce0d18aa64ac075700ccf16a06a85183e1ca36036432978187fbcb83b58720b1696d197b0e8472cd238d8180000000000000000000000000000000000000000000000000000000097e6255dfd7401fa957a082e9495119fec440b03131638f0ee91c9f4a05d918a96dd588e818ee4a8c287fd2aba49fa4f658410813a42024e302708f185aafe87183b08fd36d40257db19fc4ffed1521e018a845c8f89f51e7972ca7e98ab8d401308f5b4aef15168eb9a4e72dd27c836aca7512a5ed1eaa7b01549914b128afbaf8c43d40e598657dc42b73de1134e1eeaf60590ba2ccad9e2bc8918783d262394e5da24157b648f0bc12d0b05312450f93ae2f5c13ebbdde8910b3718786d339718ffdabf96ee4294f6157679806ee824a0ea6135ed285fd7decd81ed64463ed2d5e962c4e4d35b4942a1fc796df8d127f6e81b646eaa2ccf34b7c9a9e7db4938338b40ac0fb9b318ac0fe3aeac28a95e1fdfae2bf901ad71dd78050260939a30dc4d4c1c70d589027ecdb83163c75daeddc3578d72e94c8e40ec158072d2786c21c8f060cc876316e1abc51d9d1bdfb0f50b70350b63a3549f919f08b6ae614dc7915dffc029e602dec03b56fc74cc79316752e1201af171840cad2e8a3d62f16647000000000000000000000000000000000000000000000000000000005fef348cfbf8ddfd14a1d50fc4712872f54ff256923f6a60b0b8b3e3ebf922e0a782162ad430f0238b1ac74bd0df25355fbbc7f4444f4d63f8b3d9c1e4bd0ebb4ab8647a73a3a399144619c6c5b94d311fb2fe8a2c08a0b67ddc713bcead78d0836ee8dff4d45065e8bb2f10728049b37d16317d3e680ffc3868cc1115e3487cc3c5cc399283782eba958e49fcc6f46290b71ddd5a78f3afef988e81bf9df069e648506b374a0363976167c8c32a2c7afc96e5cfd4dc00280eba34ca793880bcaa32591c458999a7942035907a8b6fa75d8712634fd86e2951baa5a1711ddf66304d40dc264422989d7f900254507f5a77d50d0f3a472a62e5608d835c510ba1e0614208be966b270000000000000000000000000000000000000000000000000000000051d91a6300b52ac7197f6aaa6f00000000000000000000000000000000000000000000000000000000ab3dbfe0010ca1f898b70432ed23ce66f7d23ec864831ba1a846f6da004e9e0ce5a1ba0f63506e3d163c543382300eb4f61c3a670bfd3cb3062e48be9c4742edd8edceb88c5b6b5f69160b199b3b21b655adbff63881325f4198480ea355edf71c7cb7f728d99ff1f0c580682d21f9516087c87f667c88de87c5004d8237140c1a0fcb1c37c4f273c2f2a7a09c5539c78db621296ef6b1eb31f00e4f3f150b65fd14fe8ebdbc552dc07edf24350ca1f4d68fa286625f45036b9b9a8ff42ab65b99f4ce76df1e2837409b8dc2767bc652d656ba3d191aa00e64be907cfa43962d93036446c817419f6bcfaeff696d58ca608989e1a3bc7ca5852277179093ac0b779ca9783d16c8e43a8c5b7a6a2d6545fafd28eeb98c0161ae94e0ca8f9cfcc97b1fca8debd3f50d89a237b79ccad84a7dbfe2aee692714d786208ede0be7db771839125aaf02b92db0167635d9ae671183e04d7b65ad00b4d8a04be904adad6092a7c40902b3cfc8acf018c43eb004e06a5812880b2f9bd5ffbb026820442f8cae0ae3a37daffbd9f46e28354324341cd7711debf5fc6559f79cf08f4e3b17dd6f24a1b201f1a6b7cccb73973d43e49ddec2f805cc82322800378dc0ac4c1bb3370c3c5dead353392b6a28fce714be2f199428940ff5c36dca16c83df719a321c224bfcee8dd44d350a1dde8f28d5bde147682a1c2007700fbb74bb5468345de4be0038928e46095b77d661d3f043280fe4ec12bde28ec80cddff8390254dfeda56b469b115d69c3d436a4157bd74d156bbaa1260c7617b84ef7ca3452f4c42fb0f97b7f08360a045392c5fb25c655c9846002ec5361249d67f977c152e32958e0cdaafce59b8fb2db49d969b1f579e9b27294e39af7d42d790eb8ea8a3820e297de620e77dc85679cfcc8cb9a19e1bf9ffbaee0219986aaab28782a5d454ef9d2fab7f20515f4e256fa0bd5e6aa691adb1260454999818a428d99446929df799af5f1537d222a5726d285d4fa7418dab2fd667419acce176fe0ae2be3c11c403dd669091175b2399fc56b77369a5a96f4b6a45f8c2ba5abdf7c03b3410d1a4a7107798fc0aad0558adaf464991f32c3f97328f0ab9d30bb7e1ced023312ec79b08ae0d0fdca0ea7ad81ebd9384fb6ebdb8e14ae73fb289c574c1d0d8646d68925bbbb264468bcbda53d10b06effcd364e097",
+ "spend_index": [
+ 0,
+ 1,
+ 1976281,
+ 4294967295
+ ],
+ "result": [
+ "0257d88b3cbede09ba92c5700e93c7296b52eae72f3adf01d06d80bf88fcbc94",
+ "03ac0c3bcd9354831c7615686290c172d87bd2789d23dca1a7b9e22d056f7629",
+ "085b051e1d33e462e14a21602dd67374660bc3423c83eb2bef7f8abb59531d23",
+ "4371e62d4ad87e48e7c24c3c51a98c88c430df56b1cdcaf04b31049e59a34b0b"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 9,
+ "Witness": false,
+ "Version": 950103983,
+ "scriptSigs": false
+ },
+ "hex_tx": "af6fa138040b6b6292000000000000000000000000000000000000000000000000000000001b87bfd700ab3ac83175fa99a200000000000000000000000000000000000000000000000000000000b565e13c007fc58c1275c65456000000000000000000000000000000000000000000000000000000004057a3dd0041bdfc854306659a000000000000000000000000000000000000000000000000000000003cbdb3ec00d93c4e9f09e3682dad388aff31c8f36c73a460087cf5cdbc12e40ae50a4e82caa1fb397413688766ec4c8f55c19626f25570d38773dbe49dc155f5c322f7255805d3b5897462d88f6e9699d7d84217c695bc3aae2240c83eef904d5aac62b34277700df977dfc0e7e1ea82f89856dd062e1b2f557f2e1d7e1b8de18db4734173a0a48ff259a2580f6ff0d33ab6adde19663d052625b6df5b502ccf630fdb6fbb14331b1d129546478302462681dca5b90def6af819f797f2bd49ce6203f6d9f9b790cbf99d9084d6182e053ce81c38d186b33a889d2da3664638eea3b73ac8d42372d1821fe24ec2f3c687644391304f146325c17f459742387e4bf571a27523dcbb12d07b2c8021755618625e8b88c4e482993686a1e0d1b2287adf16739481fbf7b623a497fc4dede419466fd6810a1d31737cb186abb3b4fc163df1a7d12e59358d1be3eff1d19af367581775fe854c653f00dfbb9f6c23606807ea2cacfaffef8a1805cd3f77a96e784e89db1df038ed5858b34f1da70be1faa3ba6ea57341a683b19d2de28e9b893d11699b0051b909d361c45c9c159d84e2dc22c95b224eecaf814d89b00d728ba0ad881f7dc842a240fb9d24d48cc2bdfe954f821e54977787e8f9b5117b26ce554537582a4ad824b550a34c6e91ffd421446dbbb7ee3ea648c7a8803165b81198b1363f9199a3923380609fc18be02ae6e0924e70b844a917ee65f7300227d67e1505d401e614802e1c3cc238b1eb81d6c63bd358f9248ae0ace89f818792c861989584c2873e0a54a3f2049dacee4ab1ebf0f328943e64d43c37e33966c74f15cb87c38411b9f5ca9e0fb6df06d7d75f50373d0df1d45b8f452235a6932073d87db92ad4abf2c971decec7942e0771cf4dacb1422bc8c59d705a15c1b6608e0f042decbd74ea89c881c2acba7c82d419360cff319155ea28037a9e9560512d640dab6af8f795b4580cb8fdf0adfc5c86c9c0b517f06fa48c468316ffb388bea39404147681106dafa1f551cd4dc50dbb0bf0c8acd4f4360ee36f5f0e85e80e591271e5baf94ef4c73cdacca9775a0421caaa130d05023d9d234fc0ad52962ed462c9f462fad446c27af24df2e9a8eab5032ed8a7635d6c20638c47d602a0ebd123d9fc7bc89283bd7ef18fe9365cd6da2c653f42c451716627bb1ba7bc8a909e3b9b4854f13ec801d976ba8dcfd629691b588c7909248870772265bad8a4b448605d4a6aaf417a6f513d8e1390afcd111bfe298bee9fcddabd29844dd802cabd53de94f679d9edf598923bb36bf2e78b8f208a82d2191f4ae768d2ee3599f9629d5a8ba23c696e1b96a173828478f7ff09bdbdcfe6707ee0721ddb15b1da9d732702a6bff634940c7fddc5c2cfe2b982c57184c4d8edebc86b84e342d9cbeb2357d21701956fc0f6ccadf87c1e0d5806f7ef10156ecee393c89d322a7b9eca24a360e72ad335db72696f80a37f91a771e4458613c4b761c855ae8305ac7a6f0f79c886222fc148779c93ed55603ce3de2a5e7fd33226b96b3988ad35dc6f6a3d59840c2708ceddffee02f3b56dd112692d863ccca02b3e06c1ac331e6da90f1a1b186c708dac6611df431bf1db9c63e773535f643d571848229379ba0f5dcd592ba21fed529f6e28489fcb8cad98b75bf131b8a01569a3ce2a31415f9ae2e6b1b6a871b1fac28c8b1369ade9f230cdf6569b1e41f2b10ce3b31d0e5bbb16e6d2ac517534b7dbd5b61d0d9eb4c7393c19eab908ba7e8b36918f4b9b4db3cf90357c735cd57c1e3375c88554059582a77eb62985ae3a85ad8e51cd8f696a7750f2e983b0ad6610815ab81ac1f917884ca4e52a5f869ee0fdecf50f61dc154426f137443673f94864d2d63017aaa4fb6e349b260a2084d9609e5e765a27a9d11a49f4aad6205e497fde446129126ff6e6b56922dfe564876cb6da3f303907d76a28210a73bf6acbc41cd04ed13a157e0aa6774fd8e52d4c64578371f0c04ae3902a691b8cd208f4e9ef0864ff94a5f931a6c814fd409993162d6a5a371463e86edcbdf8fcb25ab537a93a3537988e85a756858bafa0e11b8b0453c80c34a0274c631336d24e8d3f57fe9539dc710312643957921377e906e1fa14c1591f98600a673602f3decf2869c5f96e96568574031ac58acc342f60b8bd61d1d5f2c1eef794e1561e6e0d180702f05d0aecc55c2524507b5cdfa1391a80904f72f65b814c206240e5c792ce066e8525f8ce59d23cf022563b661de18ac59fdf8e1539b2987142255bd67a7e1eb6d0a9cf6b84f16f9fe965d22d9d770ca7ebae7fdfb34a232124c972a13bf82de56a54e1f90245b6f4405ff4ae51a139aa26cdb4434909f691d92219413b440d0f4a03c8ee5a687612d54d13fd67d1e034d52b69784e3f4e2167d2954ff67d9bf1beb6f3bce0a08d5c8d93bc4970a8d9d297b0fcad08c1184384a09ada4d263a7a4bc7e9fe40126019bd7cd22ada58d96534e4fb5c27964e8d0fb564413652416d60db4bf8c1e0c97f45bc175a832625a87c5c5be81a06669f0b560de7ce76d6597ddca1f8b5aaf26c392ce1b966b661ffc19a8005d74c18fb8cee5caa86faec3c381823ca2236177b14e4bc1bdd44f8a032877a78555aa8f1e59e540e708229cb3dbb305007b5a413d7f4585fd2be77",
+ "spend_index": [
+ 0,
+ 1,
+ 1718455096,
+ 4294967295
+ ],
+ "result": [
+ "e3ebc01ab7898e0d00c74138a301aa044ff63406ff2f367a156ad55ebfe6d7c4",
+ "4e0ebdc12eb7f1792a67c6ada5542b98a2fbe0b0e38c65f1ae70fff4b6e3bfac",
+ "4a2e99bdd2746172270885d65bcb4568970c901328a1ac3304833faa79298991",
+ "8c54de20a56dc2c75f8f660b8fb018078e13662a9301e1e8a9e1bc9a0f0e721f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 2,
+ "Witness": false,
+ "Version": 1586157097,
+ "scriptSigs": true
+ },
+ "hex_tx": "29d68a5e02411bfbd90000000000000000000000000000000000000000000000000000000030be800f00b25eac490c0c0530000000000000000000000000000000000000000000000000000000001fa4d1c8b6cdee099d092f7d946b9d148e926825e4679e07b0d4140d03e9859bd32c1a114029fdd03acfc9e06f885e011c1cd05db51da8d749a7177e0cd1e63d8313bd283acdc936feb55b92fb85d810c9bc31f0cae6e05c829e8e21c9cfb9926b81365955a200ad67254dcd4e63a912ce299edea17632dc03cb74762498082be8511b663d7faf3f0082f888ec42b16d059b29e15d1b45452073cf670792399e87e7bb05ba46116d587adc6d28398642c551ee3509544455fed8533a77b6c40270a6aaf306437c7cc8431a2f8ae89088298f2c16e31d520b7ee58d598ad484cd0856bf7b0b402e5187d800089c19d9b32de970883542e538368825c5ce0f8094025740735050d5cf021f99236ed3a7493f3889abb2b2022d5e549ce675553af4226b71d326923c985f2a8ee829c0d76f7b72d5b46598234e940e78144d3f8283c93df60bc1b6512fd9d86c7bbd163cac7cbc548fbb748277ae932021f05d22f189a71e7f3a7f7b2cd7f5188ea388b33bc132b9334381a1bba098947cae20e9463592946df02e45498a327fd722fc5a5be5d02335bf26b3e64fc88462087b70df7806e6e95dc2a7fbd8f4734d82b39423c9b2e2e30cc1a5071b21268624e7e514c3e05de40dbfcde771ca7dfb51dee5d89bad14e56b057c9c252c02b8d131371d66ebd2de85b1e83a712b06f21b1159eeb3ab27a4ba3506d0d999456a5e5f2b5fa7b4f2384f2e66424da31c1cb882c0374fe1a14325babaefeb866a82da2866e0af202af0be768d6ff432a5765e2d38f58df4e5ca6d71dff7090180abd43eea4e0a4475a7a9ad2c7fc16aaadc8fd3837858ab5c33d855e264b83de5ab8995471dd27a5fe8b858",
+ "spend_index": [
+ 0,
+ 1,
+ 488532427,
+ 4294967295
+ ],
+ "result": [
+ "511c1af7d5757ae5003bc2a03fd3730b87de910bd3f92d4263c57aff3e62141d",
+ "4699fcfb1fc34fbea6619c9f1c07619a0d4269953d8fbd638d58492ab55e4558",
+ "8c92f14c5b5cef4177a2b0a19ef4bb320e8f0c09c63cd1b8dd4b902065f5bf1f",
+ "50f7f44aa75644e6fbcad666a8b7010096fac5a325b764185356eb4536bf9b4e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 3,
+ "Witness": false,
+ "Version": 1533286556,
+ "scriptSigs": false
+ },
+ "hex_tx": "9c18645b0a724c895600000000000000000000000000000000000000000000000000000000e3a813a4001825b82541fd254a0000000000000000000000000000000000000000000000000000000017d9bb5800f36b8312fd3445a90000000000000000000000000000000000000000000000000000000015bb76970047c67f8649de677e0000000000000000000000000000000000000000000000000000000095fd92ab0052e4e5a60612c9dd00000000000000000000000000000000000000000000000000000000c414d5f3000627a6afc3d86094000000000000000000000000000000000000000000000000000000002b12c172009ede9e0076466cad00000000000000000000000000000000000000000000000000000000596d0f0b00566218498dbbd45e000000000000000000000000000000000000000000000000000000007beb01e7003bf7319bc6abdfbf0000000000000000000000000000000000000000000000000000000003086f11008d331294fa7246ed0000000000000000000000000000000000000000000000000000000038ac0ae0002eb27611031bcc3774906c3e08c88b5d21712b17491cdfe047fa41792d82f2240ed56ca69bdc91cb9d2253ea6bb7fa58721106595a14afe68777034b97aef9da1b2ad61e89bf0dbc7e099772c98733df891f0c8ea54f0e18b048fb92fb09cee8c8db12fed33ce9ec4419c210ad55b3ffe3ae78c58674da35a1fe11ceeba8894d07916e8c954e75d503e682d75b727eb97397c4484ddd1b1ac1687d312bfd7b782a175d54bd72c03c7d9f4c96d5e92788531026afefda23033849786507e380573d748e051b7c20eb351ba18327bde4eaaed4581f45fbee6b296e6ff70841c82325cbd9993916e0fc9a13773bf56a6d474b4030255d81a98dff2add45a62d087b6a3fe3beb5f98404fe2a0fec6e02a0ff9fe2882a1f6d0a071010f874d453a681523e7c5af75f01fe41edab2752a933d2c9aa6d21f9e444a81fa20137ec17fe835e2ef154ea09b70690251b474c451a98e2e0479824f2fbad05798d254d61a9276869910844a343d7c2b6052e8c7bc83920b8fbbdbac71073e2e0331c74dc0711a98da61f89c09c9f2c032b0b651e4adffdccb815bee12be6ad65fa09b3d506c01484b2fdad8378806dd186b1a15c6bc8f2285bb100c9e8cb92954902abe937185c26095b8e83f07f0fbdad0241305d5f9d7fcb9139b78f2eec323aa6c3a6b985d13a0856d815701380628fe00dc33714646b0747b33e1798ecb9c2c86080c98614890853fc6f2bd5222eadfa8772dfed788ca957e263ad79543f3ff445928517ea74bf4d940dcd3f3ade13be1610e95c829ef0d321e10e74d4870b3ce9631a3df823c3c77f3da05e3459905521459e56f51b24e1d6ef84e8c7d577c33a9a0af562346e146d209bf30748646d0e93253233cac718a78e861ec7573b9a",
+ "spend_index": [
+ 0,
+ 1,
+ 3984766173,
+ 4294967295
+ ],
+ "result": [
+ "dcd0a0e12591c98a2d6a8881c7a303d9a0107570f391206e6a691be2832bf4af",
+ "09a35802c10aabbcf77dae06741f299bc2f93ca5f25977c83ed6a7d192cbb1bf",
+ "9d47029c60a2d62dea9a544428c76c2751a966454d2098b6607356a17c43c52c",
+ "8fe316a21ed6c595b49766a57574a1bb2c00a0c80a8ae50e71878e48133ae35f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 1,
+ "Witness": false,
+ "Version": -1046185967,
+ "scriptSigs": true
+ },
+ "hex_tx": "1178a4c105c301ece100000000000000000000000000000000000000000000000000000000d721b701d934658ba935670869b99e74e137856c6665b704bfbbc3862ea142f2d79c4122ecd05eb4396928ded3430de337873293fa17e094f4d8448a497e86ed07f4f6eebfe0b504b9f0d9bdf0f69ce456aa44e0c557d955f6620dd16b66775e59e8fd6b020f617ac6e68d3e97200c2802b98b302e27027330ad80e19121204a3d94714b122ccde996519afe725cc1e42df805c8e7574ad1f22ce770974957696f4bd5617e1b988d7c45296b8eae5aa2ec6154bce5fe68ef98935594bee11994f9ca98162dcaa7dfe9f83636eb3e4e949443051d46170e324d4ebb015db901a4e6fa2d94d6ff00000000000000000000000000000000000000000000000000000000944fd534689d714e39b73e63bcc0ed267209de8654f17acd985cea178682a69d6f3e0388f49ad04343de07100e4a55fab139497f484a0ef432b02ac4aa15ff9af6a79c11e6576097fe0b5a527fb7de2730180ca5ec0a685ba00400cd6055fe18c0fd3bfedef32a3fc2930b7d477c2c228e26c71067000000000000000000000000000000000000000000000000000000004fb2ca0acf406ea8146daca89cb2329113acabcb1b1353bb26f791f8e660cddbbdea6695ea5ad6c2ac5429b96a4295d230f458af28edbf7f802e4fc0347c529006ff619457bef327dcc8f14b1a703f8cfeee855243a555fc884e7b42f1914c3413bfd04e9851e75e69a013b7ae527cc09eb38e99a9969252fc5132c6192a50c6938141c4e1d13dce8f5993815ce71a60ea69c79486e6edc94c12a9319b39818285740c4c4c4bbdd0780854e61ed2156b0b9c3539bb73b5a94609875aaa141c0d2b45f3c80b04949051bfb9c3f4c672d55a4f440a38464b525778e5500000000000000000000000000000000000000000000000000000000061775380fda10154519ebb2b3f6c9329042bf5b66e15fb04a7378fcdff6dd433b877fa30d197c16a34f1e81436100e40ba642d3705bba492c26d941243536aa945ee6227fa884286cd16b884a810f1935edb0378eca6be19e1f307eb4c25ae28e483eb3c17eb6646e574c90c0a26144b028dd12b311f366f3e5ce59f203a958539af8895fe980ad89458ac205cf5ee2d6719abf1ffb5aeb699bd85146056b7e0e4db8af5fef6086a225c6e88070cbd40576cdc39c9871c7a0bbebbe3883786ce480f5dabb2148b719dba4c54ca00b81cf4b686f140e02cf0ae365b697596002c2b01513914c5bc42f428056c6739c682737884a34782051ae0ce2a85a8e78fa1cbd42027abb7ad79ba5a8aaac04688297addd57062231eae11afe12f43a76c5df5b6dd2b19cd755de1d1112985ad1a7a3a4ce6b13894f51e67f169318d982386b66f10ff9c76f81aadd2815fd8f0f1c33413c2b039260efbcd68257b08ac5a469e8c2731aa7b91c917d9933d24f55c4f568e74eef02108397515d71ee8c4c927e949ba54cf3b29708491a2f77f9e59b232193a22a5d87a86bd47e3f6ffcc47452a47bbbecfd307bee555d58e0a7dc7660000000000000000000000000000000000000000000000000000000074ef9b6e04357b907fc2deda330123eb094c8e8cf937c881fa5c430bcb5330255390144b8bb4870fb37411ea3fa4f154e0f91e09a1cfc9d7d1d6873204ac700fe3a9666995c60afa111d67e1dcd83a687544cf2c9e644d7b34bdf57366e9ab421bb06c43688f4d1c61fc3715ee013ca7ce0d1fcf92200efc00434ff1be2d1e649149c3fb0e1c2234615260775a6074157dea4d1e93b8b816882bdc6ac9ee8b37bd9eed50984814e8b8aa86f16e08868680e370941b1692b7cb049f70b0216d689dfd61da7584d1a0cbe87dbf482dd896bbf1911cb370f50e4786a61964503d465ae85e",
+ "spend_index": [
+ 0,
+ 1,
+ 1911039603,
+ 4294967295
+ ],
+ "result": [
+ "ee6c9fa448ddd575489c1c6605fbb7074c8e4221b064d37ab411e9d40e9b3958",
+ "824e100dea2db58dbe671ed74407eec9457a11f9f1636def3eb7221133cbb77b",
+ "37ea4a8607541460dec37f853aef9bcd1907f35222beeb840fe5fc60c0ff153f",
+ "02b79621a4fc7bb9dd954bb7529425f3bfc3e30fb08a9e5919eaf0dbfbf51545"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 7,
+ "Witness": false,
+ "Version": -2076899950,
+ "scriptSigs": false
+ },
+ "hex_tx": "920535840a59faca3400000000000000000000000000000000000000000000000000000000a9e8d77200c50866e0c98126000000000000000000000000000000000000000000000000000000000008b19e6900da1887d7aa74b60b00000000000000000000000000000000000000000000000000000000d17f9d8e000d3461130ea4488b00000000000000000000000000000000000000000000000000000000692258aa0097388421766867910000000000000000000000000000000000000000000000000000000022e24c1400e158e46061fe236e000000000000000000000000000000000000000000000000000000000f35b41600425339c4ad6e6d2200000000000000000000000000000000000000000000000000000000e71b5205005eb69b91b3446cef00000000000000000000000000000000000000000000000000000000fa113b30001c1a31129bddb27d00000000000000000000000000000000000000000000000000000000af19a36e0084d7798bbbcff00d000000000000000000000000000000000000000000000000000000001bf81c940008ea6d2007a78de3263d376b5bc87810e8b9bdf0871b5316a7e3ef908fcf6da2f6a2b9f424f903067212284e13c7484f0393dc9bee801f78c18528ffd4717f5af3c481622baad5f08d6438da707cfd0ff5ce38f2900a97816c410d7f03a209670a248b882e20030b5da281c886fb5e2cf5977ad0aa348d7eed405783d49088be3267e13d0c8496b3da2f17b50a19b6acc5e4286caecd30e6b4b8da7177923b41e5a55372260fd7e1b7576cb2606f24333db27a063545f0272b7d5e1ed92040bfec70cb08a21dec01e2c978a4d56ba03255009476a1157ff8d4e465ba1300c8357e6ea7606fef3e35d16fbf5aa62e00d39f17ecfaa17ea3817d408350504dafe86a8438aad424438619ef56bdb49c9c75b16d2b9314c478579556581289453e501496b71a2ac5bcc11e897838bba0b43b782676a1f623be98ed73be1dd78e6c0310cd9b2ce30412880eed4c7ab384f49c809b508153e895a2a74d23f318dd406d402d1b1a9a895e8196ff5bd70407bf13ed8d0f26806391e25300dfaeca3e9f699873cd1798f07a73db45877dd40866eeb01bb61cc9b14aa35c9443a1c5040068d27591d48bd1bd19ed0e35220e312ec8d2e86f19d247cbe312604d1085744923d1dadddaa82518e29bb62b8a9675fe68380e65c456ab124eeaafccf1be563c928b44a29cded0976804a71528984a3094a61100bcc4bf8a06507a2cf699d751c48342c8b1ee71a629281d029e7947a59762dea77b82f52988c418890d2b46c4882d95e820d902d28430d6c75d712e3af9cfc3a4a38b750893687ec2704dd52974adbe611aae0d59eeb5453bdff8065a663ac66a08cece2637773cf8cec3e26ffeba500eab639b254cfbab32f0e1c224f88ac82d742e518f0e0fa9652e1ac2c278c88ef2ffea2c424e534ca1b6c2f1415e9c28435b3d32027eb4c7004db3fe710d99ccf7e1118e67a40ae1808e00126daca873e14e729312b1ac6f656cfa0428551aea725b4d73c6de450abfc540eb757d8faa56e7dfb2031cb25be2c43a50b73984ab718843621bffb4e46ac17dbcdb88fe92307dfb25b68943a79352bcf697c4b3834aab77a8bccfe5c82427d1bf527bd948a526217b8795494ac40eb7779e952686a98c7690822648f5e51ef5b930e0ff50e2c7b12386ae7cbce573ec0c0424cd7a415e5abdbefd943c750077a2e0dd4dc8db3cd669e67d95ced6ce4aeeec807dd04adc444d16cf798201c4978e9e5d31025e5879f64c7442d69599fbbe5c5ddca1ca6d1536e0e720659e94abc72e356b0aa3252fe09ad38139e3424bcdd515647877353adae83b439b29581c6e54c8fd012f3cc61909200781e2c4286fd38cdb551202e8d3a52730424d85cb006507f405162d1c66835ed25bee89122fe3acd80e765e3b0e2664dd769ff0ccfb3cc4e0adcfc9973c4b5950bbeff23d1bd174819a2a05aece181020baf02cf9b354956864596723c4c5637bb1f936c5b8d8de9344c8d733db7e9660e806a2f05ff14e92a8bcbe8d5f23c7749b4e96328f30258c0a6177a45a78da8521cab5bc8760856aa17726a323bd7ebbca1de6c920aa240a2b276c6062b1834b61890c2c1863e2a1adbe800d8760b692edd6762c4a6e23a8525094d0da05c34b9bf454e4903fd96f16571bcfde3870a330482439fb9615934970a55672aef616758ce3c2eec43dd516c10a005ae2a88072550558ca99760a8a1296fbe87bc774e385627cb8bb2a8b3ec21193514ad93baba6e78b6eb2b1f54c617695e40542197ec16d1ac99df4ed733fc8466dfd3a5c4c3f1ddc011f4b45d478c0e07f8933a3529b657e9c299ac5ef3d35b60dc9331a933599f06fef18492dbdba766a3860ea7ed268217c2341baf40b3459eef3c9ea382ed7ff18dc228d365e4964ccca1270e5c46bd381a4f151b8084c64a22e83c331100419430963060ad26897151a78e41be8688c739c86d64cd19181ee1a24255f5bcd5f37f15c859c04e85211ddb6abd218b94881e7d626fa288d7b92620085bb9edcc11c9d85303223af824e59f112350cb6af413b16b210c8627d2b61c60bad730f6c7d41db",
+ "spend_index": [
+ 0,
+ 1,
+ 1039465161,
+ 4294967295
+ ],
+ "result": [
+ "a2a16cac35e718b07027623e243e73ec51e6c6465302cd6a4183dcc4468aa8b2",
+ "6ec7b9f66c1dd580207d465450f9bc88e9b89ddb6dbaa8217bd4d818263977c8",
+ "e9834cbcffd8ed9419d5f0dfc17e3d23d1676ee29097822792c75ace48dfc38a",
+ "f15f04bdb876303c6a20581f561bd525b702fd8fd073a9178e405ed42b9683d7"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 5,
+ "Witness": false,
+ "Version": -1778983691,
+ "scriptSigs": true
+ },
+ "hex_tx": "f5dcf695093fc181e8000000000000000000000000000000000000000000000000000000007e2483b3fd1101d6690001ecc003832513a53dabcc55b97f41ecd703ae104fe896e0456647f35bd0660bdc3a90d8bcafbc654f44512481794cea474dc3d663cfc58b213c0d57ee05a04ed9a18845a52087b93fa91334b891e42394183ed2ebb43eacc66be1fd4029b5528cd19a8cd749f8799fda3c7a844a26b6463c310f0ce6b20499d1f0e2a9dc12a8167342009371d688e62de4878a9f4fa068aecccbcfe28e59a5cfe0b1158ee184c36bd2a5afe0c26cb430494def39b2eec4fd0ece252b427fec0bea90e5cf595613a5eed4de54b35a89716d44a2d8a79fc39426d57fb67da6cd1b38c61d3a96b838495c4f5aeca6e9d43eb0d024014151c144bf2067bf6d31932ca44c954ccb7c562885040113c920ada2ade923e31fc0581d7bf73097000000000000000000000000000000000000000000000000000000007ede57e7001cd7d0d128797a9d00000000000000000000000000000000000000000000000000000000f949822e5385ca0bbdf7d3f0882caf0d83c26d2036dfa0b8379fbe6c5dab138e30dd7be61b5d85352848215842755713c53cb73b04109852e9806c6794cc26677de7a4cd06d8ad00b1c8365625f2eb9e0e62f57074160bbb2d9c678a973b77090000000000000000000000000000000000000000000000000000000040141ac2005946c4007a4a255800000000000000000000000000000000000000000000000000000000d6f015e1dd5ffa5dd907049505d2988b546018b952e3fb159d4de638d9489ba60bbcb7b72d88f114af486e6538c9144974214c22996633b87b937fafe846616a5cb843b630d3d69f5596b982f3160c3db7b086261310491f65e9350d66532561210adb31471b6d33021a10af85eba4496e1d5b780d3d730ae304831fe2545ad6bdc1ac463342719a2a13ef89bafa5ed0b5e36c08ba70f0b688dba8e7ec9192c9b6896918c9038176b9a52006059b7142789e1b587cd4904cf8c0cd9cba8a07baef19f6b060f13a427ca073e61f05918a7af7e1478771f2f7a0cc81c519d4173c972850226edb725e0c1600000000000000000000000000000000000000000000000000000000cf75aa3ffdda011fa6edc21e87d0b325c7cc142958b9b6613e10da0e532fc462cd39eed889b95fe26e020b4a10137ee033049364482e0c8962ef7ceed30cc4fe9ae6d153ccdfc7a317781258c53b0db40bc2f1d43e5089728ac926f2daa82076275f0ca2c5bbec79d310aa63319cdb6c39ac20a191c24ab5d755f18d4379ba40e0496f425378627dddd02946e82ab8268db208d64d642ed556d0328ca41ee3f4bbe6cc17a10946976da05ef023cb10c08a5a97b29e79bc1884540356b5c92254d84d1c551a2fecf7135ba82f8c861b1aa55cd0f56301e40a43cfc933719cf67e4c6b0c36f9927e96923b944bfc202195b434473d18f0f705b1d5c19e37922ef2f4cb50273b840ba5aafb90fb7b2eb9573da4514c4df6534841f945237a8570100e723b111dbcdfd2b5c6e1d6ba2f9ba9514888705f6dee8b1ba37013ca47dfb63504d6d69f7a388282af904cc216975ba9da3ebaf854da5c43e6cccc208d0d54d6ce17502b86427e8bb52f4115d077a0af341363b5946de9a2449818a4f59159d75087633fbb1bf6e5b022795a9217583e54fabf3170068904d706fa329fd9124d2bf1d72f045d817a510539558e7b2551c11925b06101652b42377dd6482e447b7a16d2c5284f706889811766f0128c367860f617bab532b7bb2aceac9625df264290857a69c8d3fd00000000000000000000000000000000000000000000000000000000c1ca65b1004c9762cc725275cd00000000000000000000000000000000000000000000000000000000cf012455fd1f01f7655f0f0ab2cd04fd4c9721d2f06cdf394184ac47a9011c04ce52b65be28161cf788f3ea2d192fe7b4f4230d3dc404c449ff4a7a29a64121844c4022b54cd54969f763f46222d0e11ffa3e66a87d535488af9dd4052abe49c289cbfcf7d7f649f0e27705e802275e460253a29e6ac2856488aff974ea04e8b009c53ddf849454a219fdb3ae9275b6156fde5870cf94eb37796c243dbfbe231a886cf42343e5f173b9a618260e062f0a020dfce2ca617aeebd7e3be3e586524ced4bfa21a584f5744a84c609b715bd912efe7494d26904c8e43e4027df4d894fdd8fc79c1965cccbf9bc697c7ede9441715335dd3b4666989a9ea75e76a1c3a494fdeaad4848dbe2f04b4131b3a579c3914a5c5227fb196c837adc7bf21a423cff2cd8cb5b71d078639df7b550000000000000000000000000000000000000000000000000000000000dfe9df45fd63019188e354948cd4b72d16860c58deb309e252eae07e31be10dc9901b268080e54a875f645cec2165e958f00b2d8ef994a7bd5832dea1496ebae1905fd46073efee82eb1bef614aff71cce2ecd5029442773ae07ed35868df68b80897c0a65b6b61748eadaaa9ebe4d2d125438baac1a2ac78f3e3119e7a8d5f0d2b4a134c724b5126136ded6842faa8e6a4abf6edb4630e4c878ca8d1823ea01bb9fef5c9737db5671c5f12bdf5aa8615d19bde847105237130bd3952c426d5cc1de90905e27a96cdedab96d44153d215bc43db1e01c2a5940cbc371628d3ad7fbcb1671506246e682416ca0fc5e72c2c5010e9f3270ad3e9ceb8d0505db9f4ecd5342957d5372ede3675584ef74ca12dc7ae5df95d870835ebe6376ff628b4a34541525bd7d5f6271ba67875d7cd5b3654af6a91cabfa23ddf0e3a3816b214046b143f075c9f58671ff9b9b730d606485b6304db2d140851448777037bdbfd60009b7ab63e1e729e607322f398605d7fa164923530a5fc830ba0382cac05055d663f26fe99a2f5dc7df97ecab542daba3e05dceb666cc2b73dbf235b9db9548844ede8bacc71194ca9bfb4ac6e8a0dae54df7dba17332cc4831bba6561bcd4f7f3ec5e92b634390e1c135cda417c587ac97a8dfbe295f7f953d5bca200891b39f19c190596cfa5cf90ee33cddc893ee9a79fbb836bfac4cd0e594036da081013cab6aadaba86b43b288c4233c3d8b4f42a236cbee324c7ed9cd1981c85a4e46986909b8700c08f7162ce886895d49cf471d1080adc7be83394d1976425eb175167ff0bb6c0ff820c833b09daf471a0a20aadfb9fd93fa8d04276f2e48adfcd3fa7a972783199b63e2669380c972f3eb280424ca5887605032ce9ade7fde8f9c61fed04ad62a6b85a40c2c473eab56443a2f3538681a9a8be50c5b4efd6d542882b6fa904969fca17f2f63ccc6da45c05dfcf3d52fa770c2966923f5928360e2ecac4843de70f57fe214696c105ca61e96b1088843d250d3824948529f2a0a77a59d5d4151c03b4a47324904cc2941cf40e49f6d2a20601d4108272605d3917bfb294694ea3fbbd14411959ce4cea3d2f2b68bd5d55c839c0ec89b78417dce13986b76630d44979033fe9f899c0b0d3b88efbda0c5db44f6a3e0dde8a345f922c003c3509dc540b74ddd4c88fa65866b5c465bbe0b2ec09aef7ac70dc67dacbb44d3ccf05642205c3c927d0c545457cadd75aa93e19aaca697e46474986cf788194555e921117731633f8ee7ef0de7143a62dda72dcfe9926958d67c5f61522f31c8ae7c0cdb228a283b5dfada72b94e5e4427647c083e1d45d00c39bd17a78aaa8e4253950b5f354b90f26376e09c8b87cbe96d7ffe53318842b2ed13a3a13bfd138b1fcffd711bf074c8644c9ed0edfcf98e37cc6322f97fe7dfdb3d961e7034687c278a3a03b039ee63726e2cff8f2a14530c639800cb6e3c05680ac03763ba60c4d39cdea5bb441856d487bdc57fc87e0ad23c5c45c117b7fd0f52f5847d26328c55865329a37bf00c42304bfab148191bfcb5acab3f801cc9726af71e89d2033af0d00c5f28fa28fa10225b655cd3ef0c5f49452a392dfb13db9a0647b6eda1c8bd8e4b2dade1bda2e1888fc7e503ae768f3ea27e5a42071d06315efec064371582941157502f8169a444371949083b92bd798139d5cb7e4fc8c440b761cd8bc8fe8808dc74c0c05812bf49f97215994efcdc6e3cc953cc5acbc4e40138810e326af9ae379af0d580351a0f1052c50d93a4dc759dd2345be179c30f5625af069b5f5c4af6ef956bf3610b5f7e6e87ca462b6633cff354a9b74139a3c7297a8bca323ee234f6bf639d1b204aacdd9a18f56e4ba086d40b0dc800a79a80e4b81b20a45d3871d6d2b7e002445d7747b261cdb82704357834a7025663c5a6ae43c0f21ee3b8547af8ba31a59105b25d6a4b47fc46e124a6b92d6be05a7223483fa9df16d6191028",
+ "spend_index": [
+ 0,
+ 1,
+ 3001707671,
+ 4294967295
+ ],
+ "result": [
+ "930292e885c283bebd8ff54113a8eafcbb7ecdd6160d3fd243bcfaa30f60cb5e",
+ "c446abcce18fdabe4b288924b4aef3a7ed504eb8794000ef1cce0ffb25dec6ef",
+ "2526dcfc4befb9e6538e5aed58471450ab49c9545e65469894db81347276809d",
+ "4b1720584038bb4e9feed7f86aae31af7f1420d0dea479084582a0946d7d1706"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 8,
+ "Outputs": 5,
+ "Witness": false,
+ "Version": -216890641,
+ "scriptSigs": false
+ },
+ "hex_tx": "ef8212f308a82f1ef100000000000000000000000000000000000000000000000000000000a4a996200000e822cc553589640000000000000000000000000000000000000000000000000000000017ac8d47005aab030d2fe79b6c000000000000000000000000000000000000000000000000000000008b7902aa001f25512aff3f4cdc00000000000000000000000000000000000000000000000000000000b2f03dab00e670be7b3e58388800000000000000000000000000000000000000000000000000000000f9ef4a420013ee1575ebc610c600000000000000000000000000000000000000000000000000000000f7f5ec79008c90fd5119b2920300000000000000000000000000000000000000000000000000000000404681a200cead0795af49e314000000000000000000000000000000000000000000000000000000008aa15dc600fbd521f10561d44a64b3e1963bc8df4f61fff9222beb129db5562575437f9a1fd8ca574d8807ae99a9b5cee236a626bf943342c065423e161f267e0027b3feaf36f52719729a3a0ef7697c4409ea4bcf412eb5fe072d5769b239597e45b992c9b4b7a5bccdb37fb3d467b27af3827836e651316cf301c6f286af4e0ffeee5d0434f28db1c34428516e16af6e4ae82c30d56e6c527875cfb3966832873ac00b5c7fc278f3b7eb9e5b05e6af9660e4e4d0f62bd15aefdfb1ff37f77b6d37bdc927a191be7e7959eeca3a2989363f5fb7cc33be81cab92da130f382dbd83674c8eb2acf122ccc06f14677382748ca1277c49a9b247165f73afd00f18ac30a4996825a77a2ad87b86ebdfb7ad14ae2dfc081d50719cf78837f512d5d0bd2c7ac651b53c3fe33ec06952394ff36d6dc5283068151f893047ef6c1c002b52e51039c64d15094a71d39e4b8ff85b2f6f3c1e15821d03483c0d95092f3dd637c98f6176ccae4e22d5182390447b35a92e728576174e7bcf93a81dca7a7993fc9e4a465756fb6e30687858bed579fa3c5000d1f37963fe5d6e62a638eeb8ec1e3b184e0ca2c016113125cdfb46e57ca2082da3fc8148741c8961ab884272045a0768366cb05fe8216a330fc28c7e9850435a8dbbb4355b5bfbe7d078db61c33157dc3b615350e23bf487c372be4421cd89cefa10e365c0188e80cd53ca6b87b9efe6a0d04e6f3eebbc1b2b58fcde6989533c6eeeb23bb2411cc2b01f1ec28948fc8b971a753c30be63783cc33028061fab62ba388b3043f66fc544f9c4ee231808fb56a4c9ea308c742ebeb8b5146e2b4ad972945baf28f6f4d74b275a72d9e097076af22d97e65d08fb0e0f9fb309df5686a51f839fc417a72bf2c49c9c9dfa03a076a6dc81179ed1a831760ea97d2a2621a69b95f603c5cd08a22670408832654819c406b24a88c2d13062ea6949445ff95e118d7a085f55c1787320bb9a4824f6a72c0a5488862b9191873ca5e91258ff0d175df136f0aa8d13b2a7e4369952f7c2e8e4d4b79a0418ab32a6fe8ef92d026545c25cf997a4da4e39c6322fb2be30c818f115edbf6df5e3afb196420fa6fd2068bfe3e111a6cde0c296cae0ee7a54a8c4e15adc38ca8855719d036b27349283359591e9cdd00208717eb8cb42ca8e2347198d321c9683a2e017875ef3853221fab31c84cadb6436fe3cb56c1ad93be49cdc2490cb9968918cb01b294d2dc694b254ffaef397aa5b83d640d06cae8ea97812285e57c3580bda02213c481907a4d917ec7ba2d635ef6dd58a3ccbe451d627e270270c0d86857b7263ae758e0a55b4bb290d48f8588c0614a1532e3b223dde1c837ca086e6753cd6031102bcf57b1b452646bc6716e3a017c9a90d0097333647d7e1bdeeebd0ce438000b026142d165ab676b691175cec7aea89e383211d9b6034b4f284ae651424351bfc70545b78b263c7988ff915a1907ec828da7fb",
+ "spend_index": [
+ 0,
+ 1,
+ 3359567509,
+ 4294967295
+ ],
+ "result": [
+ "685c624863f861c67e4a8210849c73759d3347ba3eebd7fbc562135f7f47672a",
+ "0a610c39cc9ac49b0a7cef972d2162fb0804237112d98a17c38f8386ba3680a6",
+ "9a6ac014df6a98749b0911bf326f7bcb5acefd7ac764952053e924760d3cf15f",
+ "ae96a56a28816b7e586c0cc694d8d8c15004e2cf87f1e06b68994999c4dcfe3f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 7,
+ "Witness": false,
+ "Version": -1883448568,
+ "scriptSigs": true
+ },
+ "hex_tx": "08dbbc8f022f54e72e00000000000000000000000000000000000000000000000000000000877ac0c9fd250134ae14a0b9eb05820f80cd61c1d7a6e6a729a9c84e4e2c4e8b61a41aa855ca108a0aba3dfe312988c96136dcba486c17ed0c9e100d1be2520d34e2989eaaa57810b12b333cfab0024f5733060ae2a4dd79528850de0aade918c188165ad60ebd5669288d078fe6b78b736ddcced05873d14775f648b93d319354cfbd90a2db807fbe5f251c4d654eb82d2496a17c28855324da8989eb9386b6e50584a1681546d4cef79a012ca3482e8cf9590f885775db885ecb22bf1672f7952a1349b31d0c95a2ad47c13183edaed9618d50c11f26d7229970d1f8c4bb9b7e8b29554ca4704c0028a0610cebfe85995aeb69981ce506959be35fed6954bea67e9537618a7ebb02e0d96cae21baeb41d05bd2f2f2cb813ad444360714c7729db5f6b316cb07da13646b60fd0de862b92bc0e900000000000000000000000000000000000000000000000000000000f3b39caebb3e523c4a7eb0ef24bb945994e030b77a3f44c82343d4581ee2374e0124ad3758d3c388fc5716f0d2990e263784eda69cc2938631dbfbbbafc2de8aca297942516676c0d33b92add38756225130848ec9f6169d3fdf3ba22a82443d1e01c61022fe9b748b67b9facafa5b35efb5f529b57e771f63fcee5b9122957f56ff47be42e2870bf093754cf096025f219f3569d400dd159c96bfe4f1807f638325b53073ec6f8230c230036db0f3ced100f422e2c708b2d507e3a27c907faa9554fb5f070827e935bf9e865ec818c8b59b541e199f7c7cd377a7297625904ecf0abb0a7756b0fdbfa7e3b583f90f5ade635f885f80713f318c59677f090f43a75d9681e4740c9e1516eb7670af9f50b842536d6d7b0121f56be4af5e9abb7759e584613ea51bd5491bb221bff5c3e0c8b7d2a3968e184506c4a2af09e53cc24e34e300918f8c2f9146d7be2bbd6d25945ce8b2145289e7e7a21f84b4cc4a102fb597787f15896348784b717b2e950619c69d561a71c044ac13397eb3cc4839f3ed9e027c65920bef596251b5b80e90ca7da263e8bf27cf37b1c1ca887cc8bd1646a1308e578410aebcc9bf89c58a3f3317605755de0279f11c6e21c6a38eb615083fbd914e30f3241fbd734fc3f96870bd6ce6d39208fbbcecbff639377038fd245815a52cb4c842cf3b3307171a574fed4567c7f57e907663a3dcd8cc2404f8051fff2dfc11f941043d8605b11386f3ff7e04b59976895688c544a199b323bf6b8e7b023c0796ed8b36f5e4bb1d5a12f9d26ad9cfee2fc4d69d1d95e2fa72c25adde053f7e85e7cfbf6b916bb0ccf993a99808092cda8b14921e2415bc65d30a1173dfd3f830a6687cd9779e97fc8be7e5034ae8ebb00370c0900e0305338651f1a6dc93903ed946308802d38d455c3a137445e36c379e002eb02cfcffca370ae2d9961c6ef7d424b962f455f3ad22bda3cf12d68e081207f8d1565e9967014a4a1b06f5888fde8682fd7fb0432cef9a23bd2bea7c26ad9bf5d38308c6ba2fdc9c50b9588a9ce7e2b92e81b5c6e761255b239a20cb2963e691407fd69faf433063e0a35514e36fca6792f4e65c45890da1ec231f3d3b4e75f7f449bdb8b5fa0182443e110ede564a1671027af992f941dea938e5f7da5dda4ab368c575848c864d428f8f146cbb1beab77c483b4b42c477f817e343655cf3f376cf59e4a4ff553e006a200f5e749eebc52f9cd53cbbcd1852c3facee3563181dd7be278114fabc0d3c11e91c29ad4e59057ca48c08755c7e29c02a85174c118612ab99fac76e1d610635138583d0750cbe836d146a156c7c606fccfacff44b9739ca4c4aeae943e07819649edf8278c55e88e3b8b6e74a4ec077ff5a8e253cab1379a13aebd89963f2314d2ed655ede7f71d608548bf3d965c4e168cf13b1b46ec2e1aa2e006d13598801ab392042865667e7e150406c851c1c869a8b07188d4ae8adbb37ec9041f2a91112d95b66b90ffbb1d1190b4d7d1a7a3318b4a550456c9a74dc300be42359ff834542629e1de45a096ca923a5af0f3f00f33ca699a14c6c36fb0edab108387c6dcdb0cedff8341f8882571af05184ebd9846a1346b80e8fc7d28f69d9a020255831203650b9e91b2577f22d82ca5367509ea0ae4638a4dd0e53df0c570681934e6d149fe397c742750f11ca91efc8864a2fc807db1952c19e9a974f1b597a4db66cf4d371eb579d78aa154829799c4320b70ed9ef733d4ec9e33266a2dc84e9bc1bb0802bf456fd27500fcbb02fef049ded55990f5dc193ea804b498eceb99fdee7832d3b2a560587d96a71e656994cd0388de4ad2012150dd728b288f9e756b5defac7f56f22e770f450c52ab73649b790ff10e9190dd0f0c45a3dc5569bd7bee562e67e9ee9a4972917c346410735954b623547cd7336455f0d5cd3986931353352d02811e75e4f3b7830f7dcac8fcdf0b515918d2b94f2666a7c58e0d8d119cac528006cb0f30cb7bcd1016323f7e7906d1ed5aee15e826403cd3c744ba008d1ef7a2e14cd8d97ed77073d851c8d37c096e1245c704af53c461e561152877945c9be828a1ea32094b9896752086a5c13e75e0eec5ce591f4b5204e9f84fe205d6328c693ef23211baf1d562b0db2fd75a3c5f874ad5a12630597dd94091905f69f2b3319dca7b82b23e4d97f8c84b05dcf3aa0372b64702708a0bf89c3f135192f07685c6093088a6c11a84423a95d450710f5628031be2aa82f2bafbb20a249d8d9211fc979e977895f28bfdfa3c7b74b41aecbf74f150561143cd019417d4cae61e1fc16330948eacd2aa926f0faa413d634a2c496294cccf",
+ "spend_index": [
+ 0,
+ 1,
+ 3425086302,
+ 4294967295
+ ],
+ "result": [
+ "c4ff54c5b6bdfc36141f3e24ddee434094858fb57bc0d0249c70d3898c65ddad",
+ "209df5582d0e9a7e694ae163ddad064a842b7f98547fc16c7273f1caf2102ea4",
+ "b8dcc1666c513171ecdc329d3041f567ceb4045be8f728fe130490774cac4aa2",
+ "6132d4ba22d464e4b5437f79b7e4155035eca1d50cbb8822f2cf343f293d97f0"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 8,
+ "Witness": false,
+ "Version": -2124013575,
+ "scriptSigs": false
+ },
+ "hex_tx": "f91f66810631a91e3f000000000000000000000000000000000000000000000000000000006456780f00e54408763610d8c7000000000000000000000000000000000000000000000000000000007873c2dc00b49a2ef2a77e0151000000000000000000000000000000000000000000000000000000006d7056ce00aa6eda299fa9ce6600000000000000000000000000000000000000000000000000000000abb7300200709c29b21639f50900000000000000000000000000000000000000000000000000000000c26433e000c6b3e924b4ed2f3100000000000000000000000000000000000000000000000000000000b202ba1500b43c304d08472ab497abd2913dc82c05bc0c7df3fe622241479aede78410e9e0fdaad46ead2cab38c427309fc511f552a2d31e1249af40883d99d1bc8a74992361b8a3e2ee64b1af943efa4420caed82c1ae35059c08d72e4cae205ef4d902f4552831651f31032f957c739aa835bea3968c67a96dd150c6a6267b4f6583502daa96668012c19cbaefca3432c240ead9f5d41ece9275c809b876501564b20cf4b01b084ebc87ca4bc53b7196c52940175d2009ab269a4ff710fda09933a59076511c40208a873da1d9a1614bf906fb448ecbe93bf67f417f21fc46bdb630c8088bb17da2a0ecc3077fe5c3d8ab5900eaee042c40fd71664607164b0e6255e151f125c6af0726d8b478c8bafa522c8ca8edf1c151aa84f61614e861f5ae9a4c7efc1726fcb4e0f0971b87f55c14d64d78d5b07248f0f8ad0bdc700a89ad8df8e2b446e2097a6c96c3f9f1917bfd64042c6f042a69219846da7e074ab3d2015949ca28d1df0d205136abb6526b8ff5889bcfd199eef182d71d1d423d9f8cf44ab1649a9a1ffa86512973a63d0584ee127e8cd18554a72eb9a91a0f19ed29b0cffa7598c408ddc8e811cd35f685545644c8975428b075e0eb87fc1af9004664ae0edd8484e25ba8d2bb1fdb028ce63c738b6c27ba304cdf393c6d77619b929ced4db5702750725938addfca160eb66385d1874c2ebf0827bac548b9998f2c4b19744584824e0bf1edfad072f2d30a8530109cbef822376fe7c2e7f7769849840e946bbb57070b31f334593f3ba0bf01ccdda6b0c390c42c4dbc10b6d4c77204322637a9841536cf46867fdf63801ac0e6ea2a19a33cd15e944c12d3fb47702b3c53f3800bc6a3a6b38d3c770a0d4997414afa5eebe422ec2114d6e8512f67350c14c823e4fe85bacab8814cc2bf4509c294f69f6592797dadd9493a06255d808bb882ecc1bd2a997d499a3d2a03ba208f4c252ddbcb4b3a07effcfb3faecc09447014489a2babe90f00c4d672ca58b959fd61c2273d80d22c21085c17a182388877c9cb0a18ca79b26126b8244a0e5f09892acaeffc14df529febafe6046d4602cbcc1d089d97b9d9275a914ddeb1e24144083ea3e4107bb499b5c1079927a2e46892d54540b783676f45b7ae002181527a3c71a35cfef62ee769b79a41805a6a70ae2c79b05a38611bb0b82de3845eaf6879c8780514862fd430b98d94d1838bfeee12d97aa2483882d8ed993939a93310c2d8822fcd9f72c4adccbe3577f2989a40393f52c70fdfed7967272d3c12b10d6d695e36f08b0432ceeee160db1b775be0f812e0e6898985ebcd51796ce9dc3b3df9bfcd13df766eff953e4e142c381e7c3f32c1cc77e4726ec586467b474bc6b3634409fe14831fde7dae12cf7583f9ddfbe98144d39025b8e6e7f69b0dae60bc0d3f4f7a0029eda87e8f26c3458977af84ae4e7fb6c0057ddb9b48d5eac73160459ee15c7281bc103e9bc72e6389830000c85fb913f2dbf8a1c92413244216f9ff4b34d6a34a2281943f1a343b8aade6cde15e15f4228040af5e546e45da72e1b1374b61a143a238249400e2f5103e25824645be9d35fc74b5652894abfd4174608bee29552b7b88096181eb342424cb0adedc7285add1cc4253b2d76aa112c5ed06b3a103f982cdfde19ae64b913826bf339a91c4791d3824de23822025b7c279aef8c9853ef0cb43c180384c073fd6c76815692659fc15295eb62d1c626f981b903fec6fc6ee0c17948041726dafb961eb249a8a44743e66eeff36d312cf3c7c7fc875fb7b42a8d993c3d49b2c90f5703d0845bbe0ec37343e3b501f56a399910a9cd2d2da42d0214ac553bded064017ccc4c07cac9edbfce92b22a7661011ef9f49c1f0410f2c4a7883319b6aa927ee8db5bb8038bcdaca74f158969a6f0b81e1a00c1e7f386db1ecc07a31576fa76bd2c7f957b926c11ef2ab6a1e8d83a07d37acace1a852cd37a26a5d490818d045300a54c813fdda483630fa92fd9d06af62b3a4801406b2fe7b5b7d6011a57bf135754e05ae28b25d9a14c7404258259b99384c333f13dddc28aa41b9332ecee74f58c80d774dc5e784e4d9a4b10679f6947270b56c5f6997ec141de775b4c53be5abe6af8b522b6b7eb1bfb1ae737fff7f4b5779f3749bd44af958ca814817e5bca716083cc36dab89ce480e6b799d43c4a07735bca9526afba1240adeed6c5d4d2c277e27da4246ee0d7969dec01f1cc026fafebedc9aabc47cb3946b986d5a8e31f1bf99d483f4cd74f0e7113ef780e694c31b552b63b1691f57c02e7607780047161b94466bb0b2d46e25a405022d2545bb2749acc82bedb6c18130d6869bdd0c8c5c72242226933c08ebde16c6",
+ "spend_index": [
+ 0,
+ 1,
+ 4231503344,
+ 4294967295
+ ],
+ "result": [
+ "07744dc2bec2a557bd05022b9bb7e12b5a8649fa00963988c524781e0326c47a",
+ "0b270576e396f0894e3d4217f9ee7c85937a63f0d095fec74174b0dc3896a837",
+ "964ada7ea73231c728f3f60706e0010b67516e8b0069f659440bd2fd799abc71",
+ "086d75dcc9731576f388fe97b6fa83d562c8e51742b18330d0856d3dcfad907e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 7,
+ "Outputs": 6,
+ "Witness": false,
+ "Version": -2095044500,
+ "scriptSigs": true
+ },
+ "hex_tx": "6c28208307060ac1d90000000000000000000000000000000000000000000000000000000096f5aa0ffdb4010e3736ac16944cb0bbf50ee66da139409dedc362041859ea64545969ae391984c36ecb9734a42ca92676521cf835910bd259641c74217d715465236a1020dd4ceaf6a6c81f17f0e05f7bce889c3fc10e97fcdc10b3f298f3abb7cac2fae62584a19cf1e328cb4c88dff31ffb5a8e108aafe752f3de151f06516439896c80bcea4c79f71c68a335b4cd167f208d21a997f3640ba9c373410e9c003af59c718728d1a6d849e1945e107206aef6dd4d6d79d7746aa8c50ea2ac5bd839bb24ca291cf37aad53e78d52b0b05b154488f6d1103c50adff728703ea3f4542e14b4b4cc989f8105bca92e67b4e2cbd06dee29a638b514be844b38357142525ba77d561b5bda9811c837b73089bf6e880df1fc02ebd64765b7353aa88e153a2f19babc83d4c060115919f729024a01e25f8bd1455ca6d2a76abda90c9450f4a7744e3964a7e43a1dbbe2d8eb3b80c8ede51a099f0e1bad4db24ac50239fb088156666c90a7dd6d1fbcf38f7c1d3b5cd12727f6afe3c57759b787045bfb2654fcd66e7302386a87325c7506b3342aa7b45fbebcdbb8eb0bd7388e8eb55d078f33760f9737092f2e4cacf38316e9e8033cce9b3a912124f651eb21fc2335847e6ac000000000000000000000000000000000000000000000000000000001fcad62927cdd4fab9908abe626c449532613699ee4dd4a1767012b5da4bee04483c2d036f73ad64a7a8f0c9c549bf7e7fbfe9fc00000000000000000000000000000000000000000000000000000000f4fc86ae37006902b4eeee9dbb24801a0b38a7d194d773efee77edd3f553299a7be77844e580900055aa410fd3a6b92dbd40c0086e458258aade6a33e977b7a65a5973080000000000000000000000000000000000000000000000000000000016f0c5b5fd920153a0a6dac7c870b1be759c7e9ced21d2d7a7f2ec4f3d9ec6d977f204879ef9c4cfafd45f82313778ffadb63a11eee3fbc354141474dda7821646ffc4fb87e45a531018999a7a3f967e11ecf99ded742d67ce91ed31c92d8a041a97c1d44eb75372d6555a9d20c1dc9aa576e3e440e3f21192e02b4001e9b7d766af089c7153dd79a020f9444df960e5bc0881587aed906b66b4f9b92b060f6ba7d15d23355580b97697a9edf34c0c65db5e601513e367c839c78aa408cad9c6e118b5982dbf0ff062a2c5efa0462cdd4f40c25fdc66f727b11988435351b1662b79afdc2771dd23945d617fd8f7c8b1d75b366443ff05764e60ab8ea165a63c71b5255d1e7da579e51836529b24d2469e81b25b0e9bb1fa12ac8e61b0a7c0c8cc85bea23b691e415837ff6786e1fb1d15547d7ee4dcfa4c57e914d142eb37e6d816d4808cb422ac74b0486f5a6d2e3f084610ce1cd5e60b5450d68ccb644e332f65081f6cb873b18b8ebcc3a5a47b8e3e10c1d592bfac9bf1fc2b26e837dc8d5b3680e719789394d8209423a4f633f6587c394255da4d6e64592f94d8839bf994000000000000000000000000000000000000000000000000000000004af9fdc600b9f2b5494ad008ad00000000000000000000000000000000000000000000000000000000cf6104e92b205f957cd7699c242984af2ce868fe1ebe1a25058e271e1f68e2053891eb6888df286721732afc8c3f58e1472aef8fca06d3340000000000000000000000000000000000000000000000000000000087d4389afd340194a2982947fa8f757bda68c65d75284a67d37d5b9921e75ce40afd5bd517c65c000a66ed79a208319f521d6a737434fe9786437f97ebe3ad3fbe8349ecc8ce2df5d69c00cd372f04bd36f5bb2d7a59c7412cde2c0a0b29d8fbe0a9fc3e5afa630a5e88c42dd617f38d6728c7a95b2db9837dfc6db91b52bee2812865e51aaddd8d7e58d63b8f2824e61cd4e73e2236da52fc486430c0e644a6b5940a01723cdaf0bdf79b210971284ad9e9b371bf7bb75c35ee7217a35649c0e50be730bc0911c7f753d43e930100e89ac61e4fa4bccea1d254bcd0ce52e1c8b971362dc02037c236165389f193d7f0be0f7379110c7d81e729f83642d37715b218fdce818036ffc796417df655c1302032692e0030e1a4dbddc5813de030fa52d5d19632fb0021462ec5ba63cd3400538c10cba5e4533e1b956570b681170695dde7418eeb1a7ac830accbb70f4faa19eb0ce2a49ca8e35b30243447bff801b5dfeac06dc82b3229e94e36029500d83a8249e8082aa0b0251e239027ba2b119aeeb3b91a8537a19dd3166f6949947fe6bd115efd3a41106fb98cfe0d4497cac0635c43db73ab70111b402e59b940743ed8d61853f5493797485e3a5e33eddfa6566d5863836f482b21d650e0d05700b0635b0b8851a0c6e6be79027b6830ce371e760ed37a389c589ea0778e4f0551d4ab3e9c40e2990947354c38ebd58fac940e17db022ac5300022b704212647ef6374b4e1117f278857c8d7575345139f14a21784ad6027e2f7ac9d659a3d5c36505c07a8cfe7cd4984db3ab9459bb636e040e3343ed8d7b26f6b9cd3b5a0aa00d1ff62516631dbb43423360fa3762d9b99567fb84b55c91a76a30428758b08668ffa04ffeebf45d78d5c85b469d64a50dba4d14390d0222de714bf8be10616ccb4c3cf1390797a8d2c7f7817242555e66eb525a33f6934a50e1025cee790ca2843dd819f7bfbe6a5934c54420c5e351bcbc959f7ba789fac2ecc5e7260e3f2c1b3affec2f46103642744bbf536320a9450cbb678d27d7d5f4e3ec8f9d5862878725bc018a92eb3797a8178c38a1d96cd43540b7833c0cde3bf66191889e9292bba64ef55241a1acd3630b1616efafa89cfc28f00172124dfad3b37afcc05857d0df8f5c4daa90e4819f7cf918ca0203279204f754089390e14f92a49f47bf85bd88ebb9c16e5335f15fe04ffd7b7f1d621699098b3c685c31082767c839a5132eeb22670608766854ac1745f0872349dffb86099f351186094efba92b2c64810aa05d903e72d0b28a5e53121d437f1cb007c4d0bcdbf80e6cf1ef3ea746a9e7dabc1a66890bd40e732b527c82f8e25ee066e122a639a75eb62562778894efff4683edcf07cdf042cb4d071df24271dfafebd7f952737c977e70d5e20a1480fd39603a43c3808aed3ba9d38bfd66c3b8a2d0f763f5b733075dd6e563052a5286f14f419bb75969fd0a204f430efe4f820a9ace80aa3fb12dfa6c6f6c6b316f1d65c8e85dc819dcf56baba734c7f166238a7ebe5d6eebeb0a2f0fe9c67ea4bbcac6392fb6f3f9ae158b74e602d5a820279a92bfc7ab27d99152b1b2f8139d33402b48ef021d4f4abca738bf27148879f6877a5ed48ea76c110e3fccb59c8638b72a29cf281d2f0a68d14e4b79255e0b4b0a97c65cd207f33c4313ab58cf5a748214931aa0883f533508593529bf05fe60f2fbd4206b87dea735b10175319760b564e231049aa09870884352a721c01a16854e72e6e9e69e611c8cc856847be2c8e38db9c8ff9302df8b94eab53c796fc14752ce43be66b1616e40be6ff409ba1ef87fa8115b3af6d5a1e8e8ec9c35d68126dcd812267f60925cf8a752f730e9263d6ef763540094858f83c9a6dfdf5e2d475a9f2a478bccb83be31059cbaeee37232ee81a4846d187de30e405d4cc8876b83db63b4a2c8e40642a00f5bf318b21c74025ce90fb6bd5c7ed4bad8dd0b4715ad407463a0737e51b7b8f5fcd912cc1438887522757a6ef37d90c9e183c2211ba5e6acdd26749f355fdd7c20f11dd3ffee8ba87191fee44abc5b443a4c96e1ebfc9ef85ff294d6fd20f6fd82ca3907e5c6c20973ed05df49b8be8aa9024d1ab3fa54d994fca4ebfe9548b69c247f6b0eaea3242f912d53ccec595d9b800b6da653fd564bfb9bab0e39e989039132e6e05a6c9f694df5c74885d565cf61a628da54f534eb2956f82a7207",
+ "spend_index": [
+ 0,
+ 1,
+ 3575252040,
+ 4294967295
+ ],
+ "result": [
+ "cc01dc94e18217bd5c50001a2c6f079fb7e37bdd1b304ffc695afc8ec71be0f3",
+ "2a1efbfeda89ef3bc34df79eb7439559c720f2465ac9083beb293f662c20cc50",
+ "8bd0513e5555b8c3692757f692f2d5a98be1db1435251bf8313a4fb5104893fb",
+ "0504e4048cec620be19b025fb0be79c800d3ac8967f7ed5389927bc1c0c620ca"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 1,
+ "Outputs": 1,
+ "Witness": false,
+ "Version": -341052226,
+ "scriptSigs": false
+ },
+ "hex_tx": "bef4abeb01b9bed30500000000000000000000000000000000000000000000000000000000cd79af5300bccb233201ea4eb65a0a33ef7dc86e238642dd5b75af59bde98b69cafe8099d052237bf841e9f921d5f9f1d116e9037f7e9ec2fcbb0969213a501077b99180f91ffcda99a3ae872ce91a86aafcf0ba5d4195743c7f1d2e37d1a8a3c68bbe9aacfcce85f186fa38c9d7365cea2081ee3ba877c794e6e9a228089d04e64fc7931f04109bb1c0c3fa8b8ddd47b6d89f311abbed387ba1ab6cb0128d5d763d03786285b0760a0abc516fbe28a8761a0fcfa6b0675c783a59ef5558c11850a2ceda1ee1009cbec3a5934217ac65a3332128312aee121fdc0e9c56438f",
+ "spend_index": [
+ 0,
+ 1,
+ 2487922470,
+ 4294967295
+ ],
+ "result": [
+ "7fd2725ad65f970b0045073b678771bc28f6c3ffd68463a02b3a9b8f5c135dc0",
+ "351fd112af9b166cba8ce742c2527f244b9e9482aee818b23994b318d8a5c615",
+ "89d41fc99be7e44d57175f4bf9f5dcdaf41c78c6604f45df8aeba2a2aa917b65",
+ "c4f884db7b13f039dea9cdbbba05839ad7c1c6c86a9e4075d0b840cf79309fc3"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 5,
+ "Witness": false,
+ "Version": -47377281,
+ "scriptSigs": true
+ },
+ "hex_tx": "7f142dfd04c83cef6100000000000000000000000000000000000000000000000000000000ae4c929871f6604b51d016cf732f8bebaaa4321b7f2c64c14fd27ab201f245abef6e9c5730b5332365eba96c9d962618dd666ed5056d435d194f2977090492b12e6fd8544e355cf26af44b8ddd67169f8fa7e96a301782c1af391aaf893dff247ba1e7fc10d93e60c7066d1edad9d7a286aba60b47123a6d8ba46924ba9e0000000000000000000000000000000000000000000000000000000088a4000d0024c83103137653e400000000000000000000000000000000000000000000000000000000385cd66100a46e22e9dd035d6200000000000000000000000000000000000000000000000000000000fd6587f7fd4b01a58bbf41399dc0de27960de84d2f4df493b6b2bd1007c2293be63806183e7ba57765f361e3e074683490712d1ce48019dab7dd33cf2c150566f3ff34f20c0bfdb1fa52f58eefbe85bbe548c9caaff8d35e2757de8e2b38f0388267b3a1ebcbe276c546b57b38ad22995f242b0e048d48aba6642339c7889f2e421c4810ef9657182bd4a21721d74e7e118ece80c6a3b957b45c08715745253412e41cdb8ef1a936620c4fb601672d5ee5fbfe0b067735c97ee69f90294827286dded098a1558854fd1569a72e8c3cec049f2ae8a09299e38c6fcb5cd1ecb2e813c24c604ca1578215b84afaa7d4551a7b45dbf3d82809f8426f60246fe9353aa08eb8e5b75fb20e79dffcb2333df7a3341ac0c8d71eecf76bb6ea78f684787c3409112414bdaf31f57b83674fd47477e129978855eaebf0b4ee7f3107332eab11776d4d8b95e88ef2f4d5fa4b212fe91a6d58df8b54055ec18d52a3fb686ac85af069e8beb727436d52ef0053f809a6f7eb49d8a2a158d5025d0d18fd2b654cdda4a142114932a3fe778f1d8761114667d64b6b5612d90115f33a814a21e54e09d87b1e501ec6dd114c2992de6b6d076bd7d9eaf8c4fc071a95a92954bcd743b7a67ee40033dc4aad439bb89f445058e06d0168ca9bd5195d32c029379ead3b9823a5c53fdcf8c0f679b298a4772607d88fecca682405ee30750fd3e93430736417bac7a2ea7e767d7629f2c410a6b355bcf575bad8865cf6925c156cf722f1f6f230562f487f3de732fecbac36d065c82a3ea615b1481b5e873cac4883aaf24f8ebcef166870ef462eac18f18567851ec1952b1bbe8eaef01a134fc47e29e81bae2156e72f0c24631dd04b6a2b56dd5f8806df36f3dc175148840ff7e7ea02f6ceb241ea2365257decf29030542a208a4c3307bbc98f5648cfebebad4611b7eb35cc8fa403d610e2ee1c6cd20ddeb7d9bb142d44fdf4fabc095d70e849885d780aa14bbd3c6b3cd6edba384f2f57fd965df917caa4295f0d9c5070b19f242c9826e59d4b5a56390401bf741ce6e11c5fa4dfc9e229877a04950f9d4b480a0745c8ed95e3d42e92f311e3aa16f58a29b81f0bb412d1f26b904030aa17c532713f37853c0a1a99661f46cb90dd47047165f09777ed09d09779b15588519f40bac3798d1128822d12d1a623b374a385737834eb12a65a128dcc18b83993161dd902ec2a00807ff7de877bf4ce017c4f8b8b67e60b371c6c0b7bb7e23d27b674344eada4eba4c4fd109bc8f77d296919a93abe1f1fb9bbf3b175abfa3ad6e1c6eeba6711bba4a05670563dc37301085a553a08addd120277b2b80d5bfc0db9a816e1b6485309e686cf6333e184c061c8e53c4ec83968be78da016721519b40aa587eec25458b402d9365c983df46b918b947d5e7bfb6dd9df0e4a179e36bd3f9c6247b2fb3fc3f6bb0cf5185ea308324902cd1d291c2301f65c63c6d727fd4961dce3c9ee40a2c68afd1bf543b7c9e09ed1a16c10a18f0bde29d5ded3b4f0fdd9dbdfbd9670bc1d44474d34640105421f66fe5d10cc3702aec23f163f13fbf9ab3e8be57b5679f78c74cfc7955bb251fff9d185ffaea26bc4778e669f2a3ce0ae6be2a920b02a7ffe87d3ba46421234f40ea33e90d5729940e425149576387d3494b9a0cc8e8b5d9f605dd109c9b11923f71f6b587796adc342d28ea05b2c53a07efeb1c01029c08c861ee73fcfdfcd0584919bb2566a20d51def2dbeaed78614b34372af863032b36f9d0652a5390fe4a1299bf81c7217921f35de1b61b970d8a859b8842157c90a02732b3f01b89d3d460027650e0e63e1e8498645170b16e971d36d7b1197fd410b96315e6591a7c418fafef7c3d40085547c3a1541e25c4c4a0d041ccd64ad9fb5b4c62077693a81959223d81402eb7e550ae48e6bf2a2bf11eedc7efc341d8abe82ab66b0bdd53d7",
+ "spend_index": [
+ 0,
+ 1,
+ 3740421989,
+ 4294967295
+ ],
+ "result": [
+ "4e54c0d04fcbe2f8563227e3b507bcfc0eeaccfb0bf210f51d7c953687b75ca7",
+ "dcf22f32f8bef20606c4b2ab7231419160c98f127968fc2e3ba863c16436f3f0",
+ "1b4456e430861141b7fca2414b2e1b87541f97bf0e6f059a397e48fc172be181",
+ "6df11c86b4040e32099e38130058d13414f088a84824c233214620e958994d46"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 5,
+ "Witness": false,
+ "Version": 302150619,
+ "scriptSigs": false
+ },
+ "hex_tx": "db73021206f6d0829b00000000000000000000000000000000000000000000000000000000029ef77d00a31a210425fdede5000000000000000000000000000000000000000000000000000000006dde4a06001a771768e833772600000000000000000000000000000000000000000000000000000000d5dc6bdf004d544772a96dd261000000000000000000000000000000000000000000000000000000006b14449300f2dcc2d158f3600b00000000000000000000000000000000000000000000000000000000bd121b22006ea7b3277d157e050000000000000000000000000000000000000000000000000000000016e3e1d80096225cf5056aec98c620906e73c896add447eef93bd791d8ea403cfb28e25f4785114d9b180a314bd6712bdc6288a65d59a3c0bcbc78ec4ca2a870ca97b9c89791b3a2a7886bdbdcdd110235c949e32f93670779ffea13aaf76869ba36c388e38670640381e78b4ddfa859d4456f0aba6effeb378e0867868db0eeb5ccabc0f3380d9bdde32df0e27deb31a4eea41319c8e506206916b0324d3cb4b740adba3e1943bfbaddc60770cdb61c4acec167cd789dc921bed5718ee29610b75ed9e28df5311d9c3e18e255d5e08a13562fc603650c92593491346e0a78a166c605c8e877d3751dc11d3486775f356909d9b616172829bfbdc854dc858db69f3a6c0efa46c949b2815fe19ec7324bfacc91644f49cee6448535d08fc86d2218707752982c14d70e6d9d3cd0d10c8626a70cfd50b45a8b084b673f42a8e730b772a2e9b090460853776413e5463f98d9e4d377865679e5a9f9e8c422712b32d8063e06ef0cf7f037365f62c134e941dfc1dd019af9256729ba0dc24a60f34fe3910685ce892e72e9e67a35af173471aaed7b11f6a34cc9117140d106976cbbb825e5b32b478b52ba37862e046fc8215a992c37c8f314c6c6f54db4db2a29372e5bc8df7979487b3a094943f981e8f608f73eca10b8c98be884cbf61b6ec388a89489b8312b3c13ddbeb9dd68f7db35b29c47c30d63205a3ed4d4fcf41b37d6915d193dee7d2950c2c5845f4ce9aca00a440d53a457cc1454afe0e3b7ec978c2208fb55d7f5ce98d8b708b3181111c78ca981fecffbb4c733ad474ca7f1db940299108b145fed8e06b783fe266359bd0a3e299aa0d2fe1f1702c93375827228583ec86739024d72d7fb55b62a1bb07519b1f9ec558e2ac3240fe7644bd200b4fe5c271e63c897a952a0f19c39f161a6d8c391ad032b52413178a0a1db8edcb298f4d0126dbed8d7e3d4ad5a61747d3955565792842be7004ccb5579ca2d9c55df5297193dc6fd0118a4c6fcde5aa7fb22559a1e6de40a75e7c0c4b1d9523b2abb145d87bf7fe85988ae8739e197c0950dfe8718f9d1eccc0f6094993a39fe4db61b0e5f8a1ad1c2e3fc619e98cfe73eee0e048f181cf2542afdb9cccd59608dfdd3e4c775e592660084eaad78b4d9482436f7cf8e8fd030017b887831d4a3261690a088e9fedeca9fc0cb8e9e23924a09727b3c093ec8ddd667112c9eac0a33947887a994091ad6600b43df4515a72119b5ab2cf156affdd068d381761b12117441cef46e1588f18a6ba358282e73b7cf83fc967de9d76373a73c7decf3ad86017e5b4871337adc2a894fb84504de61163601e8984c18d8d238cdf376deddd927831f455b5c8897ef01a8f7f75f05dbf70ad405a1f0cb0c4928cd19d486d0154e5de27d5a0cdfd1ac7149d99a8296c1b000f8f11dbd8109338fceea23b292ce5a066869cc1a6dcd56908d613b80dc0d2900c8e28d7afdd99638f5912cdebc3ebc93e8",
+ "spend_index": [
+ 0,
+ 1,
+ 3924639277,
+ 4294967295
+ ],
+ "result": [
+ "c130eb91cdddcae416e509154bc93a25ad565328d7ab173ebadefadf5e5ae33b",
+ "7813f516c93db754f5bb5c415ea60f3b23600eafb55f85c82e0808f593c29d1b",
+ "cb64ad463060f574be299ba9e7433bb25fc20d29ec3dabfaebe87d2047f9146f",
+ "da80644e069e1b695aaa1c44fbbc2be53b7a5b8104f28965182edf5481fad150"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 8,
+ "Outputs": 10,
+ "Witness": false,
+ "Version": -1687061332,
+ "scriptSigs": true
+ },
+ "hex_tx": "ac7c719b088018f7350000000000000000000000000000000000000000000000000000000060ee53ddadc7f6e76bd1e7a19cc794861844ba6bb84193fe748aff616cdbefcec069fd78f98637b764b81522e34f02f600e0c255a01d8ea4cc243621695fbf6a556801168bcb1229cf436d3c589e4f2ca7f015999bba2d22ac41f946d9137f5c858788b7838bc95c38e435ad4a7912aa82043b1c5335a3e9d5466f26dda631761a98d57d6a43814cd3379e66c7235809f61fc5f888cce6a52db6a97c7640e2c9822c489eeb3f69ebe0f0375cc0865701a25a7c1e7dd2ed947a1c00000000000000000000000000000000000000000000000000000000f9585b70fd24019e7b1d3ceefea1103dc596eb827f524acaa0012e73c35f4849c3bb6bd8243898ef39dc4cb2264017ef1a8c0da8c381e9190d9d1610871f64ba9103a9828c14182c7f9d9b1e75cf4fa285333c00ceef4aa5a0017d3a04256a7c1aececdf5faa46dbd26ad8074277c4b44f257c4621c42d30404650eff423514e767ed57375172015f389fc8c988032420aee0ca83284ae543ca172854e0c2ea60640d52ac8f6b0f3530f0b22237ce5ff2fadac7dce6641eb2c8bba1e64216b413f3a78068d4f2f791148a8916020ba45735c8acd0bec26a79be1d90b34d960dc58cc6223fcc45d72ec84d90d38ced9c3f1e924438d687b44992adcef46b8411f90bf3f784bf74c29409278a3d769d2cf5a95cb03e74d55d26d96481e49b40a574869ba8d70e34af1f197713757bc2cb64d2740000000000000000000000000000000000000000000000000000000001d16dc30c0755267c7ed369038683eb583b91a6502c6221e7e447e7686dee46f5691b355edba357cf34d1451d64db554e09505fd6338488a6179a524fed73d39cd4327af7c760e3c7aed42f6d7b13f28ce0bef43ab6c5239aa67329629bec04ab57e4a2b8e4e8de786b7a689b95296a22254da1c284f08267a20ed790f5f0e956eae97876fb2aacbf89696eab0d63a74591f7a5bcc8277648c81319c2739b70e05f8b4b721ee2ebc025baf60e88fb41842b5d1e75acf7bb43499b0ded5a32aff3043304fa1948475de4f504f5f00000000000000000000000000000000000000000000000000000000ebcd37a1196e15ac4a12c4b7b9fb75bc7e9025137b360ee837e806d8f62eb3ff6b3ab00b939e000000000000000000000000000000000000000000000000000000003a24db7af3386cd1c52714962bbfe0ad27e211784ca2428c5042a0b3bc986884d746b08465ef6d15f40f684edaa976ebc352cb25bfd702a8cf255008df17e2fa100e9fa9a6be9d3b999b87d6ce1cf501e9afa374e4315673686fb6cc45e94ba6074c895d85e80eb90a3ffddbf3dbf56c732769cbcfd535c1b04e17547a04e9cc6a712cf62c767449bced4dd3b293b3a1eef8a59753b095faa4dab37da86af77c811c12dde71037500562ea0ebf2026b4808b845f84e2d2020b693bcd2598637ccf13a824db3626d242bc9d8d540271a72265e9d9876c7ddc58182c023dba500da6ebac6977cdff594dc4965097aa26901774da3cdaa1dcbd7b6b52d99112a99f000000000000000000000000000000000000000000000000000000000babf8dbfdb201bf903056b264b4f95f9004cf116d91f9345f3345eaaf0257f684f211dfe3b179cb04af1f9ed6465babefcd3233f255435e276755e286d6a4b5fe33e1a4bbd44b8b2c93661b2ce5866964f8cd2cb23768f59e0e25406e7c35ceda0b82e9d13194ece032bb957fe82559c6d89b36deecdbac9a52b8fee109bc644b746ae3dc230ad1c623eeb88e1d1833b3700b35c99dc7466b6877cae1e6b0a2979f28b4f9d3e6483a9c9b3a18c227798bea93efd6c9cf95ba0effa4faf9dfc213f8856b55d7eb7c72608c6b244621ea350cfaa01c2414b9678b77e0a9451127b63cb5fc862288bb844b8db8471b97380bf7c1aaa809f3552ba550a586fd66b26be432ca1e4f164e62ae3481502377ed31b0cb5d98052c24f9bc8ae49a873161f76c8784414a9ce487e8e69f8c0c2d4858552867d3ac64b6836b9d3a17f439718f1668f3063930382b598db4b275fe26a5697d0267f3d9d0b1e09a7371be7af6af8edc053d94de486840d3b7e22e79c1897b07dc6f35168e9a92ff07e544a5d7d2850be99e63a0cdb88f9f7daca9873f19701d003781460037628ebe09d771136cbc77a4c822d7b1b19d99d6507941d55a113aa60fe41541ee377445e9b233232d000000000000000000000000000000000000000000000000000000000cfd521400b0835175527d7a49000000000000000000000000000000000000000000000000000000008c55f71cf4d538093c313f44dc03719044bd4e227a18cf18d93cdc7ea20974ccc70f1037d23528dd50cad2894129ef893a62a96c7e83143288055ffca70277f7519deed5f0d925ea761a7be719c8eda1d35d4ca46a01e8a511fab67e180058e8ecf9f97a5b14972521c6e14ccef9b784a264b57dce5d3321ca4c5f417dc90559e3aea31a34c5e01261e9235614d8bf640d560586495ec6a5e3560e08373234717d44b14d1d17a7435400a9d82d26bbac519dd097e68fd1e62b1c82387c029396758950607cd43ccc0d67bf9752b99dfa87689942fc250399285818be8162ff120f7d410c6a01822f131c00e1b08f3a75d4bb0d3375ea78bed5eae296a20a72a56e1c1ab71857c85cd1c212492883e8f34959209c155cc9791711277fd392ba2d790dd766e3cb669cf6886aa2da75dae2c24edbc8bf0701bd208e5f8cda68901dd3d6801515f0af101b3005c935850606d014380a0927122442baaaa7021db4a1c7dd6e791c1b085001fb016228e037768c0f08d25b77b7143795abb8e80be5d3d3d12aa29d02456d291120ee9defe74c0a4738ace82b7e9bc3c37a5f4f7124b8e39775b0b83b6e47e623e387133ca355f52db30ad68a25f5f12d8eb5df9caf523c2aca59ad02cae6cd49e6c7823780c14ae56ef23c6c51c8aaa060f60adc3941e97088604f7af91101796ab38bd6bb481c8a4ca38c1f987355c2636591a8a295551b5c31b12fa682cd38ac13f5c04d67b61ec26100e53e2567ddb4b4ddd26189980a776d325d2b16c36ec5998af267823747eedf445492a6e3649f2c06ba0f270d9623f94538510ac54a0bd110be46788222357d6c0194dd75460b11e3b218a0160f4ba445c5649bea0bd65c6a85cee24937e4982167642ba2caf30aa92475a55bb8715957e1a986153569a5473aed2dd9a4d013374bf2bbe64a9cf003507abe599310d8a39a9423c89f043123462fb254c4a0d42fdca3ec712cfd966f948bcf1a7e49d8f46d66a88fa5e50f70960e456b077f88f2ee011f7c85c83dca4bc31a11d35736f2d07f6f3c4d6ff9acdc68cdc95a7f1ab69c40e8a798c780edf27fe7e1cad06c2c7f6e4bc5ad9b4cbdb47da45419b63a76ed4f107d7cc95956e6ae0633677a7b439877d5245635f4e0632d5eaaea1738262a98a5324cddc18d1b65d6a7b3d000c7c2ae907d2bd74090612024bc0a5a57b72252a196f1e77a32cc0b0cb27279534b5b90dc7b9bd3b70931a46c0aeb316ade6ad82a7cc88a91ddb56591e92e94976a261064b32722bb16f74f0e335fed3bdad50bffb94275fbe5966d5ed5025ee640cd549539b9a46d5e554dc99c994cb98f887533595ed95f40fbb7885254b2d27fe97c6756c34640c1a25725b3db799a270b0045c4545af52ecf5e5be50cb5fa8e611da245726e64a767b6a81a9da3073187e3c8c26d4081643d8e6568d5417fc2046ff8ac317d805c610b3137f08591aeae5452fc2a6cadd9c7cefb95901786fdd69dfb8a2fa9df5dade44c91bbda7d9dc60652ee8d9ccf611f72bfe2bf1a63fb1ec1105f3ac821f9100f9f26c1eba6260479648d261eda942020af70e5ccdd0187a3a71258e3ae599d5f2412f9d79f42eff7686a0ac6ce1ec5db43e83a1a3b37c13903470f88657e50bbfca4b789d2af610bb6f953b0947e1309581b4cdc80ad4b315411ada29248669d344b51b33f01749850172ef4fa38476666af61893b5635beb8e620dfd6bbf1b6c8d311f2e5a5b1691e2b72890aea7c7855338182d6c6e602abd54426f1f981babae8d5d08feb9422399cb2b451d364845f992ac3d69838f399b97d544346d98fe72f7f08328d38e854af402ec81e91c561bd062f5d21282a23110e47bd3af73a5237a750e722411e20ccbdc263c7a0bf39e9104592dfec629ae55852ee0bbfa739afadf79adb1a6e9bcdaeb5a5d8be5816ec6b2af6b1bf69cd5a74a8e203de40f44203a47680d8b8818393a749134ecb3cb9be883f13e7eaa81b1e949c16edd8d0bf53a8cac6ad7516acaa5f27d5e6a43587da16688e25c202673106c3b960b237c1c78ce7b4b98213333b77914dab2c174dc5856b7aa6ee1d42b06dcca012116b0c8e13d652e2ad030d6f1cec0fd6926b96aed81e96ceb43bed04611dc88279807ba111abf164c81273eb8546d27d3cec9844e652c791b76219c1ae5175e34812d2a0ac039289faab7f8388e3c1d0b2cf48c3b0735748427f9b74532406a2b5e2eee87847342b607994d2160a1fc9cd897d439a00f598bfdd10ee96c52eb97f28d11ca7cc2f23cae3663645c5e3d2268fe806cc67f27278dd99b714a5fc9c3f42423ccada1a0c92f55dac82975e5efc4017840074c3c3b2824c44acffc30f61c7e576432f4e318076719837bcc4cbe0ddb2e2cb53781674b04f62fbc4357a1c978b0ed54fc5bbc73981b2b9572bc82bba1c5a6c2527832729919b4e77d160d00fe00d6bec1db1022894af82f77e8dbd1c2cf744e6fdaaba9c4e4475e1cbf633861f800b4e2731cd08c8c9810ab2f205e7e4897b090431a40ffc246b9feb4c3db30277f3a37f4282b1038f8f1cb6e84755b59d9bacb22e649a56c96166a0cbd72698e7e2f2348a11e88d77c9a6c0b99e8e8ca7fb31e5fbcadb641b98dfa7ad9032fb85351549c4219355eb112ad37a40041e3cb52f83f9330edbe03a423c083f510af680425a0c9dcdf93ae6753a33b5446f7f1ff028a36c06a0e2b0310d45c8949810f77d356a67cb0676baa54f7b7973ca5f96926e81e7d6504cddbccff719d6ce3e6050264c25bc3d78bebd1dd9ba5958202cdf6f0953469357a19b1ac4e371dafcc0b6b60ba993ca7fbf8b85a342bbba015307be43c0766bed0fe5b2a24f38ef53ebdfae738a3f9b049a1226c1bc2fdfc45a9a48b7a5596e9d17d315df626c0e7f702f6f391033f2e2081fb4d7f30c5fe8e9d5d41b33661a6bdd9bb13ab0c953391e9552d638b38b9cab98b53ffda2ebcf648a4f8f82dfa81f8243e501320d5c3f5216ecacad8837ba6b23e1db21c8bb9dca41c51a93a29d05a5692bde298e8430996d4ef89239ea526a9395d38309ded67c6f1692757584ebdff6116977e82bdf69698aec3b7de080af9baae11e95eb6a8af80cbb587b8d05401b71c09e2fd94d0ebd26d87de8430bbbe011cfd24c632dee2428e13740785b2f628d5d2edf88b893e36886ac56abfcdbd0dba50bea6f41260c0ed55bc62153a28b33732140c7c9bae7fe5714e0137c1f7819bdbc918b9fa8db7094ab68a26c7fa302c66d9076948c9de16fec03f1560d217bfa08d977bd7c920782a1beeb143313",
+ "spend_index": [
+ 0,
+ 1,
+ 1946888704,
+ 4294967295
+ ],
+ "result": [
+ "a968e612c0874ba3edecb15319b9c5655f1bab0396f581c8c6d036a681c44ec7",
+ "f8aad49ec5c23f6887ff71fae9c60b1fde351d9acba75e0dbb12929d20d2eec8",
+ "a2127631fe7b2c06edfe99ea1573ed54d73ecd214117dca3abd554e2745cbb8d",
+ "ecbe851e616c023747a2cff919fddc58d58d72cfcfd4073e89ed4916990fa69d"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 4,
+ "Witness": false,
+ "Version": 466173704,
+ "scriptSigs": false
+ },
+ "hex_tx": "083fc91b093e6908ac000000000000000000000000000000000000000000000000000000009dc406fc00bd1ed399a0e5564500000000000000000000000000000000000000000000000000000000f9025e3a00b51c5ebd1689e28c00000000000000000000000000000000000000000000000000000000687d327d00502897bc2442a3640000000000000000000000000000000000000000000000000000000020b3964a00cbf69cf982a67d4b000000000000000000000000000000000000000000000000000000003f37248100491e232e0b787ae100000000000000000000000000000000000000000000000000000000a697b480009ec707e1f6ddf5d50000000000000000000000000000000000000000000000000000000017a68c6a0015eaf38cb5920fec00000000000000000000000000000000000000000000000000000000274717c900b98d1d47f3ae766000000000000000000000000000000000000000000000000000000000351dc86700c92fdba504053204d7588ee516c8d7f27d7ada3183ab69b437bc1c247fe38b45960f2b79020616dff306e6d97a49ff6e26d50b2e03ea2d7d9e6fe6c1e39c3f481e3d205a48ad844ed0cfbbffcb6df49c399851be6b4c6fb2f78dae553159e76836efc3fcb3c0c0ee1a1c647e6c54adc34e5b85d18c84912ba431746d453480f1354a1e1466e25662a38c204521e8e5d9a56592ee2360be0d81d16b13988cf3cf7f6bef2aeb2f9cc875d66e93fddf9c2786064ed48cc60a572e5843c5da56ba190171bcc794a88dc36e0a8b9e69bbe31ef43b43aafde09b6a601986e0a871c83d02a483f8e2be208876186e745102161268f69e88df59884922690b08ebe8cdfb5984d79a8e0e7deb99599045d139bae8ed217161f0cc4c30cf5a26d5d2a75f5c3fa16b70cc9cce715d7e0c5a3980ca5f32696c4b6d2db4f5b78304c5449e0baa041b7719231ab9fef77c1829e52c6fcd227eda54e66babe849fc057aaf9dc406e9acd8842fdd1c25844970802d0d75e29bd0bc11dd9be6c1801b7771c888019845f32e83316cb172d211fd3a09d70810899f973c23ce067fde902eb00b84a7749e5d95a54294c3b729b574ce63356bc8882a71a728f7667beb7691f7f09f3683bd5033ead48116680c92208ffe9e3cf6e1893c628206a7eb58642def9e072ce1a557b15dd86960752f9c9573a1375cb16875556f8f43565493a334b5802f526b601e6bfbbff74d179060b879db6b90ba3d6a2bbca1aeabc85ded93a792ce3e3ae4ea8b6fc745c263b3a12e4c3caf135ea2a9c77587d72557132fc222343d6c4b1711f442463da69e9fde09050a77dbb6410a5e004ab8c8688a5832921c0bf10a6d4a186cc3dcd09c65d0c9a20fa81d3c364252a1457176ecfdae27dcb1dcc713c89ae4407c4501ee133b0bdb910ebb21a589b604e975e003f211d368e77e776025c8765db287e9d6d43dc622013f04712c29289d88973485d7f3188d86ba86326ff11dc11f2471646c883cdd4d84583f0b11b90603979bc4fae082776b51b0e4078d85e9cd8956bdc47352904da4dc55ce41a51e97b24f130f454b5be20099e8d2c7a10d5e98b568c4740ba129127e991c673507864109715733683ae996585f6bf3d8430ad85eddf50326f687b6d852274f8d7296f40812761f1c89ca8b38008457d0c794043c6bb6b8882f27",
+ "spend_index": [
+ 0,
+ 1,
+ 514404503,
+ 4294967295
+ ],
+ "result": [
+ "2a5a5d8d2af0c04eeaf2d9e142ba09054cda8a241fe9528e36760fa8fc98ef83",
+ "dea1e91a4bdfc44486a6de284882c31ad06af8eec2f504297d418d97d21a2a71",
+ "601e9890eb3c45ce8b96634ad59aec943207e81da307268193391049bfa7e1e8",
+ "ada6d4157e399a0b9eb1572320ee47533c95432e06ab41bd074c029d40fff18e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 10,
+ "Witness": false,
+ "Version": 233800700,
+ "scriptSigs": true
+ },
+ "hex_tx": "fc83ef0d04b7e52aaf000000000000000000000000000000000000000000000000000000004203eef760c2d9d5d95108bf9500964227dd7f892fdbe8f89de24ae5f582cb1b62e5a4c8e22e02e339634d17b7ee8edaad546eff10f9e4c2ec94adcace4be3429c3e23e5671aa48ab5219492079b5513ab33b5fb9c9983e86dc0a158f588e6fb5a001fa02f9d460ae28a1ba3210000000000000000000000000000000000000000000000000000000019a9fee7fd5801730248089cf34c385a872f5a1d7f3d7dfe9d63fb2ecf32996f18a2adb3d5a9788f1c1a870c52c0b15425951b365092dd6e471503cae974572c586e945120e380a7c9760ed66fa5ae3863b156e435cc73c5ff29c515640ea530fd4f5bd11ad91c8b69d66372f6328d67a1fbba2f643d80d289a01d55500a45f5fd60dee6febe6964b2e716693ce33f1e4661ab450fbdfc17d418d774299f7a9f6378983f3fdd525e873b2fa8a1776b7afbcd326f80e0e22b3805d7d2799fca6c95ff1a7c53df48f4d1108f4986b1e9f1306869f0f026bbf3b2c859e3d966641ea4e0a49bf2bfc05e9ad33b15e053c1ac151cb28f5138664d91581e55c9fc4c17b3851928b34e0eaa2b05c4a9cac136e02abd7ab514ccb474c89fb6789f809a2529be7ea9e500b38f50d668993113c57d60623182c3a2081ad6e359a415f865f5a65df2085ba8c8ec6c7a7297915372b3072eaf844d5a29ceceef72fe73e4cc82d3536078b4beda000000000000000000000000000000000000000000000000000000004efd6740fd4a01cdd04b07fc9793e79911a0e4fe2fc5ac2166d7a857124945025cdbb8ec5b0986c2258e1c28fc414c819f702d74d873595dcc2910dcf57fc7b27363776da98e60fb085196bbd9f67e2fc0c70cdef61aee0156d38143d57987d8bb2ced0934c8f6b070215eab36432c4cd05adee3c3c0e5cbb2eb90c50b7c6b277f995e22831484d0fb4a8497d86dabdc6cd7682c55f422e3958de0c0b64ab58c77c27efc5b0c4cbe1554f002586de4d3e35b21dfb02fb39058967579d7e780e19d591c73ab0a48b2e0d6b95f708a4b8857ea4a39fdeef37ac7bdde08642c5dbbc5cea1dc767a576b33b45c844cde2f55a064da242367bebc319117c43bc962e273babf68c98d14cbb4d512b7efdb6128a58c44c7114a9600acb792a129bb568d70ccf4ff3711e16bcd86e8b009011ca257bafa003c6c89ace435785a3243e3860cf626baab93bad428b686573b3b1732563a83701aa598868c0000000000000000000000000000000000000000000000000000000032317a0bfde401d7631ff85de0d890f36d4b7a1da07fa83d05354c9d44695b04e1732027e732c1998957a43049603ec3a3998a1c3764490a6115f53f6f001bf281ba504d8a4c826d17a1686ca2cfe7a488fdd8b85b5bafa48a932c5f11dfe03293ca59c47f742251ba60c5a44b8ee2f15e9b38121e4d90c8def01d1ceaa877e21e1547085212ab226af086eed854528618d0e19e6924d5e8970b5f7bf178e94c4cb63208d0c316946c56bb46b1ebe8f23f61bde981d661ede6c7fd5fa27f948baa7b279353035570c993920091cf6524d110d44dc94bda9caf2483d72ef3f570ce9bf39c65d605462c602061e4abede479083e0eb5aefef32ce7f5e9b83da0a11523a2a20908e482598ae22874b29fb2d4a17296f3c924a42d84893fcf2d626e949377d001aa2f0020e686ab764aa6589b303a87923e3c166db609a440bdc4eb5c762c596128e9cfde3ac55161236a001a9e4b583e8f3bf3d5675de869f721acb9f9a80741b1d28875323658ffbc2c14258c790af3c9c58f6e1d229200fd3bbd8cc0ed54270bd792ef797a08aa69e132bf2d3aa809614b6e1c086a812e84250c58fdc5e9120a1d780338716ba27ec941ea97c5d0b3fcfe030ed4385a2e070806dbfff1c32d8102c8feb9d65fdb23bb81cb1e5285b2ce322971d1e6d86bfbaeb95fb29a22e25475769276f6edd89aca0af57943925ef22541c86c9ebb6ebbb38ac2140948c3ce50c34a54d14843467a7d07b70cdec88ede17fd2fb146d65c9ae8cea0453850672616803e4bf80bd092199b4202f86b14a2a976dade99795b977d409897e0ca406427d37a45500c41208c08c4194587b5dc9f90e542e78c29eb4f6f8c283f7233685dc3a34394c01e8005b7b02c09b852066741347b42bc9a900ad970e4487b63c7710c7569025cb4d025a7327b00a926f02be4e4c30198656c510cd5219908f7bb6e2d84a33134fc66c7de2e5dc722b73e39480cfb3069ababe48461760b80ce298622c8477aa3c3d338fab24a3848594c14271ea483347a1afe30359b3c9ac1253dde5fa7012ebe3d169e04c85cae2dff4636628f4087e4e2f96f1dab62e7b0555a63d6c25e50c2d3c045865bdf76b1e7f730f3222d3ed3e50742d6180e2d73cfdfa8bcb7ed37336a4826e84cabfb61316e454255757dff3e4c35533b7f8abbb555c2728ab5edbc5472e362aef4920c0899271d1795e1490bc621e71c671301c44961e6eedcd5400a19122020e9093022cc01095419de6583c49de37d7fe720ab61d5b3f678e29419df8d2a13739e5e26428520c8a48ef7347a4ee8e49637a82ca3cc8f885c32303aed568d82849a8559e96e158b32bc6c2d74b0c66c73fba609684e3d01c5e1a161e9249bd9239d57e84ce27fb766b9787ec353d84039a7ff4040e8975c57572d6d382ba65ff6cc6c6432f1f924efdf63ae2903f959daced0af629f8c80ee4d61707eb4b3c030de99b6869c01fbb1e07bf7a5321b352f99d922eaac5cacddc0b789d245eef8eb7bf938368df405c558f7ac01fb01a78b72cd7cbf02bc85d60edf5769e1b653b81e69133499b915d0bc442da6ab8c1f8778148d9cf2da1ec862df77f2250aa707750bb606acad444d1173ef1eaf6a82f892c7026e0c0ea1a0d18f449c6cb6255b95a11ecddafe4ab15cd483399baf1150dc79b5f294e6eb8253fcebb293d21de6adccbd4950f8e6f12f3aca441efca113a7c59c1badbc8abecede2360edd1acc2fe2b2b862dc48ea4535e42f9fa64d1b3f27282d0b6815cb7e3cdb12d032bf562b039c499ef735f65dd82b58f8aa65007dcae541db4ddcc50f935b8f24eedfa5b208d13000ef9c6725a7f85c75cfb9a1d646b675f4bb171b7f446a24498ccd0dd2656dacc9f72e330c8e697b15d5c88c6effe101a8b7ec63352b86084f51c94f4b3dc4f58292e9ed61059e8bff5c8d3533627808edfd6a16f07436f131007b81b69024a78dee9b3adfbe56a016cad6e93829e205e7fe949a7cd8ec0a84f0d4f6482302b82f03592279d1900b31ec56908ebe11442eff5c4f6a2986910273898f433e2856843a5598126576166aa0edd4e38a5d074dd2d039e349cb4b17a498ddac2da07248c24bec883ff17e9988ee69556425ef25537d06b7c7360e983ca381eb6d55328a2ea969875d5fad6c2bd2593d4e9ec42a51fc4ef43c818702c82d7af73a492dbf992760d2fffde226ae9a65f14019c6d451ea62adad3e8e1db773a901ecc1fcb8c376c0b899dfe802315228ad19dd6749ea0d1b57bcd7662616ba9b99e822225bbdaf0d8a501afb3151c9dad127d1b6b474e1b4b4c0a967e067905518603124dab7b59db38d8a3876e24ab5bdb987b575e9a986652c1c7c71b684359a84a48332479706fa34582d1e5388763ac1e5a9e9962797083827a545cd82a9ad1a4f01436825ba24c198e88c1c3ecf7861919908f29d0cf0989af3d11d5c42122edffc91234adbb830ec89b4a5db9df532fb94d768ff597b3bbecc5bd78a709617e6ed71a26784894d751d1232a851e84b5dc943916e4733a303386d669f6b3f57934044aa5cafefc3a36f0fbf360653eb2fd5bb600da9c5f06947acfc48b98cc79053d3708436dbf47b5f3dc77be78230387c81e41095762a9cc3c53ea44c3a49516886dfb8a41050e4be03b31385cf4b51af20e8083edeb6092b2969a8a9e974fd14c93d025c77a1caaec8562a1bd1bb44dbf21286da4e8c97a93f575ce407d0a268a31c52e7f6d98934195c827fd4c91d798a2f50ef12b7b6ac88c01f752c889e795921bf829b38d1607ce1a84e978f5f4d39ace0ee956dfe86f6cacd46ddad231d4cdd81d8cc097f001de7008605950f862a888f32bde2bea7adb920ab999fa927b04e8d592efcdc11ec62e3a7a7f99ba26695a1a2e8f794b9fd5e21540d1e3ec03cd8efd4d5337caee3a71d12d28d2bd4e791cb7ac7fa84bb211ca999d991f47b2a2db39f614333f74ec0183d42be2b31131c5ae835f2920968548e2834d88f58e013687c2ec4bf5ddf0a1ca1d8ef2f4073ed281aacde9e16ce649b793bd0f9eaec438abd3e7f7c935c8a44d220ce46cd5ddc6d8af38d400c9431fa5028e80fae7e962361082922cdfb2b276f88fe61783e1b9da26edfc65a3839483186b8725f78f515cb3ddd86db8b79983aadc5e9e8ab689c240431cf1e9453298c66964ba0e32e12754dc109e4c2fc8dccabba837a4b6fd00182a17e615f9eaee345faf7a99d981b4ad04b22e62bd5a5268cc1ab37ad1b56402defd4d13cd65c33c7cfe0c9382cfa22504cd3d789da2f45ac68037af47954d5fdeb33983b7c14ead5dd99d6764da22c7f22e119998b58593f4c15d73acb636b27d56992845c868d1b46402c1983083d6278ff19f8503383ab0cd7071da63a4851020f74efae494f346d7acc626b4e097997661d24ebdddb17176b723f3c311486f86bf9e67ff524837be585a48d009bccfedd923255b44e2c66305d7b0db3113b830105d4231cd357dbbc3dfae5eced32e95cbf95a85e967214285eb1e4175b51d92348fa5767b053611bcfa84fdacbff4d6206e12c2b361749aa5c41944b2946d90c02f3cf463474c365ca4eea67f342e08b84240db736f08807b11ccd4d76670a60337932ef31bd5d28fc711332d46b983",
+ "spend_index": [
+ 0,
+ 1,
+ 1012000868,
+ 4294967295
+ ],
+ "result": [
+ "fdc72b5aabe68203dd0dbaf37a1ff78c3362791bf9527ba8de717f493e233baa",
+ "1c7402a155fb9201e164dece687fde25a6b03f39133cf72c1b6c3a912f357baa",
+ "42c0622a740320dff800c460722a13359a020425d4a7f1ffc0f6675026b22334",
+ "ff35ef313d52de732a2678aff944f787a5d3f018cdb12115c19fb28578da9d2d"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 8,
+ "Witness": false,
+ "Version": 1064018199,
+ "scriptSigs": false
+ },
+ "hex_tx": "17a16b3f0ab40e831d0000000000000000000000000000000000000000000000000000000044bdb289008d1755433928a3a400000000000000000000000000000000000000000000000000000000d30c788a00cddbfaf7cdef7b6800000000000000000000000000000000000000000000000000000000460e6b8600291cc340112862b900000000000000000000000000000000000000000000000000000000fa10e4d900b9ce1c6bd05fa09d00000000000000000000000000000000000000000000000000000000dbeabe9200461f00e8967ebf7c00000000000000000000000000000000000000000000000000000000f4295fce0006df8f31488df2b500000000000000000000000000000000000000000000000000000000f0c4c7ae005cfca7cc9a71195a0000000000000000000000000000000000000000000000000000000048f9d0ba0035b65c06a0712f9b00000000000000000000000000000000000000000000000000000000cf7dff6500d925d393cd2036cc000000000000000000000000000000000000000000000000000000001e389110003de7c87f08011311cd86f0277ac857453c60d9dd63b5e7f0ae592aeef838bfed1bef937defd8b275adc462e498ed93153cae785c7c015be5a7f09f209e842132640e471f23547ad76eb5c6fa4e506f119f9929ed3427358d90d88c8e92ed0afd8cb9297c705bfc0fb7191d6160819f3ecd86833eaa4325a8db1cbf33fd36bc8ff922be21c123850c5e521b00203e69064a4634a5b448d012ad88c37fd30312c75c75bb6f8072ad9a6fa2c490d44a09e083c5c33ba352ae92a7f25fd9de3954fb267875b6121cdb5d0f8019387875f6a044bf95994b6c372a5f8824b1c426c84f9e3745c5410180f79cdc820f19470cfde0e6a5d7c4dacdb58ba5c9f8d7ee2fc85db3bf3d580fb0179e0bb7c45b21c29809cf13c21cad38fe27f49593f3b110ceab98da43c4c451258d81cdc998cb157262d3ac3d9f6d6d15a86e6373aab439be2d83961d1fc0cc1e7870f5833b05ae4b1e557399c408adedd0fbf60287efde883f67f64a3c7bd7e24943be1123ba52f55577c140783b1a20f774b5f099cc6b53ee63449e95dfed4f51a281e20f6e7efde38ac79ba32684727d3f7b219044cc17b0517b2622098c6144652e2960880fc84b700c55d4503ad6d4a481a0fcda1fbc1e90123da7ac4a0430f349ff5afd4c2ee2ef713b451f701b80f77b98d61dc697237612f0982770c49d69682e1eb009ea26ea561d47f51321e346d53e06da65aeda464ee98d27a769bc92afe93d49892f3e7abea82b459b7339eab64a7beb08c44854c309a768d896ecb0e797551dbc6d21c70b488017b9826fa06e681d0e04d67f85ceed3fc406b252b5f74896b25ab6fc67224a6e9768155beac50d97b66f13d4cb47a45fea4dc299f5d0282a2080fabcb8cdef66f4a10767ddd274d63cda14c8db3ad697bd2a43590bdae80fd469518a61abbc73450be68855ab442f2a2b15690f682bf7b1c8489f34cafbf7be712b8b05b495eb1d1c0f6b73ac2e954b639e9334fdac360a7987f4ea1dce69b234f22398f3f0caa9dc7c831348aa5641c8ce7133e2648d0a3b52c03599454d01fc58140dc536809a883f63293390faf3a4587f72202866e0f4e8acf47f4bc4c6eb424a526a9adcd36b4541171209a9f69f30274f2ca27cc7494719dab7070ab4df23c3175783a18013b9d69c811edacb2f4eab5e1f118cff0bb2f76658dca537725b3bc8f240a320e32d496811ad9a68e3224fb58d7d3e4135045aeea58d49a6bcc6b95676a09459242da680c4caf017b7d2415708a141d64253f50234207205712c117c67b8221d2aeadaa3a62104de2b31632b82cc1decb5e69e16c5c942b57cbb999c354eefb6f09fbccd59ea85ebf83d48eb06d5ec7ef4e07a80c976f953703d4a57ae1e8dd20ea6dad831d21ea5add18aa169f66a886b200b252ca5991d3d25c56d17b6f1558c3450d6e3e758843a2976156813d4d896a80bd13187e20047108a60b8e349c3b649d51e2dc0b9309f8ddc57c8fb590c74e1ecff4ef21b8b8878c155672b1884a07fcf96fa4a2818156b6d006816221bdd869ad734942935b10dbc6c5445f6b1948f914ffb0a55861a993bee37f615f80654d5514d1540ea30918fb1ede5f37cfb3a38201f5cefb3082e3fc80d99004077da7a9bd7a4ae5f2bafafcde71ce910df384cb6b6013ad9ea302adbef6147e0f380b71274b33e76016276ebd61df07c1c296cc71bcd425d3286beeb0bbc2dfe5c1031a0e5700bd29016a3303a048b012c4d8a1a11fb3bec23518699c7d47858164af9bb581fd3a0360e5ad16dc8cddabd6aa5e7ccd0260ff50cf04646222b08c853ff8fd4582e83918d665cae48a924f947d02562da8a00f2f19b1da5c1c6699b6c92ed7615e81357a12b1b66f290c4b82001916fe4b4a53a1308803357258c4a4c4e3cd8a9125a87f3acd4cda0c67b99851daff19108f1ee8939e981c6bf0f8639d8e1a51645405e78b8d07d4396a4914e8b2f0715520559bd74911a8f16cc77d46b17e82b3d6e29ab4a87bc9c0b71ed69609e745dab8a6b851e5a183c16c301d631f02bb44d2ddb08c182611b2b338bc38c09e4986d9a69fb08010810c82d5ccb737cb4fe8177a00930c4eaed5d0e937129b7908064bcb5abe64333eed5ed5d2891005d58de559d2e8626768a84234b296f2a5a3fd8c8abed1983c1b8c184a98ea23f7a5729beb24d1410090755afff465d78e17f542e0fc19a36344bad169ee18e7cb200ed08f1abed035b1284af52fe1f25350af3fc0427a7b266ac5e58f83d1570016f74db68413e12571fac80adb5f50283066a509bf27fc7ee459184a95c6441bc005bf320deed8946251a8a82683278c14798ff3d9b2521187e104adb1d520ae90b38f8399e5e",
+ "spend_index": [
+ 0,
+ 1,
+ 3173180552,
+ 4294967295
+ ],
+ "result": [
+ "3771f95a8979cebe0d1f1b6eec2f54226d2a432ad54d975bd71befb47810a34c",
+ "5bf8f06db72fc5eb93e55cf6725d504aac10a24e5cd3dc9370654758e9210756",
+ "19462d64e577214d14f1550e312db8f57feabc5fdc850d51585e7405b03d3692",
+ "e6e719ed457021afc2de1271af2a1be2461627d047d0948e2f7f47d694e92999"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 6,
+ "Witness": false,
+ "Version": 563167293,
+ "scriptSigs": true
+ },
+ "hex_tx": "3d40912104388256aa0000000000000000000000000000000000000000000000000000000065971d1afd0901d31e2e46c0a53e7534c44895bfb8ccbd34eda968f1efec0770c1fc4b0abdfa0c79d6f7d74c05842a6061826a1926c5525ba7f89da09f8fdda8466582b81f203e39ca696f1ac39008427ed21d407b95714ac65c1abe7cfc6903916c42a0a0e8274baa6084a8e317d4df7ce2443a85e5a13722547021eda174b0b3142dcc50fd489bc16fd186334f893ffb16d1088bbb80248afe97202d455f9bb4fd7409ee677f9a5506c2217392b62a2b419099dfdea1b0abb6c9c179d6698ab6ee3f233958b511c220bbbd70c51c2800f2e7ac473ba9cfa5c91c979e1b619dcfcf4b9fd8b1a4f9742e5cfd90ea357781a68193f1124405faeac1490136644536c6dea31869b12889cdb240434b12d994798581ddc3cd550000000000000000000000000000000000000000000000000000000042c08f8bfd7101d3c5ba9fcf3d95716ba18eecdfb54561471505c26ac9d6c3d72e97f8deed33a5383e7662f8da2f812f802a6931a01368048ed1a518ebb4dbb8c3ae0dde3d00279bbb9edc3199eb94495306d0cf67caedca41958fd89e65c90ba8880cc5351f2e966fd8e6682b9005d99cd193b8fb32f39b0ef689699566da3eff816307574949387abfd7d4da1749fa7afd7145f054c34cfb45c59cc618f947650450111f25fd31bc800233bbda6e7d7cf7577192f0f4d6d7f78c771e6fb1a9e84b3d3e9ab60ce8289515f8a149469ca67d8f2c10cc9968c72b203fbb6cc239d945f5820a21f62ebf419f7c49d3bb79b3d51feed9dc4a3ed93fbe75438a7e282cae27b40fd3a04d4fbe5566349f2e3ba757c4e9bf9e9dbacc2fd6e32bf7f53410714b660965d197c6f091251385a71321f949d2296193eb186aa23587c00ea43cab68a5def1c58cf6bf08e34fe4db6d69cb0a8ca400b2fac82194907d2a09f78796bed876256b74a8c0f253db856de71d10ffaebd7b037dc5b67b2ee0b3434900000000000000000000000000000000000000000000000000000000db0adbddfd91016851b0c4df06980c4e9ebd072d00019865043f6bdf595c8f8dd2f15d78025c7f6d8eb5fdaaff7c3b83e2411f851be671bbd8e3420d367be250c41da4a58ef721db4116381fd725d68bd560c71d146ca59211c2331885c7294ff7c829ff2b00942b2eadf80170854e68be35c5cc921724f68a6ee96c306c68f9b9920c1e68e23901f5e5c170ec871e8132006d762f1a6130ba934ed18f27be027d34761ee5c7686cef5597870d9b652d4711c155d1aaad9bb7cb9d5e0b16eadf6e19af1cd5539efb13a222753da6df0a9860bfe3e42c8dd8f791cee12fd1b3483391afffca1d0d9722975369efccef028480adbfae107df62d18a92e33ce65e68d8d0ac212259755a13409662ed350c6314780348527a3189aeeacf1ef3bf0af72a23e9937fb8945df0514897e131ae1bcbf30113c3d5c657e2c80a3c666e36f730c68ee89c58de8f0ddfff4bce478d4b8bf9d92fa9797f0431d8df0221d6daf47c90e998c0761718a44a4c11f4bd85e6a860c323203391fb78b2002b4efc56fee4380d176df834e935a32bc75c5f74d8e4da1ce671e3fbfce1f3a306469d9b00000000000000000000000000000000000000000000000000000000024ef503159da57602a43f3d2d9001532c98ec774edce6374436d95e3adbcf7c7eb75f17fd05599270f4cc01a0674e1cedd6c19a8bb079bc927c16dbf3c2264b6def9d86f0857d4e23d190ab958fcfd26e518904863dc91085ff0fde8beb21680de4f0602805a85d3620c00c8bfe332e6b2feac297f46400d5780a1a2d46be232f49f4a366db1861bc87400259795faec7db3d6b499b2b3a60d8f637716d21ee5b267e9de47deaaccc913cf7444a111548e4f7ca7bbb9eb58c43395dbc70332fc3affe5fc1031ceff43468411f20bc3981fec2b5f0ba7ac6c269aa004a0952609dccd00b63e7701a4daa60b06452d2bda5a8449eaa5fa9a188643c75a40dd55682912d88c4d61729b578a1a26454f252982490b7199d00a6a0c5b5c48a0852e7c3415b572049683dbb57ba527eb141e5b09b766ecc40fde226055bb0cc8ce43ce3b423332ea000e610239d70d88b76ca43877297f5435bf505940e3d623c242b1e1961489efe107646a8c7e0ce837eb4581dbc7fbd9a56099181ad82b8d8290b9d18154dc34a3806302d9adad751938990aeb2818b20fad15016ace06919a9adcf24e45f37f3e94a8fc209a6c9f07d932bae5d1db804a06b06a004c7db146e9f55b2fdbeae59e6e84f844e15560f376dc956369d15c6c11bd3c720b9eaefc5f5e61950db33fc732b0a1941c9e524715638f2183d49fde432d7f2df082b5ddcd7a4acde97d06d5dbf43b82f2d326c85d81f49b1aa39f3889cec29490433541ab03f0e8e23a04d2affda88df42fe602e40e5064c27af0edc2488e4a7f4623e664dc3730af3776247b975e98868b494f865c482c879dba23861deefe7a0c2a4769072cabf7340aef83a3f1f9ade46bae0f00c0cbaccccfd601e17d9c7bd678582af88020b799c04053181c33093f61fb8927b6e032b0383a61a9d1fbbf585301b0eb8ebbb7ee96606842d866d393eef4b0eb066e47814e277cf1c4e3bd10c608515b15f5501d32badaf9ace6285ee6652fef608bbcccbff61a55b15b2ac6413bc8ef7232cf413326da9ce54e4e4e605d12f025fbc5eb1d6a8694721d18431f3ad5e67fe1aaebd39cd51275b68f4a42bdb6d7c323690c32eda3682e583b7b542c41694cc4a8a0de5272c81c09152de7790ed01e3809ea25807f296db08219773e5ecff9967208f79353dd52b2af31eda542d095c189b843118cbbc5c9e990866aa5aa406c8ac573148557cf384fe950fa9dc3db0314dccd1e9a07ab01088bc32af3010b335f0f2c466710837f9109b13f23f4da88981109b629a66e954025bde287daedc656726f08b5d2c71cca97549555c895d265117203812a7cd687c53056ba25f924a4bd3b0970162b9470f33c5c2912e0f178abd5609bfc898eda5f73d54ec474e4152b205c8cb5db43a63790fad88d76c3f1b28d41ad9b80dde740cde498d4e7fb13d7794c2491f524b186d7265873a016fb6ef7911c1b665b3cdb8f28037ace8e1dd55e50f601231249bc7d663dca77fb711084da39cb57076a3baeea27c67a418c49d1a87853eb20bfb934a71ac66b6e3bc98cf781519bdf8bf1714113edf5cb6108914765202004744a3b0832d37549ee983f4f7e8bf0602f405524a046c80b93f3f4f121310100227d653f48e72cb6ae007fbfec63235432a543bc98f7592210eba0f8f6c80e1757460727660fc7cd9f6339381189bdae7e511f9b3e7b14c46562a2c6553aac2b59d6faa4c4e2e9627c28f42f2f914be9a71f7880e4229be7d259a0047bd33f6276915be97d0d84c1bade71e32a368a0048f405990fcf8362a4576f50d3d387d8d0a3914f91fe80c2534b9dca75eea410643c5dd660a29acb0759b0fa77e7587d65ede0d6aa9993cddfc8b8fc0e30aec481457cb5f412b04f3445b0b275e0ab96a8d590",
+ "spend_index": [
+ 0,
+ 1,
+ 3730060837,
+ 4294967295
+ ],
+ "result": [
+ "24e96b4a4e3f89c2bb481a551862da16c22c5f6c438ad890c0165e3e07d74fe0",
+ "7a8618b8e1b73c23865ab6852d76b972cd89cd6d917d1282c0a158c7078866f6",
+ "6aad6da206cfd5fec432e5a6c3f90fe4696497c1c74d9921be54592795aed984",
+ "969a11f68b297b12bf6a4d26829f9360da3081ba2c1ff5e2c142d1d1c5a180d1"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 7,
+ "Witness": false,
+ "Version": 846211581,
+ "scriptSigs": false
+ },
+ "hex_tx": "fd297032059d8f2e4a000000000000000000000000000000000000000000000000000000006ad4927900724e9113e1539ec400000000000000000000000000000000000000000000000000000000affd749a006c86c97cac51bd0400000000000000000000000000000000000000000000000000000000a95230250073aee47e2c2c13d4000000000000000000000000000000000000000000000000000000000cb58c5600b5a792b6d0ae8af7000000000000000000000000000000000000000000000000000000003fa6d19f00f0f1b7f707e7783686e4dfbd51c8fe857be958399ded2f893d90665a96953c95cb37d0d6ca11d5338967f9ea564774258038ca5132d0157c1b4088a4b6bb4b1bf46d644304ec66c9c6a19081bbbf428aa322c0baaf9f98dcf29a922a2f7ee41187112b587b433975c77d87d88fcc0be07dd76e6f14032e78432e7cec4ed15a77ccf3fd575d1fa216c16c278dfb49cd45cbddc73a8a9833528844e834d7a8c9f44be368c481aea78a6c4a32c950960ffdbf4e14e43d3769bb28b5e9809229561e8c0201dc8e5d27574565e628911aa81221755bb7d470b1c6d0bd185f862bc846ea1cbd42f30cb2599c50c38ab47266dcd373b4233f9fadb5afe00b3ea9d22cf2b4431d0bec7a5686aa8b4bf2a01ae8f8e7b91221f69c9d88237926274dab45b0fb2cfc7245d8cec4b8324c38f7e50f9f93eb5bcebf24d54a2ba10e3c88d64a889d7ef4e0fd4a55fecf3d8eb2dbf582c1275d0f9cc2cc3f1ba6bdbb33fe2e2ce8478614477363b2b5f7229fedafd3ff9d13ffe353cf49f12284d77e8a6943cabbf7ec295976312b7ba26b96c23f6aa4f615760a61e471ceb1690e54b30592fd63e84ad21c71e92fa8d2f9d541f40724c8daed51f21a7eea2568c7b3774e8f6cbe9ae1d65ba0cb826ec9c235c1839bc2fec4ffeeaaceeaa0712046d04214a5456421e99a2eb10b18bef429997085f3fd674610dfc9419551191f003e96125299aa486ce35448d2df6e9aecde943f740cd4fbe2b1503d41a2a1233055f64f1ae44c9a0cd07b3871e72eb80e7e5541ddf87f85713891fc37f27077d383d68815c7a628e05ca92129e856f3e1493b9dd49c4ff0b4ff42d81791064b1093ec7a6704bf7da9aacd5822ad1db5d3691c8ee2b46718fdcb111286f5c273e136ef6db90601c8b349d7c33632ae5537af353a80a359ab89cf1678c05b28a702e374b18f7ae18bd971e8776fecc319986a42a95a39366a5add38c31ab5369b6f9c2c2b9947af297a229c21c5ca69a83283c5964656ee143c575e3b88915fbb3d8350a8f6471ddf2d0d4e26f3a4bb251c679a26a764a68e2de0404569e316d663a04283ffffbcefc3487f2ec84ea96fb0ba8a80f96a48ce4d8d42d1f44e3ca4664afb94cffb0e518f691171fd4bea22c006ede1c9ab558b023474ec51352bdec18b1767c031687dbbb0e9ef59ba9edb00b249a06e20ca17c8543b6394e1e20ed1078bf9df0c1f98a032de907a3fee041093a1b7d1824a97269734cb907806c1d3d45ba44c9770af78c118258ca24e5d36c1e6a39f4496fac8f0ee866ea8a3b513b3ac5fae0444044c02374795293d50663cb7bb01855b82636271803331077738d6983344b4a13b95afce8510a709df3721599fbadba71d8fa1562ca72689e64828c305efa2dd4d57523fe6d46a0443fddf11237a222d0eddef737c2c59f27dc6b1092bad424d493c3c57a5314ce22f11f555b96967442556bc30769a9ff4ed430313f99a8e1a6a31c8a4852731d6be398e9c42dd8537e56aadcf961cf6668a5b123234f53bf6afe930b9d1461a312460b43f713dd7fc9b136c531c94e06f878314e7f0c0ca444a4e911cd6b9f4fd949c27226d7d8e3441e5f15996c437fc7fade96ee41c64ec0f8bfef471e4df5f734c66c00c7c78506bcc1c292968297f13ad096d90d9f2b4c3b26a2c414810dffef179a98415aad4a48bcfd130d8f46d23cff68a04e585a67fb0a38a7b71924a2b74e0f132d7365abe6b8b0426cefeca897d7979405b97ccf843530fafc3204459855c5c1cc655aa630f37c8adeab4711ee9fdafd851aad34c4ca3afe979dba3f2a7b0c38028683683d5021ef8066314c33251e1fa4399b33693b822a9810b73cf87d877575e4a09148c23dd63c34bfaf2c47af6133d0da81f88a8e98b85abcc00106fc3ef5b7321c7a91163c73d108fc7f149de4dee0b608890cedffa091c76ccb5497b6ce70615a12fef85ba29754b8d23a50624c00d11c9a128b19dda89c88f669e46f69dce3471c8c018b224858a563771acb6cd9e01ea94d9846f62807758da50fcb345c8dd486e9a3716633824b8139fa8f28e63ca",
+ "spend_index": [
+ 0,
+ 1,
+ 131671016,
+ 4294967295
+ ],
+ "result": [
+ "426d67aa0b10f1989589c3dd19384a15d02bf6c359eacdab6a5d86b4ccafd4ed",
+ "fe8428c7b9169065fae17bafeed4219d571e91379a51fd8a415db0b875934a26",
+ "788e97595eae8dbc90753d7b2b36f2bb200f359fce4f30691c8990100e0ff215",
+ "c23036b78b162b2dbcc5f598a6ec0f5d17f154101a940f6d503635d2e0c0f39a"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 8,
+ "Outputs": 10,
+ "Witness": false,
+ "Version": -1574382780,
+ "scriptSigs": true
+ },
+ "hex_tx": "44d328a2081b94443300000000000000000000000000000000000000000000000000000000a886751464f9f38e242c62b656610a1f82319272a176345cd2a998a58370215229be9127c7738443708ee88324a59b15e0205aec039f5390c8d78242dcede6748609a6eb7ae09a75936050b1e6ed0733b04aeb4bbf84485b966d192f5eb19b774afa63158934da28bee5be376e5524d3e40000000000000000000000000000000000000000000000000000000097b8e2600011ffa1143fed34b000000000000000000000000000000000000000000000000000000000680196edfd3801442fa9ce30ee6eabb973b35ec0c9841fc00d64cf688b14c4b7817de9b3b32a90f59a8b5c7656de2ac7e9e625eaff5099488fa9451bae856e1d582d8abcebd400b34c8f236306930cb5c02150a39a028dcbff4fb0ab95a58b8911da783b7278f3efb0c799a18075d61bcfdf9eb32420451d8251cd4bd9678993994649f58b3254b45adb9733ab37cb2b3a0c1a008aa4c38c583cfccec7fa8fc4b83fc28ab055f119f0de6f46946b9f5d2a6eee8dfb4a4cd4e031bebc30a8bc8b3308740955ffc939ac41dffa12d385736e75503abb6b3c280e6cc625f5bebeb7bf2ac66ca18c84d3dd12adb02a5537e94827a6e38f49ab0e4874601c098c89d40a59704d192716ccc244592fa4563c9d7db718de830e0e4df313d06257cd34e0ee02f4b3f7a6b60e39eaa35e76c8484c36bf323e3b628e2b66188569d9414c2e1633d23c83f3700000000000000000000000000000000000000000000000000000000037fc715a00c349adb6ecb8c9280000000000000000000000000000000000000000000000000000000088c15f4f009a3ed5e5fd37193c00000000000000000000000000000000000000000000000000000000b4a019c1fd3401ea4bcaa791a17606d3faae9e9a73e56f016fa9ada279cfba50e41b15b08d9d76d494a21b59c99a03ed56a240bbc0deb9ddecda8cb1a54d3b12b3602a60f00fdd69057d7d23e89fd451c3eb1985539665d46818c24612fdd8a524a5307b3fc7f4348c4a422a428200ae9d1b2763e054d14954653d17bfd9e94924c91ac732aab35081b1cd03d68803b10f2b26b805ce5141291f2e836651e49f5d60925e4b61cb54cc7fdb857cea50a0a089a1632cb13a2b07fd16c490150e71b59677f8ac627afbeeacc5072685257458a682a4804e8bbc7b3fc8482ba4ba33cb12b7bc2d54e3bbff7bbb8ac6d7155791520a4ff2754df67521b1905a8af5ea0a779dc7f9d1dd65a6a0cfb4df5fee1829f08e3b125ec2527a923339e3e16b693c1b69b32517b6641505d223b2d738ede86fa5a60258e8ec2fb96eadbf11983890373d00000000000000000000000000000000000000000000000000000000f8283babfdee017b298c98616741fb4b87e68170dfd1dc28eb90035346497219c02896a25e1489ca35e164b1626d28960f88f7d2589f086f3f43fea33ddbe0462cdd5a94f35c2f8d083fa67f4bdc23395ef4f7b46ccdd5299781503240707e0c630529e2f794ca19292ff002dd35271adf84251a94fd399cffc0b99d4e63a904d3c8f5783ed87e2aa2a77648da6ffceb55a2b20e2f2df1f49f5b6930a73c5c2360d01c7ddf1b69a2b800abfb9a8550ecfef567146e5c14477189e87e7d4147afc52cf5daefb5f3771adfb57853e560adaa2f9ad65eef299ec873a32985de4181587bbfecd50f72f335738f7ca54eebeac8e148fe5bf238be288ebb548efd15e06722f5a8236113103619c100e45142c6e0677ded1ee0b3cf47a58735e38b8ad9d2cab7ab46444b529eb93ded2b15f9c0e1e0dafe27fc78f8f298d1972d955596992cb9e04f1471b7e9c8bcdd4c3a6a03891ecedf09ca3cc0d3268275205c3581b3eceb46a0a1d75504b7248b9259b55172865451b506decc4e8167ac83cf1cd60ace255aa7c1cd392b07209a8dfc5ae296c33a631a1ebca89d0a1142f5634505d33365d646a9a02c25946f3c08a1cf1edf7a51bb7cdb212f14b96287a8fd3a32450be5aac788aaa5bddce1954acda404d6cf92b080811feedea53baf9c31724466c8ac66b3f9d066cb128bc9974e94135a2220942e6c8bb05734f8e40a00000000000000000000000000000000000000000000000000000000e939c9f200f34e11770a159c56ae33e4d155c8d9121a9088c37c866f585b375f63d91083287016d5747217a0dcbd3080d36d7405f475a933a7e021381f95837103207c98f7b3b80e33971c6d84b489a51d842bc38d930f1865ae1e9282f1edabd7d8e4a4f3626255380114f3efa6c5fcc031be7d0c82cd04cc952a9817eb7fd36bf5ed76ed16533371e97ccd869c79eb547eb2ef4f62802eabbf560fd4a96a99d93a745077b5549fa3f55b1aa9a9495fc38f113f5bb897ee969dd7853b3d063287eb3e3470e2c87a29fed0fb76a4f97ffa1bcd3bbb2e32a82608c607bb5fbe619f6667c8e84727aa6542b8c89b932991f22592fd0fb95fbcb6985998be7b4a2a2961c9a37dfecf69b63444716cad444d17475b1b1de727f0757ce053f24113725ff4f451fb74e8e2c3e2ec02bf0e1bdfbdb62fa864a0f9986da097f06cc1f2ad0d875a0fe71cb1767e395600a1bab80b9f9b7a827993c6a9e8eb6501b441b6f20fb45e8725df5fba3946024cfeda5e7276438135aea3da7ceb78a7be58e7d9b37d2f36d5a9a8cc31807d74f56d6f8911e255ec2623b1bbe615831cc64695d4d16d8413b778be4baee7019b79ee3404b8d1489657c8c7da55e55c71f99040fb0af185bd9679e4ac1c846983b954b5f3bd83655f281a13dfbe9ce548bde41227633c433af464c98864deef1caf123e1ed85808c001acf0441f8473cd7b97798fcc7add646a350a06ae7c7af6c9a60872371273206d2dc4522d545c92a36969b4f19f91ab3bd87bf754f3a9335875c8777a16d83138f2dc1c8f6823af1e080d7d164eb7369fbc7646cce618f41d8da6eb3b5332e8a9310a152a64e4ece54d6d48fda989f84adc261b307f09e2b981c06e9a7f8a11761f7263bf55c729387ca1fb70bb5aa73e59c8e2614a5b408e48cc3bc346ef3f1ba49b1a7dd630738083c44ad54e08675d6e6f3587b8561fa42877f3e8790e16fe88a54ed69ce6d3599f577bf89c371828dff961250bb585fcdb521a43cbe45eabad3cb17046fb7ab209f17dcd519e22f093d915fcad8b85aee4b774a1895bf6a910dd9e1dc56fd8a075ba89f0aa752bca314a12a9b5dd8885b8dce3d4cad86ca14044a926648af953b273b9e1fa9b85f0795eb4cacba1231c9ebfde1fe89064adcbba3dfb294696ac1c964ea008758dbad14768b6d582307354afac871599b075e457c8e80f67ec373c1dd2ee83a44f42eae8e52c7b2cc37fdd4779bf8d4e859e637dd1dc42a9418db9255d19a494d8afbb481aaccd8b424afccb4701ae74384db73f9bd595924abd0a090cd2360563dee0adddc312249540f7843dcc89f6d210c3a1ea9d5d4ee111c04a01bcd96d232078a7535d62a517302a3a6c3b792ebd84cc2defa7649c9118a37eb69273ea11a3f180525aa5f035f9133f616e8f70c49baeaec8ce5aeb613d58ed8a9894e42b3f87b00f386035229a16a0e90b479dfbd69123b3575b9976d96f04279cb272272d37bd67c8336ed74ac5f0abd2cf9dc437311315b1264936454dd1aa60dc5f3a00d91b75124f90962835e8fb88a19f4089fbb593579024d0c6530ce0a3b07c0367fdf9ebabb228d66a27b6e28dd091690045200b230b7ae83b5941140cb56db28f5fd7a97cd4c34720543a093ce486794bd8ac80608e0c18eb7b6a7535e1e6bd601cd4bc258519b8c30b6c2fd70cecdf105e395e79961ed8fd39d2ecae4e10c1fab97fb8c471ffea6e5cf4006a0bae56266261061d692fbe2c3bc19a4ff3dfc51019f6cd4bf167eb79e182c6a8e3fca40e22b8b02ec8ea0ac6ad75e9db6f90da6de1e2f4dd334a46a0d71e7c5cff5bc7618eda63792330c5ce4a5bb7aa2896400936f29ebac089d4644b98d60f68c7684af6f9605deab295db64956af1e005ca3199a5a8041d15636315a8811a18f3095fc95e4a95c61584bcd466ad77ae40f2eb0896435cbc91eb5ddc739f0d15ada9d0b46b066b55de82a9c3188c5ad66933f86178fb512c18c2805b8721a0c6dbf2e79854d076dde7f54430078cae232fac81c24648a23ce29358628a76cf26d58ed796f0f3c7d0cc5a67768521e20b881633103ec45c52c820d91b6211266ef7a0921c4dc51568e9f836d458ddbd025fff6b52445ff707e8af0e02c3771411a63c95d901efa7a4fd10fc07811f517e52ecab1b1680106eb7c3df88e2bb6d22a4f69eef0277cc509130587c807f682645f16400ced744f1bcb8235f5b14f5ec6d355dcb934766c1bf20a380262734deb57cfaa6993526923c0b63593d273a9713b79bda14792b8952908279eedc11a6d3068242635af8655789a74a9ea299af963457e671ef6accf1754af7cd5d0b1ffb271911820b75e3ec2f5675ff743d113a465d314a7cde8c6bc80e731e427090252e91a7f105b4d1958e7971aaa7760730d01d22ecb0a9b33a14e7e508452259e8ac97ced7cf5b604ee116da49b27021fab72dcf595fee200311318193061756315d4f3073c7ff7c03494241367e72d753ee5cee93066da766b883848c58327eed8ee3a43faa1d48484228f648966d6b29beba5a6357a1e7b3f90f690d0ec98c1f486501abb10ae7f6ce9502d587f161b811b5ba44aa33f2f2bc59f7cbbedb53a9ce3bfd911f2dd7e59f0b0ad885044a6e3c15939a853b3f82b72d1f542599960ccb04c04e6a40835d58c82e3860d477c5e33ed3eef6d984a73d38537fd5d890caec9c0e540850e3bbdb53221d387278c19a4270e58f7b8eac4f41bd3b85566a879bcb6598e927f0dba5b8f33db8e24a83971be4ac8b5b1d3006be3c997948ad83ca681eae944fe1fd7e98d23a15f1de64f7d747a812aaf50a6fea45cc1757a4bfecd0e8bd2ad71773a773e098928bb258078c30601a1f0c6cba095a96d77ad50a5e89554498c532948782527bdcd8538c114f98ae43ea365915de277fab9eb401e4c9a157ad0b015e03c32428abb2b18011037edfd64b",
+ "spend_index": [
+ 0,
+ 1,
+ 206680780,
+ 4294967295
+ ],
+ "result": [
+ "58341bcadf24913226c239c3f98212df4441eac171767ecb3bd9c10c3173b869",
+ "8503f915c572b7a17e89e3016c2b332b4d4b695320dedb09ff14c68cb9963bab",
+ "fb7524262bcbf4340dd6c30b26e19ff8cec3e48bb4c0b33ed059c4a82d2a730b",
+ "722b46c18def320f4abefe4537001b871c159c85cfccfec43ddfe59551edd7cb"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 3,
+ "Outputs": 3,
+ "Witness": false,
+ "Version": -1982256653,
+ "scriptSigs": false
+ },
+ "hex_tx": "f329d98903633f5c0000000000000000000000000000000000000000000000000000000000eb79ff340060c265897579fec400000000000000000000000000000000000000000000000000000000d036cca500b6a3d11d12d5c9fa000000000000000000000000000000000000000000000000000000002711f92d0087209da1036b4a21a0b2cfe547c8c8ffabb4a756d191e0d24c42a9dbefe8559ae663ae6cbf2580e602b0536e96921deb78278aeb52bb18128f75397415ec434f7524be2ba88ec85137ab7413f06ff04256b08069f4aae1919d9d1894deafb4fc8b302497d6995386eebacb2c3f14fffac585449eca6a9e50b40312debaec965cd9df71ecbc1bbc15a140ef8bca7649ab68f9d79db5fc980730a23a3ea5530a4dfe867e7c767c6aac1056e69436155395295a8e00f1d9a4be8bfa11726f57c57c21db2208bd30a33f773980db53c93f55586dcfa9a42bbf55896cc9b93b15c8cbe3334c332e38af044b0e8ef21829ce3ef4e19e1fea2e1945d4471c1dda993dde26c856ab40839ad349600153a51eca7c8667245807be1df58e61ab6f3ee44d007b2a2fe91d43e49cdd5f9494a106c62810a79bab090846168697070c6d3dc5c1809459d1273906e482197af5312a61624b6cd9d4836183a16ebbd237ac52703131acda724459a5a8e6f6185ee4a22c3e2a299816ef19d6a8b07bba5feedf5c38249d67c7036c8439a6476b9b6504f137ce251d50f32e069cfce6ad0859c4a3cdacc8fc9ec92b7172cadedc66597218c85c1c30dcf1ac87d363895f946b81bf8615762423c4d6e680250cacc6b9d97567215134973765fdd5c7342a5fb40cc8ca5c445f1ededd874cb8aca04f8da28f367f0adb81a30b4531bb9dcd58c90e4c76c0c0cfc5a8abc8bfa1716e1613d8a63cd8446f28d4c7826c901f1fd660d1c097f2e956ce5ad240411dfff96fafb5f125f3557a425d7ccf5899bec1c1470fe93e27f29b273d3fd323529f9b498e93a7f6530fb9fa674360c7fedd5697979b10f65e938375fe1dbdd7650345a9c00a2226b1b3b00772763a701c50ce4c",
+ "spend_index": [
+ 0,
+ 1,
+ 1790497802,
+ 4294967295
+ ],
+ "result": [
+ "f03f41fbe6fa92ec2305822d84f8951c10b434d32910ff87688b5e0954483dd9",
+ "8d1ee39f3f10d26642ac461076cb16b9fb79b5a13803f887235405762b460193",
+ "60318fe6ebc4f4d78b5670e4fd932b32b2144c7f0893894fb7c6da3f1fdb6e7b",
+ "3a7bb937b729b5812da85c294edf30e930b9c9b79ce4c6668d87208626552a18"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 3,
+ "Witness": false,
+ "Version": -1503121461,
+ "scriptSigs": true
+ },
+ "hex_tx": "cb2f68a609e5de017500000000000000000000000000000000000000000000000000000000d09e2c75005dee941d01796ad30000000000000000000000000000000000000000000000000000000056b1ef68cc0c10a3bedfc6217be5c1971491ae6d8f63812b90d946e47af784edf79c999d365da76051f8ff09ad86e0ed91177e5b75f97175341529bf4bf3e33432958b1fddf62c6db571f28ea06c35945bfc100540cef9b6ecdd9345f2f615102185ed0686662a6ee2bf34f70b3343a1b484571ef1b7f51f0a40e550a2f33e9d95ed3e2f95d5520b051352bd822f9917195d2f05e2a84e5dc945e94076a8aa5770a008df326357eb34177a78977dc0ca794b84105040a8aada606401f8232e3dda42660aa783e6523218143ef279042232e95bb0445e4fc6f900000000000000000000000000000000000000000000000000000000e6ebe4e8fd4f012f3dd6f2ab4c101582a10dd8f65c9c3e584f17bf7c167fd6c5f3bd3b317c3d978fa2699d67853c33c351b432b9f3172054e7aa8a4f54019c88572c06ef175a2e509491f23c51fc28384f99c6aadad951d45f4bbd2ce1558ead4d687d4bb42faab7755f525ceb1f43059a62725840f8e9539c4f4deea0111bf4c4e6531677c66df5311049ac9888612dfc39b8629e6a44cff527a0be982527906a3479543ca2d6f65a9e028a4cf7bdca28678d63d321520225460134992c56d77809f2e8eb1b8829e26f92b5be1cf0e35085366b6514fee542adb64ec6fc224a58de6acfd22374e5fd7d7e63de0aa53f9646ebd9c373e01a680c32ed65aac686b5c4a32940080cee2a50cc1d92f2fcc4b903d29002b3f20cff6a73783eeb935275ecb29a21bee39e50fcb97a30500fe35ac0c63966b68d08417777d193b5545cd3a57a56c2ee321bbc3e0fdb70d51b2f86347668995cfd0ab0d835bcd13700000000000000000000000000000000000000000000000000000000909ab41a00022fa8390b856ec4000000000000000000000000000000000000000000000000000000001166674a009a5886e8859d478a00000000000000000000000000000000000000000000000000000000799b5fb5d025f4015c024ec5146499032e5b85db12b613a37f9eca6f0daae0339e5b388f90454f9e5526f69b73ed8bbbd3da06eb5413a5a7e562355300982afd5bf1eb141cdce722dfa113ebd32928aeaf331ca40f788e9388a0e72fc65ea6338104aca1eb8eec4c3da4447147543104ca5b64f06a8d6429efe123d4b704079d786294dffa7ea6349103639bb5445d6be9bf00e5b2b04fe48528f6751685fb770cff6a09322675147528cb93b733db529aeafca641a728b00e39528af9dedaa626d9b6503f5c8953c4dd2f9334af98d73429b10225522feaf01b4ac33500000000000000000000000000000000000000000000000000000000ea307843fd6501e76f82049eeff7f492a0e5ab9628cd4b18131adbcb67ae132c3ab6aca8dcfbc8857d65ca2ee39354a8abd325f989bf53aa3472e057c78c60f68032c1fe9b1ff518d3b46177a63f879116bfc138c1d8800143927d931da826d389a16b828e78efa3ded11b5a02d5201233c9813b7ef1101812ab4187b44969b6ed2375164823bcb896af25a6cb2ca6f658cf7d65656845aee7ce3f115370dfa65952454def15460f501d41d72c8dd5d24f05c7a27bfb653e36057c7387f040997e908e98a2da052acc094f1c72473095dd2b0f0388c800458cb869e67fffcff7024dde61f6d44dd799148b99823d5829f907f6195ce1369d918d44d926bc818e882412f852d68be22621c5fd0d1489b9b886950933baef7e087c8d1d9432edc50a4ec45f715b16fcc099644e6ea9f698a0a11768797dffd45cb5c40c7650c1eae727826e8dfeaf6d4f7db6c88262f21a9bc3e2a4169f1d6ca332e51c5254137861bbb7f81f5876c2d5b2309053c013e14085a2350000000000000000000000000000000000000000000000000000000086b313cbfd0501c1823923ed8340dea30b27639a9e04fe0a05956a720ade237611f42d73e77bd3db5249e7882591f38bb387f3be852ed297cfbf74268d51df9a91f1daa838a932cf8fd4e07306041c582b41786add151d02b225bb4a1deeec7fcd7a4df2630907fd5d4494b5a609d4945bf684ac0610ca35366e8d2b113d51a1ff1f1e1f45ca772f23ee577552245c20ee46593fe8a4c856ddceb1b964edabd8dd33367213ac7eca9fd43441261425a3b01d98ba0c21a316922baf7cdf1695cd277e7a544ba701c3a4ba8de3d1d2cad9b0af19e95288474574394e12121f2313861bf614ae244f37ddb3c8eed5b30bb043f239296579c39385106a206e430c950856b8d0ea237d4f5554851dfef7064b186d04bd000000000000000000000000000000000000000000000000000000000409078ac09bc4f8cd9c964f9c5e4486e37161f169d67b45f0083fa625e05fa4c38fe6cb6dca359ee8eeb8c3f59d0575415c9439bebb662ab770b55df602dc9bd3057638887ade68586d70ff0a5c6e4d3d8b69a4000dcb221683f41a675410019eddbb530ab5152bf57b9aaf5b77528d29e5cd052f1a870aeffea850a75f060b66328b7eaee58b381c083ad7579eb2efaa74dc01f230e4e9635a27f38f73786b9e773b0d5cf640c9597a70e28e83ccf9d5d54f34aff383e7ceb72de13508c57c69ddec46df91676b8203b87c4e9c53038d04c8d40bfbfa8b032e4a17379eb32f8bf1e456bae2bcbbe5cd8e26aa59a85b733215d93dcd3dcd4f0013421268d42e44c858dc04fcaba2454e8a08b4cf156f1e36ef7d3485eadef5e5c7ab87aa1f530cdc8a314e5e43bb44fff91c4e2639aa59b8a21507400f3691688a7a43fd7d54df22d556d17fc8b39b3096282bfce97d5ade0d3101985b1654f8c65269ec354c64861ed6f238fe1aed2c21abdf0ee5aeef56b6444c08cbdc60e6996a9d18ae6724ccc824474efd708272a99c19104545477a16c1825cface71708b5df88f02331f4064c8f0c63b7bffa3575667fe06d6e631ab8db726ee012c6d4ae840ad51fd1c46805689bfd7559be84c00e167a1ade51c3c6192ca0363905a8f396e42cefdb9522d93a7752b6c0bc31e0b375d2023cbdc66b39e0c76378ef4039330bba17f6ab6fa36eed1acc396c3f6d1279c30ca8b6a06bf911e59b5cba6e344a013aed80fa048391bf7963584500daa5c6b3dbfa550a46f69f0bb049a37d3369236ea94bcc5175475abdce243fd1dd6202691fe588b701d286f9511202bfdabf265601cf099e4efb8ef631face8c4e2cfac08c92e1c545fc83b7a1c23d3c0197bd0c0dfe76a7744863e9aee8eb1a315ad0cc9a7f63e02247b9e0f82ed9fa62b684d022f651ad8a8b64feeb2e17ce697bd66bf943e2cf286f015f5671ea22269ee9deadba12c2ca3873ae4f91c281c5b24b6782aa6f54c83730c855b4c0340da726cbaa4ab5a4b141809d83fb821214dc60b089823b6dbca1b944fefaad4ad7333c8a5e65254e40d2fc51283a76ecde81217d067d87b359a66a363e075b6fbbcdbfbc39c7d5eb0a5cbc01d6e940d72dfa81a73da02a1931b1c47b37066f9156b5da387c641",
+ "spend_index": [
+ 0,
+ 1,
+ 178805667,
+ 4294967295
+ ],
+ "result": [
+ "c0f082ebcad4231a1fad70bd0d02c5d293ce82d7c7e7db185d5b2554b2f4455c",
+ "65f3fa82949b8689ea3ab6107c5fae7127547bddd3c8f70738905581994820e7",
+ "85d973f15ced3f6133056c16e5b424872150e735c7b19a0045442f336ebd9f5f",
+ "8fae3556a0ede99ae4e1bfb4680dad9cec44f64de26afb93e3ad0f871c226cf4"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 6,
+ "Witness": false,
+ "Version": 1575624129,
+ "scriptSigs": false
+ },
+ "hex_tx": "c11dea5d05cb981dc4000000000000000000000000000000000000000000000000000000000c9b9b0200b290a7ac6f849bb300000000000000000000000000000000000000000000000000000000e91bdc03007f72a0d3acc43e6200000000000000000000000000000000000000000000000000000000b6b1ad2d00295bd546d097890600000000000000000000000000000000000000000000000000000000bf722469006fa6c23036cf1e540000000000000000000000000000000000000000000000000000000089e9b7380072fcf87606b2e599f5ccd68544c897d63d66776afcdd23524fe6cdb266d5c1022e393b15e3ee17a96b56af1d9aa19d9ff7ce38f2bc382c3b4b21fa6555b4af8fdf82e3a559a6c6ed58b0c042c4d281f539a0cd9c5404ebe7f8c68de5dd1aaa31d449a6b22e7c353d4f84a738a944c3dd42ec792c28e7e50b4b25b03c4e86c7e3ad3779977943bd59d7a06a9e0090bf65c3c224dd9ff87d7b7ad41c3f56b6d391fdb3988e5832def393ee04113ea86e347a304987b08ab59ae01f63e01f3b747efdfb2bcbcd03edb079dccfe5c2ed683a671780f86b3a3646a566e0d31302c8a788110d740f48430a499f8fb8c445d6d1f8c3b3e07e94a5583cc4f539bfcd9a8e1b160792164cc7b9d60642e8e50c4c46d9590ecb8dec0edb4724e092b8ca9204099ab8bc9f7fdbaa9fa4b5b08b1c87816812fe09d5d4334f64776faab8ec65b8c03295fc44960faf95d6eb60805ff6a3f2fccc6afce6d49382909c1841de89abdc19dc35b8114b0845aec5f4b1cd7ab335f0c31ef279e473e859f701172f43b7c77fce8b1126af6a4adf0862127d3e4ae3a26939ab33865468723fc52e7f06221bc6d2c3ae9a9268b266cb6c79605cc8aa2797beba4931b1d95ea442894acd628a631cf9278971b41040da8b69951830d870ccbfb4e14c6bad6f478b860c576a63a920f837fb311ce454a471fb51765809d682b3952cd2afa0f317f2e4b78e3bc4449a89c10350da53a331c082b6b42d4675c99208ae204e7997723d3b289ccb1bc297ef4d59405e0edd2ae0e34747c07569b477f38b9c6863b778f2d84c20dcd7bfb4440788a6214d34ee7c8083e4f1f74471ce772b43cfc236c750e4fa83f46cd676f6a66bbf9b248cb105ad129968547b37092688c8c8dcc09ed8c4a32446c8a4bef9f3e37817a5c02128f3032cc8b4229c047c84e2167852aae160fdf153418a6d26acbf78994e902d18d83000a0be6f0a8034495c73b32c01e35f7b9d992ee3feb4bd48f0c14f6ca7e5cc606d9f6fd1fea227ff025cb5011ef6cbc90fd3eb56d6c5820355e2a1e8ef3dfb74dd78ebedb2edd1f40913d6f07acc44a6f398f2fae987d709c8ca88c68d614f6454ab8ca4cefdc57471f2bcebc38cb511253baac79261b04ce77b423b2c9f0bc51d784f75c16b78501772e4ba06dca487a1b990f7102d1a4f9e3669ff4d55b4831a4f65c8e7b03d0acee88b7118c26924109098272ff1cea11fb4ee9496d53189fdf8297df6fe9be7ea9c0691c5b1b2fdcbfae3d962087c340180750b69ded3b7588326f51b80d1dfba75c7be4f00d0d0addfc2a18216b120b3944590d2a5a767cafc86798dd75f59e29bf23a942d6d903ca78d3e8da941af499d4761cbd4c005a3679c8eb5324d88af0a1bc29be3721452ca50a2081824a288cf0e91f71a820ca781bbf90bedb0cfefdfb951ea0e975116d5f640c781e7060a521fd3655f8bfd185966e89f75b4163802287305aba751220d017fc89843f5e6ec6069404a67fa383be88db9707cd3006e4c3dd25f5a533b762b21fa06dd152ead0a659aa3e085954ede15dd0aac553e8c3dcc09450add4f1ce86e0d0dedb3a848bef9d016147b51d8ab928c2fe100f5d5893c6babd9cfa5b66ee80d92ccdc358330711a6237c4db067ee8347a1c7543dcf0d82d51ea17f75c8db0ac2354282c7eea98052a584a2090b2a3e81d1216090e0285a8498e7c7422c7d95541a34b9650667ef74fd06fbacdac9b73880813bf645e33aaa3711021beb326e8abd9b96b47a86770ce6994ab",
+ "spend_index": [
+ 0,
+ 1,
+ 1689259243,
+ 4294967295
+ ],
+ "result": [
+ "bacf5ce1b20c30f37c9fd6bfe1ea6a0bc2d11ffbef851bb2a938774ad81e24e7",
+ "76a6b018ce73966a14dd33b530cf7bec0654bc03c1069425327c2bd8ef8dd01b",
+ "2b9480c19a30bfd2d71bdb6432ee44a7a44c1e19fd5e50422e98453a27c4b361",
+ "292235358d40ba53a6087432aead647aa651f3f415f876da958fd814d09c561f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 7,
+ "Witness": false,
+ "Version": -2047477303,
+ "scriptSigs": true
+ },
+ "hex_tx": "c9f9f5850a71a2521800000000000000000000000000000000000000000000000000000000a797937efd210139ca4af1285756ba497203c3872a7a74b940f5691de5b47b685708a92a2f2faa74bdaf7ba88ac45e8f125a3a1392a52b7ca7f2379af61d8ba371c8a97c28812e62e0c4180d2938353f20b276e5753a466f15f680dedb499623a659052569a57d3f946dda1f587919f424682c2fcd35b6bc8fd9d3ba1472c19ed75e922135b1a4752b89512c7633796caffe25f7c5abb1e4c45986822921e2ed8d4e653d1232b45b87332bdf367248654e48604bd9b487e6786ad47d9b77dd3edc2e3366fd43981a54b1cead2da51601ba9f3a0fa0ff3d890913d43d16e5262beb7cc3be424755f453cab87e78281689ce51c1025e64493d3f958bc0ddce21d75fd82fb3215bac54d40fc8db06a19994665973e5f627bfce37f6e7b608585a7856900f58a67d89344666517b253eb1a800000000000000000000000000000000000000000000000000000000c568837d359b2f75e75b3d39b5d95ab308837b50b6a4724c83d8884e52d24ddf11ee2bf8e2f09a6aa86e6849a218598f427f899017db9ced5e37da0d3121cd256a7400000000000000000000000000000000000000000000000000000000eb5cc6273221db095a626ba6a6f671293cda3558d1c3aea3562fa80f535882e63dd40ee619b3cf5ab55338c5d64b3b041bf99e6b7912124b9ff01b549e13a1000000000000000000000000000000000000000000000000000000009ef30358fddc01f3e13fcea1413e057861d719e571ea78aba967df3fe4f52d13d8fc72f0345ada8ea98a968894cf0d59586c298dd9878d6bdb01877289328be0a280871f629984afbe1cd05e016fa0f38123bd5c1ca1c5fde54beb5c872e5b481662b7b86093ef6bbd3e59529b02496ad66583e73ce2d5af8ffb787dadc5483180687ac1014a22a35c490aa0be5a1326619057de4a6b5395540eca7ce0cc2df05878744ab989b21e9d6bad9fb7d5f658d777c4c83d11eaa9eeeb74eabb2e335f3ee751c9c294dc3c920b9b619b0242897acab50c722fe78a2dc2aabbdbd36b10c18525996f558f7d2cd36f0be38692dfce12e5b507be796ccae0bd29b293c4ad831e7bd2138f06576b395bb0182d67a900b60e588152beaa2b66bd9e763d25b2e586806fd09318e68fe9d61111884516b860d8143014d36f43ade13a21948f6cd02dd4724ee4d9f348410c4187d6236164361ddf614d7c9c75fed4b022ebb131b1c749bf3337fc519b2a6021af2f575183e587211d8aa70d1e5bcde674aef5ec5a8cfeff8b0ec44974a704d4b199f943344dd610c97c6998b7eb4b7fd6f946298946fe4d8c2684beaddb47a7219b1370a2a0dc97d3f159885337dae2ed4cb067ee9040c51ad1a557c3134b5d88bc88dffd39fc15f550cc5822cdf287942d05a60306494a7c10be05c8f9b000000000000000000000000000000000000000000000000000000000694f038759e676927bd0cddc680bc3844e849de663b85aab13a5738e4e8edaf7efd4db889d87bc03a060118f8a6e720a5f5c9825d110a181eb8a2be1216f21198cd954d2fce2581b3ff50725960a9013a8347f270c8dbc899a7b20f101f67ff7573d32e63341000000000000000000000000000000000000000000000000000000003f46ee457c3eee443ff1a0a98c0e17deedad1445a18de5b2a734781a0cc5de3a1577b4c11cbd94fcba823aa167ffd6282a805e8fe896e883ac8e0f9795fa0f1ce8cb39042e724417cdae4c3397cafbd9792738820b286a24e9d1e3b4bad3db1ad46f232bf8e79da2cd1f5f0364c6c18c9526d856e725c3285aca3f0968f7d71143032a22ad87a2b12e00000000000000000000000000000000000000000000000000000000edd59f3dfd0301683b3db9e8877da4b82cae60088f4cd57375d6c182831acb9d86ac0bce97887bbc3eaaf0644bc87ca1e81274701718d2000697818b8124aa686b06a2ddc3ae69688cdc5c024a4fbe59616c22202cac77ddda4b52909b166d651ad5122c4826e2b555ca52d75892de41d4eb8e8cb2c17bcb32e6dcb327bb36effbbbc8f23757097813095f6b3b1513c36dca3d3f8c10b6e87884c18c18c83ff27588672afdbcbc7956e63d38e265bebad4a2244017fcd2cf948c9d0f8092fc61c29245186a53a87b1956fc7e0e2492b1381c057a56df789e9c0b7ebd1e54097a6a1005cd59a2c5be167a8327019390aab0a56f8fd4aa82b381e5788e60ed8975dec6fc047efcb2bbc597cd00c4d342aeb95600000000000000000000000000000000000000000000000000000000edc15b9c0047a68fb336095ceb000000000000000000000000000000000000000000000000000000001b0abbacfdff006803a5b4846ed22ae9af55d16d338f39d56b32ff7e6a42e8a030e50a2680cf3414b7b8a2010a8ba6bb70265aa6039f06ceac4a9613bb5b38dcbc56eac41d420548e9558a16213d5cf7c9fcb4606070a1a1f9258ef17c895c0bc00c5f630b702fe0e425b6990748ff78bdb27d6512a4c9f326dfdfbe71e55f15c7be300d606aab1f5c4176931a8ee3bcc13f8815311529c7c2ea41e3280f7352a296493d2824269660fd24aa943608bb9c9a9e80a82bf4853f882ebd5028c79007b91f430e106899a0656a9ebc4455d81a40158cccd76b92adcb5051920e5b0f1f305140aa3a284c3da654ce887959ce95f1bf095dafed6e4e5e78fa1f32e8655e68e980bbbeab28fcc45be2a6f0000000000000000000000000000000000000000000000000000000008f7fd2fcfd3501cd53b57518f1d683ba3e7395986dea55c44a344f653788a3a820a9c695dd3d92df0d7ec6f010559dc6423d4d6a1e282f7a3b74fac6cf91d6b7e61e0c7b3df2ec7ea3dedf627772c0644f2ce93abc90be91bd66426f11f1a1bdbbbbc5adfd0d8be28792bafa71603a71dae861fa62dbd7f7e4fc98261343414e332ff5708e3c97c04ff418e2b2ec185d1b8d1d589937c12ca0f2bf62393c9e7ffcc910d96ef652a77af479f9646957f137af33e2e8cc58e5d81c80605283ae26bbe479d6dad6c651f10920fb383486616b90f2c658c4a39e1cd13afeeac9a5a11ce7491d7cbab2808663eabede07754429ee753fd65973ba88763881fe948863d12189ba885a3d4bb0a3895fcdfcf83f2e20a3f47d3121278aa64fff71f49e61cf0db1dbfa0fd27644cb79582ef0c4c81a088abc64ee0f332e1dd3ea8e605ffa07958d3b14523f0b48c82baf8901eba24111293e08901beca34b0642739d825930c604dfbc401f30ad29b6e97b716ed98677151242c9a109050636c83eed74df2a58ba5bd6bddd07bafad4e39a0d6e3310fd1de8c6a0264a1c536083f69f1cf4932ec2d34fe1a0e85f2bb796ad86ab07142cb28b3b91f3c178b993608f7370416baa1d9ab723a9007d083f07db387d6c2e53edcafc8940b945adefeea701b9509f08b512a4135fc00ce68807bee85521217eadabb6d45e37746b3151aac0a18a052030c18e9173b48ec6f516c2ed7d7804706b052b4301a2dd3dc8bed99ebca3f28694850c382f0a5d226128b055a8080826ec21b61a70c74e792e617457917f31bcfb17aba58a489354fa9627dc2a876f65f8f5e5ed4710913f68aba0cc20f6e6c4df1c51571a00f5c5b552f96c8f48278d2e7d68ad0c5e34295b899223a1a050d2e9068fa1532f6856ada35ff0d46dc30bbd1a360fb6ad6d08d9b1c409be3cebc63cb049f8582ae4b1ae823e1db92bd1d63d2348a8f52ca9b0f17d4773f013c6f481c5ec94b4798e1b2cd4ee8aeb145c9abfa4dfcf8c94c720721d4ad0482b55338df705638f45cc8159c82df07f7ff24630a26eebd8514fa62ea0361915628853d47f3b9def22466c99d78f8ce43d1937d616547e50f6aa1a7fd89da71b0585c2918d9e1f9f76050a983712f449f74cdec61641da51f6a511738de8b1e535a9c86a782903dc1bb6c7c2352e1377404458a5cc8f55fadf06c3c1a13508e4e4946a5a03314124621ce0f679b816512345d92fe6cb00e5e54692f813c454b4d3457a80de5462440908f40dbd9405177aa97603acac2f6d5d455676291fbf033b2807644dd91de143d36c438574d26bdc85a52bbfc8d4dd941073f44cc821d802e47b393c4efbfb1aab7045697df1a9850ab9806ccffa9250d6f84ae78f3e5fc325013b83f27b387cb2ab37e2569467cf0ded9c6e570c303d8275f0950d7f2645f299ef2f4157f7f7d5bfb330c094d83b15fb2cd6ab743ed3322917dbacf75cd00e1de5aae7d40abbd6ba08c22e2eaefa687cf6ae33f67bf3bdf07793e8e10128ba6f01b64758a376e9a08e71082e46bfe19564d9eb4cb602311223a756a87d1499d316f59260dc315c60532af3fc7f73eb3513ae426e6fdbc117e49bcd6295ea4519a02ce61072b4670874975bc86ca4c27018ade97e38a902a7fad9e41135078951595ee5d7121fa6b89eeb068a1a361659a0941921c4a0e5f23db42503f88e82dd955c6f9789d877e37fee05f44fb9771904bc6de7566c7d05b3f254fef59fec0a1b2a2e35f01ea60f8b3b1dfb0037dd51b33a3f97cde04bc4aa9408a40563e078005f00bbf94b1d962679374957a5baed6f5878ca5aaedd2e316c1fd4a8fff61d9983a938cbba3973d958d3d104485d53124483fda8a348ed4e8dea2565e8d214d3175befe054bc59c51a18b2a6eaca3d4e6720a4b14390eff349df23c8767748137df6cda8972b3d7e6c599bd39879f38de3a774ed8cb8f623f50eed76534d6a94ef9c82f369a953cb61a11e1aad8f206b8435005db4e81d94bf2b641f47a18a0f44aad259d958790ac964b1702aaebc4b40caadb03a665374803628eba669ab4306173a6baec79b77bc1da5b816574c87769ebf7d092f46f1489f8121814412ac036ed84005a6554a494cd920ebb5d8b804c0f65a7a43f33b471622394b4f35c9dca24d876aa8e5cdb09c50fd9c89e8ca616b2563bf03d31cd11e9699cf7f8081587abaea378b02d48a7eb36bc8de395c6307da59198dbc8ac1f29c539f8307df511739b84cc56bc31d350d52bce9955d6196a3416b50d38468e3bcedad775a09bc32926359b81b3b7b60aa814aabc4800bc3c3e75b71e0e4c47884a8bb3aa678aa87234278e2fbc5da9af56d14541f16ffca371e041ff605c06bf82230ebc54d62ba00f92bfdbacadb827016ba484a74483e0de639c742a2d5e24e00de9e6eb63776ce742bad238567137242c4e5c6fa8f3313b5b18a1dd8380073bcf39c700034001c5723f50a715d06477a93ff8286eb0f4cd84f4ca0b4e9",
+ "spend_index": [
+ 0,
+ 1,
+ 1195087093,
+ 4294967295
+ ],
+ "result": [
+ "6aa6c8f163ed519070f1b5d30899f909846523a9f5d52f82e307f6e325c9892f",
+ "8afde97214a02462a752ac79057c77d71b29c7092d41566c22ee2006289882c6",
+ "6ce7c0be2b0433f000fcb0c4ba54e1dad8e62939a65b6b99299fc2afec725bb6",
+ "6c86ce104cef982553616b66e045d4966c7c8c29039823c9d42420baa3f07c56"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 1,
+ "Outputs": 6,
+ "Witness": false,
+ "Version": -261671089,
+ "scriptSigs": false
+ },
+ "hex_tx": "4f3767f00142dcf017000000000000000000000000000000000000000000000000000000002cf836ee005ceea6cb067075c902188b7267c8d41847372c474a50b5fa4210c567208035b741fad25c6648c75350636ae11e4e5f8d1bc3f506dd8e9f736b5005422805961b87890e32aac131083f174433a492531c52ee7d23c03dad6eeed7e350334a1d673b5bc8571713712466d613bcc63afa94e31c5d7024da21180feda39b66f5948b7363bcf687bd73cf3142325a267423edda2e46bd38e5450913f632345d1f87afb0e2f7bde2821ca24f7b35d315e54c89c631ed909cd7531e271b820475f9f59858c53721404c59c22de68df078cfe67cb555b965f4fe79066ed4253ac84dc8c2faed9b7be85308eee3345f411b7fcc082c973ead339c527b9f41580dd57ecd2b651e4f2021cab0df68deee19f4f8b1d3f0dc0ee245827f9e15776a626e784ba4e25e5cac87a4f38237f86582f988659c8da97fdd6635340833b47b60d7f355f0a3c594adc66088617a421180617f4ff302be83d8a869ce3b5dac88770bb5fe367ad271d5da178c8427cdb57f2bf52d09e53eb52b739ac3f8ee1f7fae1f7ea2f40b61f7a25dc663247287eb37e9d07ec12acb11218417fff27e1a23b0192e6488b7e0acf650fbee9440109b59886d16c84f86b287d715375c60e69853f621999e780254fecb325460c18c1c533ffdd325b6dc7ab559615974a4e869e887c215a25811e44d14c3e1cde85302b45e4dcf90d6292a8098c30d70ec66ec9de3cb989ef335f85589918c77ee9476bcdc2f77f75455c647a4fa458b2c5b0107c800d575dcd7776500d98dcc87734fd10c7bb8ea57bb1ff34b124144c075e56272ae8b922cd0a97592d820257fca45f0d4b020cc56b75bb755301717b62995838bc8789f610037dd4ce3f4f91c9050127373f6f25b8380a14f8b4a835401feb2588ca131c85e4a0ac5e4d2d52198438b4ef5fdd9494d11e919f6a9ccc499de66092e2d5b815b1af828b36afdff71274bb1e765c118585874d12a1f93f19a7cc490ec809ea923214f526b6bbca0bbd44363cf74cae4853ccc3631c51deb06c6b84ce6b1c7f8891d5d86457c28835bb6a6fcfdc3fcdf5e1aa01ad043bc8586e03aa89de83b85d55fb367efd4fb0f32512fb352d2daccec669211147b9bab8b84c93c3fe18b878ab6218b2e93571a75b9e405537f6224058482e6334269dde4ddd732b4226d3292038fa94cb7c529e270e18bd1352819c8da36327eaa4004505ee199b3a4a6bbcfb243d33e2070f284304c58ead9dd512b1a5f616134105bfdc27689814da6628ff7decda254d51f56d48a18aace93b425ab9a2e850b8b3554e2f4f3ba93ced376ed2784dbce2ac333b189bcf91fb6ca0048063114a1a62aeff98b67ec3901d1e986cfe63e4979da9f13c642ed55a0446ac66df97231f3d025db73d707ba8eb6f140b9fd562da17a8d4050be92438682fe6aae8682488a579ed8302ea51053bd525ed16fb71045daff0aa5778286357c8a2eda9923d11787025945dc3c2ae1e55bc85f4128c5502cbe1159affd70b6320b2f6081c64f55304f3582a42eff01da1231dbf3b4411eb0f12e03b52f8170bf0c721920912ca9337754c7014a4066ca13c032269bf59a4aab7fe7ac4265abf5e34d983da5594abaf4eb582913e3f712ea08c3f861c6cec3e182fe3a86903e62a8d0dddca5a8348507ceb9c819a20f7b721bb11b36fef9e22e6344ea75854cc8c7964ff8040a853e13138fc1d8227f6e722805f53345b7b540efb48b0f49cf60107f3885036111c3351f42cf92220c7193e45dc57749196778a0dd60d267",
+ "spend_index": [
+ 0,
+ 1,
+ 2550797592,
+ 4294967295
+ ],
+ "result": [
+ "ded67ed13e00b640de7195e0da96c0405467542644a4794001bfebd0c6a2b9b2",
+ "2ba50675e027fa8ceccb9244f4fbd5fd0d2366cc69b38a3f3a5ace71af7c6ecc",
+ "f13c3dec9ac4a80790fb6366a297cacb6493e44382342d780e5b0db737216fd3",
+ "e0e7ad3d3908da50829786291541fc8015d69fdf65e4b2727e084aa5327c32d7"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 10,
+ "Witness": false,
+ "Version": -314128345,
+ "scriptSigs": true
+ },
+ "hex_tx": "27c846ed0a80c6e24c00000000000000000000000000000000000000000000000000000000ff8b159f0074cb1b9d5e00845d000000000000000000000000000000000000000000000000000000000e6d24edfdc201a28b5437f918eabdee7f036abf5d17d23e586a13004aa00252ee7eda09b265715050efd3a7ef31e1f77a8dd599aa4c8478a07833dc9ff8f95b9c60da6eb33b24fb516703eac7754f660014ccae667be1c5f72718e58074f874216f389b797a611691471f3594eabec54194be149927007950705646c1f3d45d73363f5c8cb62ade56260034adde6de77851bcac997abebaa10c5ba7007d234e11d3d1e190cb721744a744e4374f7a1c5e2460d077bec111dbb0a9d3bfb6544d4b469fa80a4fe5915a4d0e2301f7834cb149637627294b80ecb3e9d5ed92179964231c9aa680911da5f0d1804bf34534fa394fad36c7d974f2d99f4d0382eb640546e2094d6f2b7a6277f92b22f545ee0c1c8415a8a0a9bafe84e2b9dc72a1818c5b802bbb3e83bf9333c40a55321e6407e9a24199e40a3b6b390f6a58d54488560a926136ae70a57817c5c99263201404edf6ddc0abf690fdfe4e28741c482834aa265cf89821d2ee4c2a2e303b4e5c6d60859165263d3a3a10973e85da17102cc949b8f58b723641c5081a6db6daacd766dbd2464f14c0c80292f30d77d31179d87ac7a276d8994af4ea3b460f9a4da942497d638e22eeadd1d8a99d016b6e723143f2bf0933373229a7c36a876418b200000000000000000000000000000000000000000000000000000000d11eaff8b03747c37916c447e0bd12088ec8991503c5edd6787b75aaddf5fa306a25d779522788419be153755991799d8cf6edb31a99de4c285733a28521b2125bd29c0bf2d59372af22fd4e2ed4c22782d55c77fdb1e06b05d94f4eb2d1928b27cec8e0c897f2929a064abcdf36727c9141febefbf5a1c64fcc80fc13384622f602ccd0ee18b0c63981ebc4ab01ac36b60f7fd20ff4bf192c2b6bbfb832e7b1644cc23b724f3972d0d8bb5beb2dba946559f7978eb6d33e5d9a0798ab00000000000000000000000000000000000000000000000000000000c7ade67d4a901eefbf3adafaca07900b372acaf84573def30025cd8ad79d67698c9394c0bdb8a7e81fa893aafa2cd596cb1e41ca96c376601e618c29defc023dc73ad746d3dd2586b39a2307e5c4a6a385b3e05b25a0a0000000000000000000000000000000000000000000000000000000009de5f8a1fd6101794a308c3a3b17197dc5bd3bc31c1a13faf76290c11e22da8e5243e7f9df2de976c0d3c8cb3901adb94df51f822f21c4d105f186f9e818c23e2c2a61002f518715e8c61a4fff2da5c967bd145121950a8192fd642ac909c810f6e50d69f224a2456bfef2394a8c041b92b51d752165d5e3beb68c97f2774e87ddc6775fae42c6858026f3c21232d45fe079acba4df781dbdc9c5971500846c76a73094a3f0272b0ecd56d9eadc50e4657e8d04803bb1fb8eb161b56888ec4a59e2b937e832d2cf4f89acc88a4a283b798298d01014c2a6755779a8fe9e3cef6409679599bc668017fea94a7d34fba2ba1d8ae20118bb1b4c75f1477844685dfeaa0f669752648be407001399045ff125bc812e67ce6659760f7ffa10330cf63933df273c2a732995cc88c369aedf0adfe9298c2004697bfc63290a3eda5eb32da15d28505534e1a652694f6d69eb7fbb925767759795bdc475b558dbf8c10bfa35ec9438b675758649f928c5d1cfe42000000000000000000000000000000000000000000000000000000009585b4aad92dd9dd929b8c4541a894d112ec4c345c01ce68b81ce1580eb15299b20929a6d0941b889dda59444eca47c462072e0822c8aedb88e0c37413051f74417c85c677602c715dacf1ef27a6b6bf96f2e757aa35594dc4768a7ea74c820d686612e656ca5ccb186cb0239b569e807161fe27c7094923f0055981bc4e96f027b33fa3a5dd431facd38f61127178f613ff89cd558e74aaa34b7ef87d7e4b58a8c15f6ecdba9071af642392e70f8fd4a01b23e909b321965f2dabd76b9d745d4cf7357c012f882f7fc14384c31e149b876675061a580f39072615918a45e11cd948eac14d8400000000000000000000000000000000000000000000000000000000489fc2b600e6712876383fe97d0000000000000000000000000000000000000000000000000000000096264e77d6689608c11c1b96feed680b3b8495660dd2f453007831b97d9d9e81761a355aa73e51d3f2f21874d15684065e4ebe611096f849e1929c67178036eb399a60f53d2ab4a4613782d16e98112e8dbae0ac212a82197405cf1f0f0f8878a8badca09a6c2486123c8cef6dd79d97eb02fa9d6e8411a1a9b47eb012617f3882d289f753a42c35783f32045e0663e09a309486590bd44c53844423b016bce45aa54319db1673cc7e7d6b74fa943af69c6bdc1c0d5bf42f63b3974ea79e8cd363d5a478045842bf211b0627b998b04251ebe163ee93e5484280822687b00de3d99585000000000000000000000000000000000000000000000000000000002a8dd8ecfde0019bd51b99024f038464fc907f34a6c795eb4306462677d6fd90208dc2d8171303cb23a999425899bd694b5ac52e8327d274888b75ec09dc85b3c89e8dc5fae1b15817f2fd6511f97aaa0889721003c629c0b051abc0cd6fb0b9881f95cdad9496f466ae5145b2ef0b53ccc31b7458fa376b4ed1a5c56480bfa12bed0eedf90085c901c29413779848b57cdb1e11ab3bb8101bb942aafb72dcafd31b4e9ff2e5d6ae15fc93a3bb1e1b9b44cfe7d9e9a32224a98510c4efcc1ec26db86d9c80abaaf7c806d1375e77daa379cafe1bdcc35683bb1b361552cbbad843a0833e024d1ed0f66df9a6627e0353c8c6fea90c03a42e1d018ef833bd56623b4cc1c91833c6669de6fe7f0644af7284c158ea81c09a7e302d6b46eb91aec4499a8d8cd1b89baf7d40c408d173be78351705de63cfb5d34619d380f8b425c04be8358591a3d88c19f648a62d097d7b3119ea72d45dcfdb91f29e52ebb8dcc49afc30b571ff89aa82137e3bf54a7e66d5aa6b2b638991fef76057b1dac2c113d6e2a8cb472f145fb22fab646e74d6d4835f0c031965ce46ff37eadaaebc8d4cf0dc8c43476a0a3b098ba4652ff8e2a4e33d5103f884036aa7577ead93a06e24469345162975412508264b8ae7d7432462f769e300c2a63f3174e803a48d1735e2e9b8397ca6ef96d41350c4ac9122000000000000000000000000000000000000000000000000000000001c1e0a33dad3591fdf0a81549975be8dbede186c82ea288b85a3b73542057a2a8410f377acc3d5a8042a3abe9e48b889999fa94e632d20660039ee5be42fbcb1c7c2a064f1b245cc8f633c1e0d57f485d68e278e42b162b7bb28e096b85e7bda65957e599bac7bbfd4c9f7e48fd351755dd75e26f97b7c377d2ba4f54b6ca34d265f5b2e47a95673780847257ec6aa89fc011556d186aa4bcbe244b258ba65231d1677c13255bb009e4ed81d14d301d376e35f7f1ab917fd7881b276fb589eed0f1ca2d27b693c209dd3146b30abd12784f1057146528e3d06cf7fc18a66afe5fa780f0a46b0c476e11c0e11c85e0edda9a4558e8636df12ea5f709c430306d9e6f68451a5e996c6d3f3be7db5508c86ef151d8d2d0521c47a7ffe10e3465d313bd9b2aff8f9812248de032e270d0780ebfc5e38c3a08a79e94f6b8fbe455337cd84ca5f2370969a396cbc0fa242b2ac336051cfdaf04970158076832e55661d55935931d826b977b19b8688b367d79b795ee9be443abd800e36b2e38fdf717654038e9ddf3d7b251d9b2bb7f34996dd88f352ba3fc3f4b097fa507e550a767e942f9bdc82caf841618ae5a129bf1224beb2e5ea536b07bafbce673d10c80add70eafd3b58823c22a9667dba9e3f53f96a41aecc79b85c18093923dfc3b606264330cea38dadf45fb42f8ca5f6b53ccc297a66a2131aab3c0e332d75992cfada18ac24bbdc27ca738b55cdbd2255ecb7c112bdc2ca2af7fac32aae75ed02d0215d0fb92dc55bb67c1db0d470256f2ba0cfa216781bb4a025e5a7aafee3cd3f120ec9106e50bac17eb8c1d5746b94e425c5bdaedf0b337f1c042244db78da9f42940c68cedbac6049e00dd8658deb80383f9603ae735a6f13c98d42ddaceb6490b5ccd732fb068ff83ad4c46dee5fc88e865f33dc1ddd00213924837e4e77a29a9aaa962e9eed5be821900fe77321f0397fa0cd89ddc390414b59d73059014a29d6ba0f51d19331fe7906b65d9e60430588b9813cb7a1d1b0cc7d4af69be3fb459168ca33b835f25377bc7de64f1e334465bcd92f48476915c35e188a20021328dd6ae5edeba6ceb11f7605ba708aea7cee409ac7ae52fd79985eb6c0937f8de27c95db4d53dd88cb49ef4d4ba44aa06ea60ee849f2aca8a300ce85603512b7741f31af9e9cb1c0100bb0baf36e82c72429ae9f56fe6c28d25bc1e80797d966c8e2b6f7393a3b09e6c76ba16432bb4a9f8c5e3dbd6395afa0755e050b4ce2b8c6497f366f4278bc0f45cd7c88be082d7d4e271232f54c09a1e155b2445bc579e090748be3d011d181c49a845beade68a6f6f8af6c0a5596380a9fb46a81c03402c17143999436b9e57f22e2e22d7c568c917f6655b03dfbcc7b5d4f6ca236079e2287338b971292e06c6f5dc4a3e2d4426d49b87d09a9f432f40b90b431810d88c6d18e4a13ac69b78731c06c0d3ac81e572228332c200f1b48b1501880c0fc452ae815bfe794e332de32d1b6b7acd263c8840d834946ea5e174a0650a2dcbcace62cad3f70dea795d6a65610a242b19733795d4baf645dab1ccc035c5535fb0584aafac55aa591f71561211771f8dc98da6074a44c524721a5bfa8f5a46784aaf9e07859efe37beb8abd97becf88a0e6eca66b42f100a41cace723eda7b91e8e7c869d83cbfdbe8d36ea677b736671f85c4c55521ebdfdd8aaf6dcc519f803b9cfa7b154f8ffa39fb81471178f88da7fad03407835b4b767b87655b5e44f261f8eb334c4dc96e85700d30d30cba2a4a254d86174ac8bb11e9b9f2eefd27638883ac8bcf0e4949096bf00fc43cf99b44f9fc12469c5045738d3643e72a029d25b323f1e3ce8d1645033f5512fbadf30eddaab425e7a19a2d9e23f527c4a85b1821e72a56c0ded32826150a04da789b01e6f934e15a5d32ff5e128edb0108d2a6f7fc4181ce9f7053e26d7ab2437ed5764788ee58289ee36f27e85f0ae48413a52f15899573c3500e39f66d8142efdb08d5313a69370b2807e0130d26a82ed3d092acd15d7ea314b209efd385cc49b64340ec654403c763a039a05bd1629673e36d5d4698bda16d0d08b265955524f14321d62c880de15f2431ff99042da3d686767e7bfc7897e36b2ef3b2008f47575005ef0c15e4eec0b788cb874154f8904f6d0922ac6c811b49d5eff4bce3c2c466323de1778b6c369c821242de0f06c773c66fb633a952c423aff0d275e5eb1bcb416345098d9597f6bc089a82a84fe4e1454a187b6ea4d4d08f705f5a5c47de3a0f54b3bcf7b8de10cdc6fc467ead97147995099fc40ee0bad50997ad02b29e75da7814cc67b296b2ce61e3d5e6fb962d6819e997f8c59420cebf26f4088b33b88e1e3283829c0b291a51b4031ecf974ded95e55c88219d1cce2f0a6d06990dca93743651986a07741aa668d2744e71d1035099a93a6e57a230dd21f8c3feac40e20f6285229aa295ddb27788a23d8fd005060147829bb5ef833dafbc56c209341cff830ba840c63bf375ca20b51378ae80c5abf8d7802506640302feb0c0b455f0dac44cf9de3726fd65f4e9d35b92567e5e44c45376a089b426ab9760754b004238f210b06c693bbe73947092457b0b770af0a951b2098a4e2b86cfd6b8120e34dcd10b6bea9acd92e0a92cc56f63e7cc062eabe9f07f823ef9ee6c587d9379e19450c46c8d35791b8f9095a5f75202c78dede7088c77484726bfc91eb3268ed9a9598b069e232cc0ec4dc02bfcdf697c7d6bb9c9e51da9b93a05cdf0187b7228debe65c1ff3067616c4e7276a460e8f4932329867102ee8aee94c5216757ff47a79d5bc1c2c764593fe80bc04771b0326988c067579752a43e647d201405b2ef4974833ccd876b47a4a06505404dd4be1cb1b96d1df0e4a1f68017fedf74803eee63fe3a9fe32219df72cefd86367cdaa378f893149d106a0e60ec3bf2d9abd50e8f3330c80b577d9acc3c70335fbaf3c31225820c85eda9d0e968c5e06687f77cfe8810013102b63f82f9a8a166e9bd06f85a8b99efc4106cc83d2404c8e709fcc2e6857d6666e635620ffd2f3c8c0967f0f402877c12a269b124ee1b6b4a3173bf5c5f47977b29fee7690997108bd913e9cfaf0e056b232167aa1bfb7b61629d1bddc4ee80a0d11716dc6fe897ee47610da07b27fb38bbc71ba392731d1c658f6ed9d73c891d476382d3a67d58c9ddc81c7d290041846f4fe7d81981d4ed47217ab2d843d5b8771468ed90cc4bd8efa2ba44beebe43e0651bfae5d1f2ff43e1e7",
+ "spend_index": [
+ 0,
+ 1,
+ 790666337,
+ 4294967295
+ ],
+ "result": [
+ "147d7ead14620070d32f02fcdc3fe3bd2e312cfa54382e50a92f7eb14b3ad43b",
+ "5680032bc0edccf216420a54fc533a0d53afa6359d2e5b7d5fb6f421c5f58067",
+ "16e4e60831dd39d29859ecc35456beaec2c0a6f72ab0a4baaadf6c4790e41699",
+ "6e43d440e6c62d883f20871bef73df87a78cb683ab96c2f478a639fa5d137274"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 4,
+ "Outputs": 5,
+ "Witness": false,
+ "Version": -2004472070,
+ "scriptSigs": false
+ },
+ "hex_tx": "fa2e868804fa32dd1c00000000000000000000000000000000000000000000000000000000df35eeeb00cfdaf51a02780b1b0000000000000000000000000000000000000000000000000000000036ce5907001765c8dc82fe1264000000000000000000000000000000000000000000000000000000003f6763b3008dbe2fed8c76a4fa000000000000000000000000000000000000000000000000000000002fd35f190080a4b52705daa84b4f702ba527c8a2d7912a18b25f27ce07a923ccd658e3a93d3251bc3ada48464a7dcab9d4f116a95b7afb86c6cbaf720104d337c44a4e46046e2c1852050aea8af53b85b495aec3ef5fef0395e51624bf7f17df2e090dac7b1649e2f4d85cf82bf488fdb1d61836027cd128070545313e1f44cc6071a66f0075b2f89b7c20c216a3bc885cef83d594db270884d4adfdd3eaac8e35954ba19e7171d6cf23fdfa2b3bf5e04adc6b64225e6c2d3fadd1c2ca275b7dfa389e851201d8166e1998a741b7311e41989c61fb215b3c9a9e7144ef55e81a1dd057c88373d17da92f6c869d537fc808420f291ec329f5d91c26d02d9fc28bd54be2d42fb88c12735e1bb0e7f83d916198868259b5eeb4128a843ff48c6c17b430a636a081209523cf10549b7abca424368c4eee8dba7d57c6e69a6c482c3cf3dbf020c2d7b0a50a852a99e1d516007fd6dec5072461eb19812194fb4d870e03e15acc679203093fe771005afc7c8ddeb22c4a4ccce4944307e1836176843af4eb2be90fd26cb90be6b4ddffb307751fda4f7b9161ddb31c2faf5704e9ea5b78954ba695e06c7ad2f4a8ab0e0a05dd1d6da322c857cc0b149fee01b54b4a3d4640931874e5a92d8f5cdf6124b7a3c58336f7973f250c66e7d37f5e73c4954a91f669f54dfb544e3a019a92ab2adbcc30071411ace79f4a039c58fc56ef33e7cf87f65ea9f6e2bd21b0c2f88c43f521ddcc7dfb0739bc70d85c1761aa3e2474a129d0bf16bdb9678254db8d39cfb669bafcf9076899da38a64c3386b319f37431c3a195ca292ee99e5b1082c0fc6eac72075af73c264257ba8733a900244f0fcb3797307b5ef30e644f73466aeae75fa0a2cbde0c12c8ee2386f966fbae9d6c09366e803dc843e02c3b1cc0e09e27f4c7fedd506b18ddd5b67da189dd3134f8a896b2d8272a3e0d38b7195d7b45512157d9b868ea79b8c2f8675a8fc1151947972361caf4629bc8c7700ba977794b1632930ae16b47eb05b6f4bac7d731a36081dc5bf2fb15dde1593a08176bd158787beb7985cd1c49f16084e4c257070f71afbd0a9ae3945644589396585df6deeca13dfd547cc9757a449ccf0785676666ba67db68b608ef89a0935a57f7657ca145911ba7b102c8c54498e03e66e2e1de762a53d5871e707e0404c8d72e87643d6c9db5a2a53bc82c56cf4474ee01fbb08276b103c13d8b1375b46e56659d18d15d135cb339f014e7b713bab7713ec591e10245e175638f4436363739b79c4919c4d68347e74b80a0199311bd7150a246410181817d2194472d302899dcae22aeebb04f8d4d1325feae485c435d5534de05a367cd4ca2292f909982a166e8dc6a2b7f1c93fc02b0b350215d3c9b28cf1758ab0c033f50cdcbd75e44a14cbcfed6488dd8cedf6c3ca1d4f47754f2147d884f7ba102ef5faabcb39fae61c14ad46837db28321eb9d65dd365a879efadef82fb50fc",
+ "spend_index": [
+ 0,
+ 1,
+ 4101939609,
+ 4294967295
+ ],
+ "result": [
+ "b9d8733a838d2cf61fefedbb592286444de3440832fc73d1a1206d7485a9e3d2",
+ "c48192f629740141e47599ebbb22a0931225689113e0a185f55f33c9d5be87c8",
+ "68eab01f3ac6ea292425ae8c072fd2a0945bb497aa0f95aeb42e7fc58edcdbd4",
+ "c8c9e45933f973233075bcd7142e3e74fe8429ce8b41c0b74dc6e6425833eabc"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 7,
+ "Outputs": 10,
+ "Witness": false,
+ "Version": 1446712085,
+ "scriptSigs": true
+ },
+ "hex_tx": "15133b5607c2cba0710000000000000000000000000000000000000000000000000000000040609b0700424bc07f98c5d920000000000000000000000000000000000000000000000000000000001cb98a6cfd5501bbb59547dd3d0c1e66b56c839684696ae9d554693f1bc92101826a61a876ab59fc7004b7710186829a8acc20bc161add3ed5edd3ed495ebf0037c66aabf2e6fa0e7b37684735baa980583cf96620e749393a728302b093ffe5611005e4ccada468800b495f8c4bcd638c984824c421ea4d9819b601fa2aa5740aadcf5dc670ff7ead04e1f6814cfb0608cbb8bfa1deb4b2640bb4178498659910b2114184bf9fffca8d82f7b80ed103106376077a28a75c4876713b88bf754679ff1ba05b9582a0b01988943789c7c925c8f418690aa8a7ad3c604ef67a528cc0d7198248b64c0e526c696609eed82875163929fec762220acd0b0956d29e1fc1e28bed792ef5192a099e5ee5265c18f6300c3ed1ccebc47719cacd91cd5760cd23eb5e280a033aa743d5fc01321674dac63a64c5fad5d67c54a4909e02e265600d5b38736275d344b3577af0b1a95a4b2cc58a6ad01821d828f859243f49e3571e0f8600000000000000000000000000000000000000000000000000000000cb7e89001e67dd4e9f07e8e75b61b1ab092976d27b9160d39acb4def7327e6933516af60026fe2e86844b500000000000000000000000000000000000000000000000000000000703a47660011f2a8096bde483d00000000000000000000000000000000000000000000000000000000a1f21b5600e65010bb01c62adb00000000000000000000000000000000000000000000000000000000ad72827680c77e05d377624e4ac98dcd221ea62c147897f9a9ffdc3898c4c572592fb31b46a110428fa3a7f8cf7a6f2abd247275330847d6a3aa164ecfd6e9bd24a8c2dcc8719b6159ac4efdb7f7b551e036bbcdae61c86017c0c716fad801f760cfa1ef8afe3980cd3d8e1b3fdadbe01eb3e13bd628e21f521073feebba0247b45ee586edd13b3083d22d7836000000000000000000000000000000000000000000000000000000003800dca4fdb501bfdd2976bef3a9c3f25be5f591f0557941e9dba9d44de758e3393e564f0396cf2cce34db3f9e74f8455b835925e5472210458f7ea6fd7cf6e7b49a18ab0ed3fef33dd58047f9199d0f17ca8ef0e1711bc2b82cd76e88314f22c71c87d07bf276fefccbacb0a4b5d2ae64b0912efa400740edda8dc5df5e45d422579928423f230a5b84ed0704470a5804707a331918b773a03559bcaa8af9d38544f8b1e515083c6fbbb4f050447841c2be6bae82f8af7997dd36703d418595a47299088d5f7081d24547cc93ac445e4406ba3350b4c7d921a19bf6eb830386f23b7419c19968ae6a8b801d56a8b616843f41d7a14aa8b48a3a7549cb25f91cbe16bf4e8cc1c3928afce289fbf3891c10e3de8f5157c6523af71d5ea32fb14a00d1b3ed6546ceb515c0652171f97efc9f07e493d7cf2b90ff4ff32fe906d4695cb27da5c505d0f30ce50d2b7006a4f7490c44b959663cd23a3b1eadc2d2bc34eca8031474f3790137bbd9585ab386502153ba3c8dc27e7314226d201de0966ec277f67bb6707257284885526ec3b1007f0cdfb7cdfa26d418b396af6667174621bfb3fb62b44a63ced32d591e477996581bef111af87f79a56d23bdc24aa8f70a15318c27d9e6bd0ec87c000217f88d3bda5449272fd5804bcab488cbd3b06ce64b77893f9154f0533e0388e9bf89406cab037a6698c8a97170919b49c99ab04746a196466e4927afa49413dc0e75c0bcff935676a27b1d0b21b5b72336a075c4e518a053d66e210f957420756a6fc5a3ccd603c00481c4e3017305731e1c1b3f21dcecc89e2b7f3ad48198263d0b3c41acd65a879b0e08c2defa57365f778fa539be998fdcb3e71b00318795c3173695014dbf44b31322ba18f581388f57a01f444896e2ccba15d10197fb4b92ebf88a30600c4de35cd5d95fc84268479cd00bbcaea2069e8d628a497a2db2f3fd13b4f3065e138601bc9d3293fc2ab76e69ad43820a8567551c10f1b8bd95deb63f6faaafd03d14188c8876e1a11b12d112f0952ee0646f06ef53b4f5dc7883b65828e08d9fc205502e14603e8b443a1a50b7c76fbc780eb3259513edb6dd031e9eddcdcc67f5b87ba42700c4961ae4862e6ca7fb666fe80c436d3317dc5a761a4913364676739014b0cf6853871cfb26cdcf04c880e57df20e5a63a15b5e0e293eb88953a392262fcc478413f57dabfbe45e33f3c8c09b9758578020c83cc580fff6a11cb3fbab00ed7a0a9d5730060b382759354b1548d366659b5d499a6f995515c42093fdc858b5006c58a80285004c648071de196466ed4c18c428926626c980c30c5f998ef72e53a05dce9a24874c5cdb7866587ef5c65f0b0635213e9a4130dc7acddd6febfd0c760112ead253b9c817292569a6db8dcdc7e907b11691dac626093f998c4442b8d7f55f8e3274b49dffe35a3895800568ecd1f6a3acff582d3dbfad7e315af69b204ce906f7e5d2c76a7a939c7aba20681678de9ca63163971ff46b21eafaa0844e5c62c84d58e9322edc4418967a0b2f4bb68d19383054ef11620778594623f8b0abfea055e3c9384ba15b6a810c2e92b8586fb77bf469412435ab40dd66cfbe958106afef14757caba6e0940d353fe3582a7483422a30bcaa35a9edfdbff8280f6adc10ba940b77daf81b3a6202a7c8893ff04dc0b7e621f4822bd96f08e378840a6a1008b0f64b0b9c2daf75f8a783deba984d3892bf65e99c02ab2f10eec030f74469ca2bc66703a177891aa9d78785f0b159a6d24b97766b806772f188d141f56a50a5d95ff8dde15ae6c2e43e430ca6323ec8384adab59c7c13ab79b3a75e1cefc6d62e98746cc0b35d8889bce1ab448508319e85c55fd0b86a8bcee1c27e5912dee8ae70380adc787b20a7ed4d851c62767ffee4fddc68020be50f2a745e7b2bdf8fc787ff0afbb2984a6828fdde02da107691467a3fc5264e17d1e44cfd9e7f0e4612a2049156f87bb0fde500b3bc2c331e05e0f9b72bae5cfeb27aac51a34ec72bff597700803446e862bc71dbdb2ef4cbbf092bb98c8a0c85036aa2626e84cd2aa596c60c36b98263fc2d9ffc75e93a94bda39f8f46b3bba37c3572e675be8c6ac8f29282e5002dfd857b42715c40eca3f6a01078c4e376cbdf2803bea3067f9232678e696fa03c6e00b552058ae5ffc0b1137f8470a39d0bad15fc63e1962e45b178e8ee73b6e9eab2b442634fbeed3056850a9e2e3cf13d46d5edca466c5ca784311d5b8f6001a7ccb0864edea23c8c5c3c886ed58b64f3d11c07465656b1ae6d5f9d66241799fd27030b0779b1bdc1e4ddfc9c546208de35cffa57a5325c758f9f80ea4d7c06008580a3958410f38606953061938942dcccf8eb748b6d16123c5361a3dd3996b19b8a605d437b70596fc8a2162f94510b5508df825f07f3061033f5813134d9e722952e0cc546cb189349b6bfce54df36711b66e480782e30f46d2a0a6d4f10b623c51aed726514efa70d303c53c8be54bfc1dd8acb76e0529aaefd2dc1775a5cc07f16af88680c40037d362e74207d0114b0556a57e6c5d2ccb4e7d99426078b4d260df66b2c8b02ce0349cf9be23acf2687b50e78f7e6422477b87f9ed1f63b55a7857c508b2adf6aac32e2818322ac12503edbaccac3834f7fb65314cfd183fd7262e459ad68668ad40d0005f0f99d46316b8f2448f1e38011c8bbb2ed3ebe96706bea3629143ce484ebc6756873ef4b1e436a61497e1756522d7530cc143ad7aaf2b5b6cda40bcd97117daf5f7077c6dccf63e330733a05f782e59c5e95b251755454963322eb0ed2446db1232144113abdaec6c0e7df67d4d4cf540564b898fb865fdcd0e3972afff8ac7c0ad6dbef9ce053e5e01fc80dd044351f5c0cf926a53036758f2a03d9561c95874ec698685d97568b137fc706bdd9cb7d63c225aa88a28d120cbcd52411dd144041f2413a3ae274e5111233fe3237fcf0ca8b711291319fe64067492bf87ac8395687a2590fe8a4baf463af8613ce15553a64863e11d3289f80e7ca37a01c95cc9221d26a93210a379c9aab597374417cf63051d5a945ad6f3b269523ab30250244508f2f1459bfc72250882b79c3e649d2a7faf898b915c82548a89de799f8ede390a2448f054007eae584964a7697a52cd9034778db678ae018e47d08effde2a1721c340ebef76f191ffc2211dea913b73fc8fabd74823c6c0d33a7fb0d6f7444efd03a6b5e37dc0ab8de7fab309a642c72ec1972054de15fcddd201c80b9af14b3a555af753dbd117e86fe7f5600c86571d70877321d68a8bd20b76d0c71c91897c142b54460c6982d18547f2a95f0a979368380a5a4111455cd830e36a8ce399cf578b0a54a1581f89fc1fd683503c316b83b0878356c42b7a4f01c3a85963fda197500d1f21f1646c8915800985b1cca2b8ed9e0331cc4db8ca8953810bb76d83e622fd33f03efd5a338f6f1a56d77480caec4ff1038619f78bd86c8e0d5a1272c132376c7d781c8de4d01d0948890425559131755f4d397d37b8fdaa0254b57a804c4ee77b10cc5898ab0c93f808576535deb43a73750af2d63",
+ "spend_index": [
+ 0,
+ 1,
+ 3610166742,
+ 4294967295
+ ],
+ "result": [
+ "a581267570b10d637e1d7b4a663f015e9a74bbfdeab72581ff16e76d8b8c27ff",
+ "a43d65c972980ad3ab70db2189a1ecc389c33052c22e96002b61be966c644832",
+ "8d4b10716dd0b940ae288cb38754cf4ad52c821a5be584182cb1fb3a24b747b3",
+ "bbd663277ecd2f4b7e3aab477f2f440b2b4469184d216dc99a94e71f549b4896"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 9,
+ "Witness": false,
+ "Version": 1429618895,
+ "scriptSigs": false
+ },
+ "hex_tx": "cf4036550a1e69583e0000000000000000000000000000000000000000000000000000000053b3ac7c00784308065011639b00000000000000000000000000000000000000000000000000000000231e523800461c627a3e23edf6000000000000000000000000000000000000000000000000000000004c20eb8600fcf2862389a6d9b8000000000000000000000000000000000000000000000000000000007e59aca10059e33d001536c90f00000000000000000000000000000000000000000000000000000000e843c21100cf7d3ad6a01d60d900000000000000000000000000000000000000000000000000000000558d6ac900e06be76a4fa0a26e00000000000000000000000000000000000000000000000000000000530c17a20093edfcdca778c1dd00000000000000000000000000000000000000000000000000000000329aa83b00167d5bf0effecc20000000000000000000000000000000000000000000000000000000003f779f7600c27f2f4be65470c5000000000000000000000000000000000000000000000000000000001d5b9e7e0032eda9a109ef86a95031d0431ac8c79237de2fac720028f16a99c45ecedc6cbafede718180e04c7307479ac3f2f8daad7f99fa08476b49be2c2cf0f455f59ec467f3dbee8cd7443e5bcca8fcad104b67193dbaf24506a3b63207264fcd3ecf49609ffe946b349e529aa8935fbbb34ee04153b044c0b6038d41750dab1a558dd73c833419bf138a08684202495b94182f7b2abdf139bacb177288d20fd574be6eee5dbb2feb90a788e4c7a09b6f50f0aa37ba5439b2b15d0b39d41bf80884bbd943bb60f2bad7a6410a80bd9712e3e20c2fcab17daaf3332cff0e48066f56c87b47280b1119719d8bc26ad2cca7bbbb6609916225e9523e4d6515d826c528cda7d41d46719006b86c448c0be850874ab292a534ad431aef35ffbbaa1f6568b284c003307ada573241f08af8deb6ee1836f5b26fc2934852fb8f1c50c94dcea454299c57d91bc303b22386975f951a5c3181f5c631b11d446d5bedca67e4f5d135cb3fb95d88785eec8edaa5258d4ac6cab78e8e0c2245f4a4dfc393044cf0677832f752042ce6412092700a8367bb83b3ee55a96ef59b9e3eb80131db57ee43d04d6dca1928a958d82a72ab42e0cc74c880161aafe35571887d42bb41b807651bc9115b8a7266b22ce3655962571f05a794528b47f479023e513c9ff51dfc19302a8815774c38a294aa883477bc8ac5672564ee530cfdbfd464ee849750e977baa3d23bfcdae91ee718a51ab671dc195d9180d506b8562167c9478c6b2ffdb0b3984c3ff19f785a10903d7489fce9de8f3b5ae99d2fa7362510154aa066c30d6356386fcf44d985c9a13274036084d743e3143f95f50b5331798f669f9c86e7ed96840d4c881bcc2dcd9b4aa689f61c196f9873ee3c814b00da14edf52b422173c8f7676c1c89763eff57daa598271a24392a2c87ac24abf4ecfd00190952f275499159640c3faf1dc6ffdbdbf3e19d50f132a8cc51fd16a669d8f44b88eb3df1d181513059cd12be4f1c78ff1d4c39ab6fd8be05e9897b33489f1ac730ca61277f2c88e0da172bb35987edca8d4bb8310741afce8dde16fa2092738162561724fbf8e848c31752a86620cc50dba829ccd5698c351fa760dec06b787ae62c45a984252851a97627bdae70c378be540ca590c4947811668128ee312b480a95250807e8bbf26492e7d6517eb0c866cf24d879c83ffa01e96b7bef2be2a1255ad93811b9223ef2699dba5e28870258d43a7d3f2054b96364d50e200c9d2abaa6195593ad62d983e0f0a2d1d9a134bf185cb7808e6680a69091860268803d598ad1b14d1ea096ec63b347fc4f0d026afd93b674e943f44b286bcb5645ebc6ade6c1d0e1665efd0106fc781d2e0d4ca62c3214c04ad0fbf7d5cb84dc4c67d47365911de440ae9ac26ac463eb3f1d940bb9f3e4bc88af8fffb50af763a3887f5b06d4465aa480cd58bf6bd2d246a1fdcd371ecafad2aa8a24b15a0a713d52dbaaefbd984f64c85d6fbf6d936a646bf954f8af97d82893dbc4792ff2d916bf9a68ded2e1d749631ec9355ca968c6c22fc8c2003e9591a84b73be95d8ccb7c17d57898da59b3b5c6e4551ebc17527c352a4066c1ca758285db0a187aa5f6b9cd2a41f53ec1f2cd0774761d869d8bc475dbaa93eb173dd5d2a45d8126cdd4096309576faad4a7b8082500547c1ff8a0e001c0e32cba79d8ddf227c7822aad8d6562a8aecc396578e6fb2308df5096f27622f2628a3fcc8ab76b79ec509138f467581802eadc736690c050a44ba18b0dded1dc036b9883431c824b75d56f9f969de7f28e2bc40cce434303dd8853de7200c633254a7ac883f2ead10fdf386f951b4fd7de6e95374a049706bec917df236028714452552d0b68f2ac3e9551b2b8b40e2f4da0322f8d10a002cd9c686bfe8ba1e2b1b9d702f089f238432a10d7873294a4a299159a3238fb1146910947758d581d37efcb209d1ce30ba921048ab2c988d975f8e62aa513b67512d7e0ab1dfbdd64cb2ef3eb2f3a2a6880ab231db4ff3422b08e64dfcce75a8b66bdf82b5116e4567a8842e91aad3a23a27319b50aae13d6bf67d3c38252ec8e3035c90b6d5bcd5a8e771dd5163c2e8c409a02c1c1191d024b0df3c84d6824d8eb9888dd9dce0783c75483de2ec4a54c30116e1252e960e7cef4468bda28986d27611fc7484f2be55ca461ac1a742898f68f83d4b1d98abb4e45598f9df9065cffd0f3e1b41435591fae56bcfc9a9f88193ea6e74a403ea62ac87459a17e20bc9279a782121162dac972c44bb3637b4c44780c8f43ee51e23c50eff69f4d663af5fdc8e9d2d83542c2136f76c337a031289a40c40d61218d48144756cf728b3666a3c6ce35a74583a4ae814caf9ed0dc8360b02c141a887351baf1a498f2c1e342730484d8f316a7a1f5fa0242538c67e52e8f7be2b27b56527be0c043e9ad1f704c822c28d259a11a0899d950ecc24342f72189f226ac725d568fa016303287e44e499dff0bfe46ff372df241761d90a0d35d54523d31d4a1b5ab842299f87027d9bb612812623bb877801c96e72598d47e449a98806da0a8cebda4aa4ee671b19dd1501eca920b49f1a00f9d91759d5d499d66fac46c1d89b93086e267a54338d9421987f51d690cc273fceb1c621a1ff89c73bd27f88eb6dc6c8f1",
+ "spend_index": [
+ 0,
+ 1,
+ 3616295423,
+ 4294967295
+ ],
+ "result": [
+ "edaea6235b2a50a95096eccf977cd9c6fdee4067c395e52623117f856ba78316",
+ "1c4306f65455dea78cc6792f876c3c3dda28a8c4e58cd44cfdbf83ddf15eaeb1",
+ "4f001066595dee1ffb13aed2e36921dde1f9fb7f509c4182d9678ad6a08b4334",
+ "cae1e737e67d7f80941b39a0e178bad2d0748c8823596d765b7f3450b019210e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 4,
+ "Witness": false,
+ "Version": 228922200,
+ "scriptSigs": true
+ },
+ "hex_tx": "5813a50d095dd52a8c000000000000000000000000000000000000000000000000000000003f68f1b9fd1301fdd5c373efd2d10c9c119c2c6ba1cb5d7338fe6cb30134c56e74ab2840685015dcda105d2f6741a967b13b4f8b18ae5aa566d9f2b96162ce31d1db10e7eecfd2eafd84af25bffb7185925ee8a844a79759ea400783c32abbbddda7a2db2863c1487237ee612147b4ca963bcf386da21d25504770292640a4d630234c79f002bf74d4d37c84c98ea96e4f02f1a3073617636380a34839e83c28982048d29fd0ec11328e1127baff539546f49372e36602695179361fe5d8fa358fed0336aad6a9f9912762fd13b276bf9bb39e5db98a95ecaaec84c18ac52b1331041742ca0d2390c094583311ac565d6383b80dd356b6e3474c76fb41b00b4be83b8accb7417c97256c13ab7c6316a87895e5b8e23dc7e1d5fb81937f85c0308fea00000000000000000000000000000000000000000000000000000000a349c5c529e3b39bb861b27cb85e78c80efbbda5bd41bc7b73245593b76c3ca8cb3ce09825b04010a48efdba5e682f350a76dc61c74b0000000000000000000000000000000000000000000000000000000077521299d1c9a0c7df8c9ae9b0bcf4f64ca1dbf93f769c755b87d72d182fd71da39dbc7c729b23d97f847aa67b046080c9d127b78b99500e5f5aec94abfe8f8cb31734481d30b24287563b8a4758779c8a5fdfc238c5e13530496861355c3d0e0eee0b6981c7ba365a5996d5c79584afe557b2d8c9acbf2e3a1fea1b18ae3f700b5e224ec7775a327116082f6133aadb47645d91dc994ef56393c7d7cacb54e8836d47a314bc8ad81778b1d16662df20c06f709451a4beade694f4ab59b80401890e4c8f8c07795ecf43c6b8e6024bed8824625cefeb15de1965ca64d685000000000000000000000000000000000000000000000000000000004da36e9800b58147fa27f3cdc50000000000000000000000000000000000000000000000000000000043785f350f5e92b8e86564a85247243c37e596200b86c7a059be1aef0000000000000000000000000000000000000000000000000000000003994ec08bc7f6a101e341758c55e5f3a508b6914268a8d97f73e53019048c5a243deed6de204f5675345609dd38b14831eb4f28212ff3171e47d09a54e31ada8c1575c2858f85b18e4c23e0282f1c9130e0bd3fc2dcd42f8642e7333a2589afdeebe42fd11c734dbc07744045b667672843eee4725871dd2e46ec90e3f238178f295edc4e8e0ffb4b342077b88601ccd133ff558bdf313500000000000000000000000000000000000000000000000000000000575e61e2fd340176fc7b02906571efc17bb6adc866e15706dab6b26b57ffa1b78843b585f9d66313ea5c2e46a74eb5edd59fe7795530ee0d98e1635af12a53ba24b5ae140246b746c14bce965a0878a77ec6e77d23d8b57d3ab5ae94733923fd5d75cb5d071f40e5aba7103a120c4f0cbd6acf326a51cbd45195165320d12ad82e240603613c8a1662a116134bfb89d60b2c30f58f044684636e96ad71c48eb95a0252a33853a0ca17d9e20c795ba7968ae6d89f56a9613f5a127edc77a453c4d078c146df95678a2df8d0d00e0e174754828390d8147b84a990147956a16becc9ae4c113a40f7ce62d33ffb31691b87eb5b47a4f48c367affc66a6c88a23a85813f6df5267ef6c4e4d507fd8f3555d9d03e30df1f36f0e970d58d9597652b7730e6d4ded090832d8033e2009bec58d40e179717414074635a58795afc83f451d6b01800000000000000000000000000000000000000000000000000000000ee8aad2efd140188125d5720261c8bde23eca7bbc6c90fbf666b33d2fef90bbf94aa17063904db0dd71981dcb9116cdbdca1b916155fe14ce3c9959e2af9e8a4348f4921b7a220f13c4ca6e7937e0e2991e560277f9930357d86f4ec7087315014fb90aab1fe45ca17ba23f52e52cb1cc5ccce2f5947d1b89eb5682c968fe4ada1f171839e91612a4730915dae8f907bb4f5ac16e030cb67b01c2d67175768800457967731164de2dba58553e5ce7cd6d700bdab8ad5a72f41bf89e42a82618308257e916191034012c70bf2350b731b4686d6a9a8bbf6224013a2b2e17fda8a55c560c18493555f83922a55e4aa9e847e2fe4de1824825f89094f2f2355b4ce819a8075b46a808aa11edee884ab155df2b5f21cccf8b991896de584f7db50156df95300000000000000000000000000000000000000000000000000000000e9d74bb2228f4e510fba6128202c9cb7bdf967ca6a28926ca367f1fc37f3c9984bb3311f8fb50c22bc4fac0412b090b5d4667d73c81e341b829b73715386b56933dc5938bfd028a699df860e772048285343b590d8a5589e0cf8e1b0a3d70ef7dcd59cefaaec33719cf82ba2ac1874dec67a609f572ed71c6c5cedfc2bb692270fa55a928279aa19d4596283f928c06b2ffafc9139d11d130bc8edc304590718e1c7b847f7f0d91eda897d1843c5dc119b75f7376497dd644e0716aefe4e8c8a0fd760c3e51c79a904d7c15ad458cd7c8b9871fb041072d589f1d6ffdce7d204c0f8003774d65b5b87c62916c911ccc93d5dfa5efa66ec894eda669245785c2f9f26de3139c8efd70dd8fc23afd84195e2a8d9939ff747be802e388639786862881ff9f649c058eaa43d59562a71e991e726134a8cb080de0fc8fd9f07d2b64ede78483f462f15538791f907ed941951cf5c503e64924812be59a67ab83b3b2b71167d005702dd1697fe4b3d8659e704e2c7187b851c2b3ac92288dc905c6154f50bf831c20d09bab034a533ee8e622053da5492d2e9567b5958a3b0e22c2505b187bdcbb7822b51dbf2228a9a093fabd7569fc741e554b6107acca2c9b11f9423f561c76866efc95b5575c3af40c67cb1e0d6a66052c87ed3b1651e757efb03bfcd7949fda19443fbe79268748a5936387bfe77db547dde320ea67bac879a2d67e329a8a2763754efd276f70195969d854f26f198f6ff192195ffef5dfc2d9126a68698ef702a5d5e300e7885823760209178671b16ebe4443b3628cf6610f4c4debfe6a10ce2cf1a62dd8e636a3c7da29f7cd8da80083e835d0cbb796846e8745426583425bb2083bb7ad6078397a13e776dff6e4f3cc8949da9b06a83f5228f2cd2b90798058a2636243d7c353d7d60c7cb3fa6bd5e1909e811e25b83715ff21bef61656300c871d91cb50a3d82be69648785cd094ca70ce8766b37f304afd5fe848df15e60f4f3e116fc2dad8b106dd04d8c84c73fc6c51399b6f8baa876e5d0586ab574afe9c573f9b0082641847fa21aa5f0a5cf8389874db7a0752b2d15418c1060a6fb5a72bfa3800bbbbc96473c99b6b3b63d27892da7a5412e15521ac3e26f84b127d82889e152fe5ef50b2ca13d5a0ce805a0f18361aa823c25b7e7aa4b678d59cad74b68007db7ea25e8224ea07b7db0f72d96607805d0239dea20b7e8ef059275f56c2aa92f6b118f159123f76a",
+ "spend_index": [
+ 0,
+ 1,
+ 708469068,
+ 4294967295
+ ],
+ "result": [
+ "7449c7c0e0957bf2329c95151c03eec76ff335d8df4eea3ce509026112f28cf7",
+ "170aceb5fed624928b1ec575e5456b1988a871de4640540bc21dbcc1d89b4879",
+ "5eb990a684b48e5fc6cc68aaa7689a53c193b23aa4a57aea52e5087797aef82f",
+ "ce5d9a1692d85326a4413a9b10d0019fb33b1bd664eb7cd9edde3907728cd105"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 7,
+ "Witness": false,
+ "Version": 1849375622,
+ "scriptSigs": false
+ },
+ "hex_tx": "863b3b6e0a1f4e0d7f00000000000000000000000000000000000000000000000000000000cea0a5440066796a3e5d5443f30000000000000000000000000000000000000000000000000000000022779f8400a4ff4c64dfc26ae50000000000000000000000000000000000000000000000000000000017de040100c67c6b7c5c76b2f9000000000000000000000000000000000000000000000000000000003140c06a0087e9bd04201b2092000000000000000000000000000000000000000000000000000000002f4cbded005f9c296bc4afa64f00000000000000000000000000000000000000000000000000000000d32fb30700827eb4860f20b231000000000000000000000000000000000000000000000000000000001996ea7100ac03a6dd337ed31600000000000000000000000000000000000000000000000000000000ec7705cf003fb2d6284bdc38b90000000000000000000000000000000000000000000000000000000017cd1c8500136e3e1a295f06040000000000000000000000000000000000000000000000000000000015f4d5890053381e2b070564ab6e710bdb43c83bf70f7051c2ef7598429146fa2fcb43cec86845c473d5862bfb49ecefdc0cbdf659231669f9aaa562ddacc88743a941e076577a5da974311b3b9687808f9d3812c280e1ede2c6277d3eb3559c6cab90410ef03f2b7abd1ba7cf3da046b8195a0b318fb86f965aa087edbcb2b27b9b187a33b3eebe4647921d1aeb466eba0fdae322d9b23861f6c1d68086377a2a60c92ef33b44063499a1039d02a617f6876435140cccb9c6042d112c6b49b718076b8feae65e665e28ace8ac8941917eb1612a71042d5cb6400f748590fd43424309c8bf3bd45d52f9106406435cfb3e0a2710964cbbfee48b49b25baf0301477bd4244bd6ccce535609ecc6dd12890a63251beb8e092fdd05149322558a2a906b990c5d674c1be436002bb846cbd1a6ab3f8b2f9ee3dccbe0256b676f7cc434cde676ef4aa97850e1ea3fa08f36addc89888fd59500d4c2efe01bf1487723356888486544021057e129432cf3a8b81145baffb2b6b7c59fee655ef0f43269912dedd8595320cf6b0daeb70001dc872343747b50927d61afc5e16407f5fe5e52623b9a22407e0c79fe35ba1ef7cacb457b7e66c838ae3ee3e45a9ccd189b49dc348c9d2ac453fc2ecd4d414848a59ee555ae0461d46aed2078803b7224d380f6254d7e591725db9a5b314562055ef35a7b3c4d791c2d4ee8b60426e4b8b6c413e336f8579e3aa157da4740ff73f935bfad7d9f970f5d88a6f06eee5b6b60bfec3391ebb41ac1f3736123784442a22bd5a15e1d3a61450c3e44e943175c56969346a71cddea0790c8b4e8b51f5e5fc72c6f24dd62ce316e15d51310e1aaed287c4644cd5aff7b8dc20bdcdca63adeddf63ce06b2a213e7f8f867fa5187f50573dadd39b32c8dbd7089b332775873a17d365179c5e5f7aa7f5d4944df978fff7146ef325817dc949933f907ccdc5fd0710fa9337412aa78b9a51e56607b59da97721e128a60c692e021d9659d732eb4f560ddeeafde52301c96f829a9278cf124f0b3492878e49b7c3836bf2fa41e237055c2d1fdbcdd4e4b5e617968e3ae7c48367cd4e6ad75c37b62f6a7a54631aa96ac03bc6264b2157019852dd42785e8c555390e70838e01f87ab86119bde43b60519feb7504c8c1c4b5e643721f80cc712a6efb4df43d64194bb7e6ea8567dcdece0e660c179c8f36ce2e56703f63e16e052c1b7ecb830baf481951510abd5a1494dd6a70118316af13f9b43d8b665546b9fc39c27236396e6cad4677d05b3c7c950da6f3b5c3406e6dc98157c78e1d28f9dc3a8ef12276c173893f0000273acf40e3d89ee11cc018468741154351d436c1da162e9f83577c894fdec48b12c670d12f92ea5f7809ff35bbab7b2370c0ca7524b0f9d01e556d9d0d6f8ca5aa8f044bb82f0362903daf0b56fbc1828d93d18c99f1454f6cd67e8b2e6938a78e0889f67c28bbc8cfa32201e1a3698baedbe3580b75bb0fb0ec87bc284ae0193da658f8a62fc1b695a682279a01e4f3591b0841db404dae69a374cdcb1292cd3f6cf5c30c5ff9ffa13b601d679b856ef86e370171955228c50b5d15e402c078a1b1a04c178caafd7ad885e6779e0c29787860ed55ee6639e8320567329a135b3089ee783b1cfb5252e2bab26a7c3bf40cbe6f7dc856f291d466c14ad7c8dccbea54047dced27aab3cf9369271deb65a3e7fa05a988908de7b93cb9320c2b31a18ed5332722f91be01d3d72db14ceaf8f4f4e8f5fb3501b5522b84f25f025b505fec29617fb575aebe803c8a12e593a9be7165776f717d1e7e5de89a8e79185d1bd691c578e0dfbae04c7d4c7f47267ae773b2de321b9baaebaa23ce5f1f1b76e6de607541cf7dcc00b694aab4ee5ff65d32390b08ed7eefbb9648f4e3c805daada431d6c2ae6bff4ad6920901808648d8a6796e08c0a3db9c2ab0ca99d8ceaa07dd59e2044484d4b4ff9d687e327f8e5f297963325d2917fc58033efb6d1f66339fde905f347a46c908b0a19eb1318b76b2ece20467ec1d32bedceeb7dfaec395bd5b39b34fb7e3d46a69252dbc446754e65c9cd8cbdc1",
+ "spend_index": [
+ 0,
+ 1,
+ 3358500723,
+ 4294967295
+ ],
+ "result": [
+ "a67afbba0065b5896504b0f2e660aed9c45030de3392b04ea3b6eacf74f25c6a",
+ "0c885fbc0ebda0ac9654aa951a9fe010e8b78d95da3d4b98972f0222d5f2b4d6",
+ "00776d3c8512073f11d54616b089e5732369bbd5b4935d9a29f3cc80089871a9",
+ "4e601cc58d1c96b29d4b0306ae89bc29a01a40fa69128aa480bb517952f3af1f"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 7,
+ "Outputs": 2,
+ "Witness": false,
+ "Version": 1798237959,
+ "scriptSigs": true
+ },
+ "hex_tx": "07ef2e6b075ed1430500000000000000000000000000000000000000000000000000000000ff78f49d00cf1131160c6c8a7f0000000000000000000000000000000000000000000000000000000034a318d6d91848af4d612ecf9cfaa2471fdcb5627bfadbdab545df89daef1f672d2814e46b6d15b5ae5b5e56dbe294424e1d8f2c28894ef417e41ae27f9573d4303689f54a333d04b04131ca9f3825fb365399229a0605e361e694c11cb701c2c71ccf5bec7cea486e09f2b710096f90bf5cfa4ef67fa991397cde17e356649f24be45c377294329e9a0f1539fcf230f5bdb8d9a128f9899d418af7889e475e64bb145b472d60e6a6b7fac0b4dbedf3a977df7948ffec09b41397f4cbb8046f27a4dc6ed090aec2c4ebbfe5876ed54cf3d016440fa9597c7f635a94d7cc7945d4bb8359c6d87000000000000000000000000000000000000000000000000000000001fc9da2dfdae014c120bf9bc218f7be58b7067cd4614596f7d58d1ab928fba5b0a21a3e81d8db1f8c89f8db25a72de162b85c34e7dc66923a2926cf8a538d44e6d2172366e619788448f071f201fae4184f990940ed2c51fe7a31b9dad6524ffa22d176b77a4f7e123e575baabaa35ffd4202ea4ef3644c7dc653c970a7f66c1d33a6a18d1b1a01e70b1649276f06cb5b46b2420605926ae5d7601cdbac978301a2d7909ddd43170786b3264fe45f92b89f9870364364aa2963ac5aca174cb652ed2c10b96817359c05ed283cd841b0865d53fe6d8230738f68de6c4f03fb24275d6007fbdfd591305066d1f310ddbc229cab9f7b2c51b850529f56e50a8762feb20787833399cb3c81eb2c917e016ef6476c59cc82f5be77213acd94a9d6465f5d51af9175ca29fe63b323b3febcdd43c2cf6a2129596a9dc8834326a40ac2476cfa29a7c76a0c5ed3c340ed9b531e54ba5bce4fe020216f45cc96675eb1c2790968441b8929c9430b3c56e42871824f4933d221f26ba67c3088bca40be87b86f95508a0f3861621576213069384d58535d8ce783ccbe22e2a9424a74a1f1cac6b4de29aefc8d7785818be5fc302704e8a63c08f0704a213fe8656aa900000000000000000000000000000000000000000000000000000000a7033100fd9e01401bdaeccd7ff2c040bfdb44d1656d0d54b665b2403e59e4912a8c04d60126407bd04224bb6b2fa327496d639c6d788e75e79a51967a27580eb355602f8c73f4a366aa23a5032c5c5f9777669917707eca2406ee9fea402fd0d5b64bf4218ddcdcfd010a6bb00f13c6ce09a05fdec05602636649f3dc4b6bc2b62eb506b3bfdb1e34060892409961e6dcb6263f085fb45af54113f04972eb8b1150d7ada2b6ce814f3e8d5eb5cfb112ef59813bca080496749a3a9ed0d14110acd032381162e13b7fa5fef0d903a90e23f5eb4cac9256f334bfc3fa2508657ad1b247e8f61aabed24f067e90cb64d369e3bd7c637f854945d58a547aeeae1b08bc3765ea8efa65239c7d5f1b2fca37c25a952de38c97224c8c9dd6073fd5c513f3cc69d5b3502855564ffd4340f8d35c763621b0a6f926b9f0f97eeae5f02343192832de354dfaa9e2d78fa6d87bce125df54d15c2b14c52df5b531b33e9fc793451527b4f4a35df5951f0fbc6abbb994871765f8c494fe6d843394bcd54c0f66f172716b7b54505c84d717f129319fd201d51854c191027df094ab07eb6fb6675423a2701f0d6e75c91ff51400000000000000000000000000000000000000000000000000000000bb3ce8dbfd46018d139bc3a62dfceda3d4b32db06baf6edeb1c6121f9a292486a92c060ee0aa0b8858ca8e87c083f3a425bfde773da3e3b639fe454b5f51cbc0fe03dede14118337872031513415ec11804593f83760a290a90e423bca0b99a127f8e6b632700ec71626b1db14ff277d897c7a9a5778edb073e3a3adc45fa91e09ee4ea17e01bcc4cd081679ed54cecdea2dfa1058ed5c948d1c38c4f92e7cacceeb728692bb93a65d3ec0e4f0608f23ba3190d0873667f31364f24409d0b6ff4f61cd20c4126acdb0e5acfcd7fcc1359a30993da1d7c8fac52448b43736b764c12c1684f62ce020dbc325d70bce63fcfb8a3348f29ef1358e04aa4a5076bfaeadfd8646f786ab872617e8259cdbc61f1ac5ffbde8700e10541884ab7ea980d0ba83f53e2c6d97cec6486a8c2d2d8d19056fbeb987220d8e97f25ea08d5ecf0f1cc4d844a48eec48f6058958585e2f04abcb39155700000000000000000000000000000000000000000000000000000000a628b2b8fd3c018097865fcd8fe6470455940a4d67fead20a5a785401ac7c866a95ef9a3772957fbc9365db696d03ad84e51b63cd418f3a08159dc76c7e2859b815429d50cabba3329bf3eb1ae70d3f610328aa7855c9d04a10e79ac916e5789d816c39af09bab264be69819f83b487870ddc2b7378ce083c6a6f925ddb27d4b19b5c693b8da8262e1e392dba31e586f5af636873a3c776e9d454f4d623bc5d6e7567343fbd8be6ddbea50bd1e6d10bc40228d779174789cd26272dbd4b27233d75b32bd1c7bcca3c56f014b9329d3e1edd7001a793f4fd8d0d1b4e78b413fdfe5cf56e992c2d2f02ac71d261c9c31940041d4585d2b0188fbd77250a13c26f3ec0325f245a7744733958eec2cecfb9d9afed1e2a58e4bec4840030e9f3e0c92aeef1f4938c955b46ad14704c2b6a2741cf0606c5d4d0a887db0d355efd681184c37c9f35fdf95ce70f3d4000000000000000000000000000000000000000000000000000000002b11a978fdae01d84f6fa0f47c77d269733927b97b495afe13bd0736173bc108d5a536457cd4393d740d02c208981e9e34805e1ae9799f7fcc970b994e3f2168ae4076c9ee0cadd49cd01e67e3eaf614708413e8e6747a7259553488f005792d3fbbe2cc9e7a4921a4e88739c0cf0c48b322c14daa8a62f7fe1d767ed98ef950dcbfc8e6d3b2912bacd52256e8ee0eb8feb9654e150cdcc63b37501738fa74b8afde3212f0454e274e0c70bfe05db3e5b66fb0a37898339cf842f4069c2b15310e03c7247f0114098a2abd6b3a7b95f74c0d66e5183ef9dcea6cbc76ab811e85a3927e9f1fba24a3edf1733c299ac3e3751d8bef340be63d2bc99a37de7ae4c93473825a8a0e9ccd34add14342fa49b2a4339d82adad9389cdf32914df4df313ef940392eca3dbb26851cc7f633d4c91c18255892d461f96bf3ad9dc20b87782d124b8e9010183a1d662ea87c6390558e30f327e75cb7c02f09cb8ad1b29603fa67fd176b0dbdd37d89898c15d94151d6001ca7467ef8651438fb8d5b69ce346a4a3a9ccc006c55d69fbd80a0956911a5d353858d5d20e161bd2467fc524a70a0121ffe69d6879c3433163b4b268bc144179eaf2c4483a2ac702ff27ef589383cb35c860617e20afba9d9fde90927fce0a9febcad50562c77535a516f0fc46312e7e44b78c04510449c8775834336be170ac6035634ce9bc3fa426caa1a1e21585d5377244d6c0f5b4bce9554359c231ea2d2a44c6371f0030ab2ddde40264ed65b630bb26ea0fa44e22f83347b12f34ddc757476a15809bca3264973795c1ca85c9efbb4ab971b46f283ccd3b31bbbba467d9293ff542a9c047036f63f7999ade74e15afd120060d814ba66d5dd324b5e9840d9c5aa82f2d92c50aaedde60ecfb197d89f803b43f951642ef440a4ce557c119c8b0b3b31396ec5eb2eab3b68bfcb8d87d514e2fa9d99f55bf73b6de4a2c0ae686ac120ecd351950f301d788e9d05a9be5316fb0347de8f8627aeb14222479d9c0935682cb19433ae087e6fa55586b71fec9de2fb3d7fbee0fca4ba677df4f5a058d881e4883956f7e2c8c9a7ff843153d495ce0508d9e86871a75ac58760c9f6ab2ac11d638798eccb3156d869060c00808e8d589a1ecbcf54c6ce2aa41d927a337b4bdb357bcce9262113256a4209f65cd612f679edcd92024eaae80075d703a22027f77627ce71d58210ce6",
+ "spend_index": [
+ 0,
+ 1,
+ 2916844456,
+ 4294967295
+ ],
+ "result": [
+ "283cb2047c37309e829655648b28267b033c1087d81aead63e6ff2d26caf9e8c",
+ "7010b42b49bdf5cca62e1f8f49362e68f9b88f18f762620cdd8456154b163944",
+ "02459f32cf304406ee4b0de8526b878e6f8d2106be67ef4e34f8093b3d9f958e",
+ "e813f4d71c4648851297b59fbd8703ce205c8c1bfea7665e221d94b32525c2f5"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 8,
+ "Outputs": 8,
+ "Witness": false,
+ "Version": 728859774,
+ "scriptSigs": false
+ },
+ "hex_tx": "7e84712b085a8b7c720000000000000000000000000000000000000000000000000000000007339cab0076f4ea875264aae700000000000000000000000000000000000000000000000000000000e03461fe006a66435164c792eb000000000000000000000000000000000000000000000000000000004d3a4d3400183a7cce719da3c700000000000000000000000000000000000000000000000000000000162a98f500813c238d4b9b642f000000000000000000000000000000000000000000000000000000000ada854600e9fb24603d09b8ac000000000000000000000000000000000000000000000000000000009e6175f00071d3837caed637bd000000000000000000000000000000000000000000000000000000007a0ffa3c00eb027ff74d8419250000000000000000000000000000000000000000000000000000000043fa453f005837068f0891a5843d7f2e8411c8bef21df66eac8337d06a1f249cc01b956e0603d06de734ae6a2f1e170de9ad5737895c85f747bb07768d1b0f99669a7dc73b91a4d168bae17dfeac3d2f009cbe51a15460f3b26d88138bafa6ee1644c6df181291e5ac1f3a6b11bde316a01bd69588022485667ca6cd2fc73f6d7aff9d08e63b0a77fa3c2e74670d6d2cf83670e0b7edaa56ea961c1e8d3b9088f480725029e5a85e0db3dc972895698621b988a3af0c76ef806ec8335ee019d158a73ea608899a0b435ac8f288288c3a7151383f76285c5b30981516f91cfdb08ebf4fc8a638d0073680ad2a824cae7e99034b4507d17837196949c1b145183ca9f56ec5450a4df6d077e4e1f3f057660d4ac9db405fefafe0fb966ee668ee6489d97a9643d2b973110adae292a3332767c762fa56001dbe1668a48e77136bfc287ace637c12a701bbe119dc30ec7aace3f84f9ecbdf7fb6881f5fdb21c1a24fd364dbc4428e8ddb353fbc80889baee1c631e79a03ccb4897ed3f8043333eb8afc8adc5cccf00e5cd6d46963cd5b0483b3d1f09415f656714f502945f5c4e83a67259f6083947cae09df3f4c7a74a4871e41dd4fc8b8700b74e4d6ad991c2d1ea6cd6eb7d4df570c73ee21e0c75023d041f4c2599aefb7b82eb364a5fe9de8de77c208a34541ce5a90d37245d57dc1886715a0b038e2e0da44233dbb7b193a8967b53d959da49e1b745e556492cad3563637539e2a19507dc88b73fcbd1d3096ad4076af5b1e93ea376a705e061ac6b5f76f9735d3372e21eb9f9365aa4f620f60b3559f34254ba22e6e363ceb086a59dfe328df23b6a407447e265130ae51f864c0798018c8a2f8a3b8aecd0e51480e69f4dd3179ecfb5152071652f14206b1aeac2b9105c857352501592012cdedfda53a1780257ac8a55d5f2d488e5eea6773c451c1c1799d33a2dd05f4d72fc69419145efe46f27e328952b936babdf3f80b1aa64dc34696664aa5d5bc5cb8894571d3376d937a874357564b4af3040defa9522cbb52053e460b8e1bad794705049e3c15e8f260d4d3577ba8d9e26fcf6624516a549c932b2231a4fa4d99d9274af0ce1ec85fceef43b11113cc20a02147a7c06116f133159bf277163ee2d987575a2e342103b4128520229574a41c75ccf4b0e492aa6355074727921c18be00cb4d8c1e3f503ac86f0d9dced8a28b17613ccaecd59ec3e7425cce0eafa1aa76d6adcda848043e03a9d02a00a17ebaaefbc4d1c9c3b5c34c51a25c4c3e640cb1204c8b30b95d2544913a04bc599f4addda2b652886778bdbbf267b5e5d222828b7fda07a577ee08f21df7c38a89f7c5591f6d49793bb0acdc8ee4006106912351b2c5d76e5fca68f5931cff15be0b2a507f5c936445a6c05b0dd78d5f16e35bafaab2c94ecf6a31e53d62bbdac9dc32c7c6bbc4a6f82b931f874a9741c3465dbe65c126acce73ea19e3e22e968b10650166bef64c7598a35c81029234477d439cdc1cc604a8b9be7a672ef766be533e596b7e596ea75ac33178ab366a8542dddcac4692756da61b552fc12886e915985b8a8ec8e09b1c6bf1af372791e9c920507cbe78476299142d5d85e153e7de3b1c681e57e755d8cdeae628303acde8550c4ec867b7c0c49dd4cab2d917c609914569d598260ab23c489e3eafae99e398b857e55c69e9d782e4668367b0200fe8020a62d3208031f9d70dfd0b2d9f317fc9fc0b1e1f645109e024beb4190b24ca8352e496e990dd665525d5e00b40085467ccb24f2ff00af6c6ec8f57ba2b20dad8c85c24e767b2cd82083607a3f3cd4ebbc8a9b92d0d2c0006c14c9c5ecf26b023330067c581295cb232b157263ae71599d4de8b90ca13a5ab850ccc63499f3f7b6b018965f9daacf5b96c4d735cebbb654b83496891c6969c54e69c9e72eaad85b83df205ecf2ea504ba71c042f1b8497fec95ab33ffb6e7a0fbd68ffaf2274e143f5bb3cfcffc0235259dcc869ba3f6432d7dd6108586063e0646b30e1304c68034a24c69e790e529925fc7aae4a5f575ccb65584d121e7eaf14a70039066d6415adcd31cf3774f8431c851a8e22b0b1ff4b196ead0f96063c78dbf54b5e44b9041c33bbab4d01ae6c2e3667d825abe24f1d4085d43f9a5561e2b605f8109979b760907ab9b894c0ccb6e2e26536d3a835a438c9902b7848347f7789b9ffa73a21ce7709bbea337c0776efbd9302d7d789a8005c4aa1906d17bf93a4ec1dd61caf6c8314504eed98a7e7793fdff2299f1ad78d5a29d26c64a5d815a59a798d6ae86249bfebcd63efd1ab92fc305023bc1babe53119d47ad340fec3d89d7aea2cb1ae92b1fec69b2ee06a6c8aa8d5d5e87e84f2dfc8686",
+ "spend_index": [
+ 0,
+ 1,
+ 1256674190,
+ 4294967295
+ ],
+ "result": [
+ "1cbc2c12a17c62451d2cf36548bd5428bc856da30d5fe599b16743a3b289dfd8",
+ "0a1fb9e324a3bb5cb702204e1a69660c8b8c1e13240f4d1c28a52c5adcfe3ba9",
+ "8be86606c28d4cde311a518f44cd47582eae349332b906ed0235a14be33807c2",
+ "7c1b06f3d2068192342c5b643fa15b9d7b7810934c665afe08c442fa66ac8b96"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 5,
+ "Outputs": 9,
+ "Witness": false,
+ "Version": -374849814,
+ "scriptSigs": true
+ },
+ "hex_tx": "ea3ea8e905240338c6000000000000000000000000000000000000000000000000000000002eabd87700f486a7e201ac6ca600000000000000000000000000000000000000000000000000000000913fb2e9fdb701bf3f99c49e04f63d21a8518a93a4ed96d016189b40cb85d3a5764d2a13a66a38caba68238877a2c7d804bca7979cd40b6fd7849bea3755721b10482855ce2f68436e85cf9a64e3846e69d685ee1e8601ab13e1ff8d72c42bcbaf4023c935c08969b2734e88529540433125e1ff66b31ced3b196cc54b0128170f51dcea554bf15d13de112c6853ce11c379180534afbd747128f6ec49f696f1b2cb6f2384b159f79019a3a9c30a92078110daef12c648fdc75a9efcd04f663e1f42ba2d5c61bbfcfc73b8d111264424346ca055d77ff1e0f6cec83889f5792e78ac7c02566d0d9702185d93394de0cbf7de83f007f65487e8e7f1229e88f75e493790ca05e0304cda49c000ae971d9b34f418a37d7442e84e47348d4c7a6ca83cdbbf429719c4d50c621ad64bda30107a588cc6d82050e9282783bc79cca10fe04505aadbb90f7d071ae3b515e02d94e4e6c19e51df33b2b5f2b940d6df47f0c68d6d595308fad2fad8354a51ceeb8a28606f59d4bb936c94f82ab0add1ae510adb4e4373a17b4f18c2bb77594809137a66107bdae0ca690cb969c4e1f520ce0154c57dee20139b1d12f5ce987be8f5566e17e24354008f55f96da4c43d7b1823f704364bc600000000000000000000000000000000000000000000000000000000243a49d777627f4fc5e826acdd8e81a6c5f1d7d5ca35cc83369f4f1f1f522484315964c12be52fd9b55adb1ba9b8d20546b29c4edb02a1e6cf24dd93e440aa3dc35964e8ed467f2776b3bd26b51125e3c917e84a89c61a0a722352a9acdc6242e712af1ba5a88a3a695c265abe130a9636595e94ae50e30ec8f5f148dff30a3971e6eeb200000000000000000000000000000000000000000000000000000000856c91830037bb2ddf0def03db00000000000000000000000000000000000000000000000000000000c1e25bb4657f10a47dcd64ac85b0037fd99a84d60773e3b9b144061b33f32d5d916c3aa83ca0d22d932d6b06c9eacbc2617370c3e20cf65dfe63451a3ed9f8a72ca6486ab9bb99825d8e1afe7c02098d36fc80e79bd5a9f4bb4561ca5a46478d51da59d81c5539f2b000bbeabf1b09e59f12d005f9071fc88526fc0e9363b11bddbafeaf51e5d948c453d0d14a3feea58f30ca135a3ba3eadfb991d4241c5863ff4ab8cf062a23be20ec8e718a45b3ede10f67c9e31d568782c5a55cb5a38abdf0ca6aa95549563e4774221576fc9949aeb296656b09cc1a00b25b8433702079f51666f796ea9df041377476d18057f16d293114703b604e9ad5fb88bf4443744dea5117601ad991f568d564a183d668c87d4997b5713587ba8473921f86e941e8f1cf3c53a7997c1d0f3a9944cb5dedfa8a563dea7cdae4b886c4daf24b8268ff6771399b747355c8856fce298f7a3078c80f26627780b203b1bb06504de5332d8fc66d9f85b671393eb52d7daedeebdee62c3f7537151d8a0844aaea1013ce7c96c3f39e2e98399efcd11b5408f84bdfc3bab3130fb5a97bbf8f4e720978a7e50e6dc587f6585f01d9e71c8581ae4fdc77d4e49e9f07f612fac5bda8c7d92dbf139e5c6746b3fbd69a5764eab6588e2bd00019e458c57cb9d788afc60d020c46d03574ea012d56587a7b4ea8f94b2059c25e169a14b0c9efb28bf12ba967bc4b36254d0667274264a62b61362f69826327c8cb745842c875c8b9b6f01084a3326f38f10dc155953b1e57ec2206bd468aa408fa0e3a0fa71ef99afef0cf4ef869594cc71eb912a459fe07086f9d138afcc6834444f2509c0803a5cfe88205e9ba266bd75a83b672542b7741cfa7373df23b765c5e16e2a10d6b197c6a0452c4af74191ccf46bafdd0c66e8162719aa9b1a4c56b8cf11678d10fbb0ba3971fbb9cb136c744dd819239957c0c1948634ca0da513de49584b5afb789d8418a1cd5dc92dfe397dedeb11bb92eb4226da232d4ff4cd185d5e429e0b0d351dd28171f959282298ff39726673ec8eb5604005253281915006ea974d8edfea8f128f8ab252ccea01ac3e1cf88740c5a878f764ced73ffa344744ec40f0fdf542821dc79842b1dc5774cc0ac7d901f6577522ab724d9118f636c590f4b4c72341982d46e1dc5ed3ace8e04c186e519a382134fdc98d1cc1b8496c233abe88976e3d748373626b9ead18ec9cdbcce680bce924253fc04eb32374e4f759dda34f4c39ceace35bd417dd3f5c4d07831853d53ad130030e67655ca30de7f46c5ab27e7370b8601cf804bed2b273e0565f086dbb65faac171a24bd34c7ac0ab8449c832c028d50a1639f5d815125ab6c7149c8498fbee4ab67dd7b3caa147700a58096f0520f595aa9f1b407d46f5091ac71a4dbe333eeeeabdedb9d607593332b01bec9e7482811568874145ff42c740956d6ae7e09c96d1de46e0b5542016a909fb46ea77e5c5bf17c1786a7ce9562e6c504106a3daa54d64b1e5513dd2db3087338ecdda2f886ad7cdbfdb795684548a69b4ba4ec83032e446bda170c44a66d8c27f875f4d18261622f82766191fcc6840d9143d8d4fd0ea2b183b2278b8d26638ac0e0b6707fa18db741b7dd779caa001c8177971a9fbde34a2d82dcfd9798f041e037d0b33fbe8642527878a33d97693ffefebbf8b383254bbe19eb91a11b8c05de60adf3a7708bf29d6e82a1310ea6fb9708cb20869cd5c05ef4865d45c919814f4276a0f17da82ae7ce6a63cbf4c37e417c9a77f273bf9b512c4272ade516d36c89b7632fa043981ee2d019dd9b9a2d28cf935235e6cc3a021af1d9cdd40a697d1bf281cf6781c3c1cb5459de2c2a7e8862f802d4080f5ef3820e3bcb75771a3a5746b761ea033a7709dc50d846060ed2b4b88bd345a5cce967fd2c8a7faec14c8ea4e68509fb61843a687745938308fc0ec9cf6e2ed24448a0cf1ed2d5f0266dceb5c48120be5184c04601dab0cbe8b73d790df8384a4f0863b09d2ccdb2cdcbec287739f5406ddabe7de9dee27a0f6ea8c57a5697c9becd9b511040e3dbcb1a8f614a7b750e15f58d25942f0b8a7ad2897f93d5670ba1ee3346ae226dba8df07efaaab4bf77fd995a4c8072c1f89fd37ca1e36a9c503ef73668a1a466b935149dcf79afa4512427f71a8be26c3b054bf11a28c0db7cad86f042447ed8d23038f3e2053aed5e7d90d34efc68b37ca1f6fc8a4f9645ceccb554b3a4c632caf6bb9d1a9b38ebb2054ed731017b4d9af7d8c979c1f2b0380108d2335408ed3e4bf0989888953d71f3b6130ca8a5a5772718abc157ea3e04ba25a8a2161238cb7c21191169c0aa141c9e1ae1fb00e26176460a98d1cc7ebad95a9bd653950a48881a4d297a320827e4400f8c30eaffb7fae3b2b57c021b8c5d5cf560ab3863dfc712ce41aa849b9a24da9d5bda298f4821312ab4e2addf2364cf5d171bfa478224b80a484727e36a5778348c5dc802a127e988ef1c03828f200d991b9fb7c9590f36420c8626d84d36c486f305d84dc1c337ffdd00352b253e1263bb2e4b868446ef6bed02eaae3542daa4af65b48950b57eeb2b17b92031f67a6f69b24d473a28f68dd1077d73b7a23de3c8570f051ec037c5950c03abc86ee5b958e198218ff086485f8444c928f8e5386d02caf99c7cae1ab51f586814eacb85a9024486d489ae76a1b8eee999169963da3945ad8f894477aefef35c8c788448028ab8796e0c0dda90389ecab4f29f56783228bc1e135cc218b31fef04aa8a95b28fb0681a4dd2ef99e7b872b2c9c2d078c88baba73",
+ "spend_index": [
+ 0,
+ 1,
+ 3216091953,
+ 4294967295
+ ],
+ "result": [
+ "51d6788249aeefcbcefa586c698aecb744761d187790a75f86d0b22c09ff17a8",
+ "a7ac21bac86b38f58f751e9823153b7187131e62012c5ccf09518ccfc3963d78",
+ "69d12a2eb89f805fa70741c42ac301d5092124760cde28b0cebeeda59525a8cb",
+ "a588484f0c7e6406bd8873a30f7f23a80e86bd46eec094053e1cec93414496e3"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 4,
+ "Witness": false,
+ "Version": -1556642398,
+ "scriptSigs": false
+ },
+ "hex_tx": "a28537a30675c9c29800000000000000000000000000000000000000000000000000000000bfd666c7004444d5dbd688d48f00000000000000000000000000000000000000000000000000000000903fd8e3004d2e132f18d5332e000000000000000000000000000000000000000000000000000000002849a5d2009261d646bfea33db00000000000000000000000000000000000000000000000000000000b0fde66c006f46905fc78dc059000000000000000000000000000000000000000000000000000000002b79037500b3154e35f19922b40000000000000000000000000000000000000000000000000000000082d485b5002e521d82045140d648ee39373ac8826ed82def4c4d580bc5b5d8b27360aa81b08b0b5b3a0b12fa33ff0d4e64e4b70da80c62878bd456bcb877a629cd1db0de8c23d543c6e9981aaaec764e86557c6a2bf9e2de20fbbc6e8f6cd5dd87e8d014969cfa7e3a66f83263fc74cf203335d164e35e16eb868835bb08d430071ce08e8d00986a8bd9c73ffa3b47d9424621df29370c12a63500706f1f8603c18aa4f3baff28bb395f64e1a2d094747fb5134d581b2ee2708136b3964464c9c8347c59b3a6feec739e395978bcda6fcffdf4b6acd48bdf2cc6c838a27ecf20dcbd3fc8a81a6f4c10f8d6a31b3eb0b8998ef66d76193d083ef1c166127b0470457fa0f483f1e8a4eecae4c7ffa2ca403bc3754ccfaf7c6b784feef3af94777fa9ded97d85fdff27c5ef4180f305a5d2cbf3d18832ac182a65b0d008619ef460cef8a322196d8fefea42add04b9177f9d7ed2042d6b196525bdd5eacbfcd8d527ce2a7c75f7670b605af6027c3366199153482ce3885e59bcac2285b907988914e7401ea486c42bb5b1836c61a36ccedf662e4bb3c8145ec702be5101bfa48fd7f2705d40a5b15f61f1e69a5fcffd51df8199824c8418ea0103eca39e3daf6818c4f20118f0c267238843c345676e6d066254243666b5418a651af82814b2f4981246c056f7f8b2d78b6b56759bf04524718ffc679bb7b8e24276ebaf0cf1062f5db3665bd100b5257f59081ef49e136f0d8b87fc9e6f076110f8e4fd9e99818bc806f1576a033574b4a40310342c889cf32d34385c802059a890463cbc02a015d622a2d4056814c2ff2c8889388366c0de79eb6295f19fec73485584b9d6571209df890f0de9a8bb71c895e0013f4fc8b290422b17ba62b24332ff6ab81f2b00379c9df37c80152c490efbfc668069d1db20a79f9d64bdbba39625a64b4faaff402f5abf0f5aec586e982a9e3101bd961007495ce197750faf3bb2867269f9fb96388053af3716268e387fb65f0aca88b22130e49ecdb01591b03ac91dd712878a97b15e250e32fddead53a2fd03e689f72521adf58ebd8a15ebfb6808dcf4c27b9a5a4f9a1e0a028f6033c5f3e47e11e123c8f1717abd0f18bce748b2d6ffd17bee05b092723ea5992a1bd03fa1953ec441c7809739bb744d74768ca8fa65db6c05ca4e3dec59d38b7a9dc285214dc941d",
+ "spend_index": [
+ 0,
+ 1,
+ 1428324591,
+ 4294967295
+ ],
+ "result": [
+ "6128d94d21e16b1667b475e5d1cf8fbace201967b93316cbc29018ba9ad7e1f8",
+ "991f8bc21b2fd0ecce39835699e395e2da54601d914bd614b944f4a9c0048948",
+ "edb18e9a94967cd1ff1e7020b301eaedf57a935a5d85e2f4a367d806223060b4",
+ "720069c30122090c70546a46f3f33306fd7e335b4ad6ddca909017c2971b1dc6"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 10,
+ "Outputs": 8,
+ "Witness": false,
+ "Version": -211459921,
+ "scriptSigs": true
+ },
+ "hex_tx": "af6065f30abc77d8470000000000000000000000000000000000000000000000000000000011e2d273fd66019b1f3f930e765b6da05fe932d2d17a868ce72055ba505d4dd4fccc39a70578d4247dd78d35a9d97b58f396ecdcdd0d7531e8f6699c808778f3ef5c4e1563c0ac1c1566a891faa79a5e806a3094b3f9b8a1ff4e3387c99224e858f46a612c9426e3cf5c8f16b77c8f90ec321419d007959119be97fcc13bfa1ffb59215096f9e2d15c565582302939923764105c0656a06208abc93d7964d5c569300f25ae8ec9252ac39ab27d34d3fb5b6a6e8a2e9ff95665de700f044dd753e265bc9a5763642af033cdf3755729fbbca777f20cbae9cc0e3716370e0c71752344202de90cfd1706b6ef852e3529e7324c978e511d856af731f0dd311011780051f99318108b3c6f1f649fa615c7003632b2f408c0ac56adefb815f0604d96fa9ccacca3430d2de8a747ea002b790acfa0f65327c89587fdbf195141df88d2ee11d303dfd8211a093c358d6edbd8da5614faa095e6ac029f43f51d931be8d97076394e06bc458a0a8250f00640767840d19ec7b4000000000000000000000000000000000000000000000000000000008cf7db67c57e0f1263a92afe95dbba6bbceec4ce7b9c45a7099d125ab36954f11c096d6ec647e97da54eb8f58250ca9efc6b6d051e4895b22272e46881de55fdf21f17ba4e1f6af7f82cf1ffc25461f9d79089bae859d9bc6452d9e2827395b006d1e067e31146ea27f1ae0abf63f03adf2cbd8cdc16e29b80a3126f55b3162c0941b7a7da15124a614721664be4179237c141d4a437afc0ea7c7829a9f180c45a7e43fd1eea7ccfc7df39a7f23962721b8bd9816553c8d2ff41e3af548fd52081515f1da07faf916c80d012e25e96b741be000000000000000000000000000000000000000000000000000000009749e369f3d3f49a059391f2b6064156a8fb478cb02d9b7455214a7ed3b2266564178c116910c0d63b1b6a2e24d25a3f649dc244210b763e2115e2190323e83858df0e87355a5e532a863eb56193d9177e82b04161aefc46a8c6eeefe14ddf8bbec7f5f80dfae3a4f8ff0e91997dae5807c9a1a8e94846bd8e88f268d66f9a7a9b9ea1656156a35aaad8648907a7908b75b7e07027fb761cd35b655b79e09eee0d9ce64ae803a59a7dd51c0e43ddb5e371f3ad30d62616d793b5b1729278f63b5be95cb683b4a96bd88a72ef80df86dafc96603339534f03071091cf8f6344391620dddf45e76a368e9060ee64f127c35c8d8735fe42afdf5862ebce0d9f559c0000000000000000000000000000000000000000000000000000000067c1080f4842480cd397165a7df7778b3423227e2e0f34dad207e5404415136d42828e3daa4bbe78b337d522c29964eec0adae1a0197235edf369c960dfe1da771b1be8879c363d870459be9ef9e29b806b6418be2000000000000000000000000000000000000000000000000000000007e83b03cfd7b01c958574b8b1b7d0eda831bed14027e7b9f8080bb1b82d10133d3afeb736586de324e883462a4e0aa7e7950e97d99800420c2104787970c008c1cd3b8f2ea20605bd22142410d483411f80b1b25c5a83fdc21400f7007bd28643778c517de70362aece62ca15455ef573ecbcecc9318f2d80fe03cb95a489c939337ec2f9006956defdf71aee1bb5beab82615511a6bac509918259bf5c771319718998895ca20481852bd2a2d47701bf2e332fe11669b1ad5667543a4d2bbd6ce4cbbfb15985d3fc410fcc40fa09d8a48a1f18c23b78c22690f12f83d64bb9d3c63b3f566fefa2baba9fe9829339ef461b08f0983ba22ebb1cfea2d3c374e1edae8bfe2c4572f9851010b4b377d1605572611e7d4f01a95def35c9281d62ff267725bc5a5ecba4e814ea1dfa2a9c91ca1bd28222e4edb479885bbae7f7545750da21377d38b18567e438c6b19cf7511913c4713ce0b3e3a0f260e5abad4ad52fa21f05e6257716f73dbec3bab403abe270f2a6fc0d3cc11aacc99abebbed5d16a5a959b9d7b9bf103f8000000000000000000000000000000000000000000000000000000005f047ed0a8b3515e051848eff79b5ac436b6fdc9ce49d79b355ea2605b5c2aa75d69a05cb8f9813e16073917e2337b4ddc81ba597d3e44c47857e1a5d86949c4618ac74a34b92c67e2958ddfcca76990ad5b06b6cc63d9c755842b60a964a702e2fee1fa942625034e14f720f4a5f32b4a5849c71ed0442d7ed76455bf2696706cf2af3b952eb09129316f0e3fdb6d8b2475c3c28d04c5fab15670d97e559a5a68755f73567df8ed51b0b134d2f8d4e8b225ccd42100000000000000000000000000000000000000000000000000000000db5e3ba8fd6f0184e40c4c15b56c4b03440298ebc916c1afddbcd7afd5eccd9dbec4d35d5702096964d1015737af3e1131237925642acb3900dd4e90e45e1554e11231d8714ded299219ef50e9f50e65d99df34cbd648dad1f067116e24eb8f657a49e9cdc3bffc1610355023f24faa112a367cf8d123abd803b79d2f011e406cf38f6b20ccb3107698ad326179bc6564355b0463ebdbb55a935611349c468a32fda87c8f457e2c3df0371cbed5303dfd659c0fc9a4d19ba1c54178a5f63d20ec9c5e01a0e4da9014aca148da4a5e1d399d3ac253424c4f453c573e947a265a4adf92a1d9b96d4f4c22b46544bb0052a5d20d83da6566f3a6bd5ede87bf00565596e3d02e413e830433879fd6988cbc5082851445857da186a451b44f80107d53dc82cc2eead17c478165ebe17d6d12f0318cdf5cebc0596db7d1c342e609cd6e47fca2871a3381d38fac6d27c32af85fc7f6a863a9d98366370ca56180bcbd3f4d8350816a061f4c3f0515d423e7fcfbd0c8c8310d88b2cbacc674aad1d000000000000000000000000000000000000000000000000000000000d1a6eb2000ee4f5a2cc5438f3000000000000000000000000000000000000000000000000000000009fdadccce95aa4d7458f28a041fd4e4a5dbc3cbdc97bc762346628a38daea7f4fd8fc060f7196d510ff0bfadb80f45c10cf33a9175c7382cb05f35f139a38de9a60c2b91ed96c84ba19c1c572ec472419f4ceaff8c6f64dcf0d2f60bc2fd985b9cdef4429284735913ad616fa3fc0ae94dc74e091155d6dcd4052b9c71c9f18fa71bb89050e1d7739cb581b3bbae181fdd5797e42744fcf7ab04893536f57e85cf860cc32c3468293c42fcf2f85c4e0b0b113b5b8e7ca10e6c55082c4ff1ebc37d62c9150f5fe4e173f83aaa5b837180a014e7e05b417a0e19a275114509d7609c612c52edd3629c56f967b1435d3f6f5dd22db269430000000000000000000000000000000000000000000000000000000067f0c87a000548fd6d08a01a56f0c6c32b66c84b3a5b3eb086bbba2a93c64297bb74fec48fe3e51af608cee555c224d9f4f131819f1503ee536720c851ccceed7fe2ccfbac32d6c07fac139366a8f325b434ae9eec25a023d987219e46c7eb13975cb8b0298543a41115b4b448adedad0c868b185664f0410ba6b2bdf27495b4f48fe970386c8a56cadf43897c6f9cb191f9aa26216af54caf15692ec1e6a621ba844b31c8094c8dd9ae6d2aea6bdd7759d0ed0f8d716240e68b18383483f6bac95407fc95912c2c631202689f490ec2ffbd4c8eb9847c34b10f5e218ea9ac7c121d49c807d704f1aaee47235cabfe3ce21dc6d62956c6b944337f5d05b28083a5688fe1a03d2316556488a7d7c22ef7af9a9a5e97947aa45a7cd09fdfc86630e374b51e19f795fa1d0d980d16dd41cc7cf853a024cd1594130a81e4e95edaba49e490cd2c05432f0b7fac41c1dc99296214295a02a0db4dd2b6ce13b32f864b56151304c680e67ac84867034ffbde739a280635bf018eddaf88581c09daf5744ac8ea0a6dfe300aa0c62a0daf596e2854a95af252656a0619777c2e7cb0fa407a2b4e097ca00cef7d454b49aafebc478285b407c8260126f7fc919323ae4b0e014fc14082f5b515fd8d35d40328a0edb6b385e6a6fb3cf900182d351a1ca531528b521ffb34d4384303a8ef5e03632796e8ba5479345b57b3bfe9f7ef03f3c64ea7521c819f91668ad039512e3651b51cd120dd666073f128db33a3a47e66a03f39eaebe93b0069705a4a2af10c907d7aeace015cf20b19988eef8df7f8b780ee61216b84e52234b9e1573f37d0607fa8e9c85e4b03a95b873c611bbcde2b607bbbffbbffa54308297a8033898b7b741dbec07b63bd71875e90cf933fe8a8d62dbccd8461c8d2e13ec493e6f3751c1110400d051c6e0d7fc4afc253512e9b5fab91b957032ec85372fa71eca10dc5c4e2ed7a0ed9b65310dc88648d559a8fed66136b69318e0bc9d5c9ae0b456b2891b76d5fddb89f27c414e3fcccd72fcdbf61dc341b7f29cd39126e001648e350d68b3a6034dc10c43c37f1ba16b77f3b5578b90b79322ee96a72de721e44c02a7cb6ff86f7888469c87d6a04a90b77b422a212b0efe0a17daa58dff7f4e76fef4688a9bf03deb37b8928214a38d7d410c65bece070bebc96ff93671d9777c355e3640187d0c40ec8c90140dcbe2e46778796a6394f8272faed81d304c54bbc9de9a9f7aad973eb067583057cdc18999bb2111de8c9f008d282c26e7e3fff2264f04c066e4138098e70230fdcf47b7c1fed3bd9e593bea4880960cb3d3e89ae00f5b4f2d90e4ae58830da9b6333f3274b314bce2f3143636359e72dec9d81a4c68c07d86f39f2881614137bb65c22341cff4f4fd91fee3c1523af2c716950c8f17657a12188b2587bb9b16fcd232ae6ff25781df9b5a88db9027ecdb7d05cccbce8fddf86a0fbb5acb0d37ca147d5e75648c9f66da2deeb4bc891ff6daedcf5f3cfeb59f07c0903c81c04dc2ef98e4a0131587590db695e8944ba52a189b440bc77f49caa62e4ef258ecf97dee745ef31f3cb905091db896f98c758adafebc5472753cfb9f3de41b07584fe704ae6851ed2890be4b6091175a247397b8f8229144d15da9db16f0c429c7d74cb31e9ebccb6e5ed783d93a70f5f8e5fe027ae1f4361b5f89ec3b5604756935bafa937479dfebcfd66cdd6fb91aed84a76a7781dc1316f2e39879ed975679336172a0372587a289004948de16776e5228236bc6bf737786ded7570dd6b5fc8e030038e0c40eaf9eb94be857c72cb5e2258bbf22ec9f8ac84562ced49783c0a47addd78179e018ee52ea04a4e91c396b9730fe9a9e595dc7ee04ce3e5eed6c85ad367ccf0e0752c7e1b27b810f9d3ab1d4850196ab41258eee0f2e06d39095ca315a0be538f537c2c2a3c61823667ccf22f742f47c9e3273dc0d7fbaa9ec9985a603c523ded78a4bb08538bd30a0c298b838708d6f2f8ce657daa1ed68f75d1f5582f26958cb59a56c0a8b2037f3e568c200020f26ff447e947cb5aa48548a6f64afa7832c860e4bd5b7020b51d6905c8920289d97d67ed1514232c785971ec84b744430bb29a067f75c8f51ebb50f2b704ddc20aa78d1129b50181aafe9e7792c970f4d89f64c91ab37bfd01db691dcd8e86d7cb60df5f628a48a00410a312e11d204d85a3ec4426926ec7a2cf130af3695188fe2ba5a420b85ec441c66db2e0778a2cef4130e3b8aa15edf7952e2d173ddb20291d1e256d1a11d127413ade1f2b46d0c358ff96f53fe87ab86ba777da22603938cae0b3d126e87c0fa3d3e524a3d496825b339cd49fe299edf7fa58c332361ee8f404822789663e60",
+ "spend_index": [
+ 0,
+ 1,
+ 2180284422,
+ 4294967295
+ ],
+ "result": [
+ "83633cbc593700cc311dfb713af1ba7c4ff5d87bdd695e59d184b61a9d7b99b2",
+ "76c01715ecee5d532795b67fbfabf83b1c853b74f59e0eb440b0320a1479943f",
+ "152fb1fd8300a8c37f464be40f512db3227cbc20cf51dcf0a2ef919dba0661ee",
+ "0abaf55540bf9b7dcd307594168e46f95ce3a2602327bf0c88b6322f13d40f2d"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 1,
+ "Outputs": 8,
+ "Witness": false,
+ "Version": 1828189183,
+ "scriptSigs": false
+ },
+ "hex_tx": "fff3f76c01395fd8f8000000000000000000000000000000000000000000000000000000001519c49000e4868e7708a5c1dd79df866c6dc814a969c33e937c2dc893dd125471ed68ef3fc99be691e0cceb9896dea9ec51881a15287fa69a6119911f05224d9cabf0aabf953100833e933f5e3d468d0878b6b181214fb58c6e4f7c16e129debe75ee67610444e322841fc8e55c408cabc75089da4e14db69bfeae855623664640347b1945e94fd89e6944bdd7f9ca3238bce1e035d710c6dade4b40ee54000354892f80c4b70cbcbf46dbc74c4c736e15ad3a32662750afaa5b75000da31affc41b3365f72fe6d8c3269bf6cad4f31571c8002de37a217c04a7a243f8358a3253b62c8a4d3382e103651b5320df9f3dd92119fde16ad13f9d1477efe02dcf8ab1aba443a0d18120a8b16b613678deda2dcb2c1fccec0c2b996002bc5b1abc8fd8128747bfb2b8102c16201fd13e5b3407ebadf66ee38ba3f0bffacd2bec490ccededfa969c7f7d633943de9b78722aa8cc06e89b5c29d8d91960584661594c32da7e7b44dc9f6bbd540117c38c10478f3999b61055ae1a02c2e16ddaf7fde74e105c489cd9e4a9b7d851f8e2570e8c460aa917e2f8169f3b752bf0985953d7f0f0aac38967b2a3b912c6a86cfc46e224b97a7bc8de043f87630bc6d21529716a8ad2d3df44535b1c14daed7988866043d598cb569f62646a4c40865d22f52f1046ae609786292f16bc239aae63d691519f50c66375887f609829659f0892f5734c32ef3017ab698755908dd4f43460c934b211fabbd4e1f52f6b13844c14a6a121ac29d8f08a44b0d97dc668103b1a2aa882336723b10f8f9a581a9a29827cbb62865f2227fa900263fd39795a84627146594bf8418644468a9116ff8a7fb54cbfb560cd0a1e9c9fcd52d62b1953fb68e93d9a0bdbac303e3b7a6466cba4afc95a915b62c8e1c7fda4f5f695ae89cd50b2e8aac8f0e2243ec468f64d5132fd717bdf72a4850c10894d4d2c1dd600d4a1dc8fed25556abf767532811bf1c14d6d07a5e6d670fab661ab57c4d63ba389afe43b30c82afad7822afbae6d733ad7c3bf7296c8058f177462c7c1aea72645fdad3ae66977a7dfa994e3d35a7452f69b299444e8bdbdc875804ca99b7bbf28a737968a96377e36ada76af430bbb6dff870d4aedbfb816fdc43ee2ff1fa8c7db35848a547654702238b79e7e465c4deb95fac095e20b464cbfeb8ceba429bdce88668e3a61dc827348fa419592bb5c90f9012221fd5b851f6265b95ae18b378bd9e74079b6a72fc53bcefd1e78202ed5ed47e80e9d292714b63004a30dbd3be47b3eaf0a5f1d697318b656916f7442b19e7230fb0f641a3e6392da8f9de871a1b040735d2216185b99d473a651935527e251c1af6dacdc0128900920c3f58dc99aef811a3b9ae186e3c8f81dba6ac699228ba33f5054cf51e39e33d7021fac120bf50a7ebdf607a438c411ce10a658f62d0a4c1a3a6e6a13d596a543a472e3b255312183dab6ffca11948f43074ecad40400ec69aec64c82a406c74e35fce2ad407552a2127be23ca25c90b547e175a0e0f8f5260082e4581b22c1cd9ebbe985fdb3214e300c84bcab86b77858a456d7d1a794689768f0f9c6043ce0589ba2fb3f28850a16e50f52da7f40cc09dc2881e7bc3400c9bbb0fa59debb3bc8f85eabf43f4be8eb19707af9301b2106ede7ddc1441c0c5189ce0fb1d05a313fdb6fd11e17f288ba2be293e73fe459f631dae97d81f61eb9defeb7edd2e744736b0898accfcc7953ddeb3ac2b6edb7efd059e9c2ac5059ff62da45cb550213e3ad7fe65948e46e314420ec8cdd4f9cc1eb66a4f16c282367d31c47cc8e5fa853d46d236dbec364042f273c4a4754a480e6792475f7eecc6acb94d77c11b37fa96af178d8c09edfb044488492f376072eaa8bf137df8d206a204067d0624f538408fb5b8de11978d09c732ab9991cb67306976934b197337eb241d286997fd8379138270472008299d336056bcaf3e93c0591973db850d1711962771838a4f0d692776bdadd9a7b21537d930fea9bcca7c40407f6230668130b612fc823e29dc4264ba98db789dfb76a416b9261aae0f881e5e31979583a03e76657bc8c510ca6b166abf9c73d12cece1fb098c22e9e2db0b8bc39202121dae0fef7bbb43295bc5d2d4288d3f2ae029a09277743434f10ce0215a7a078b3609769cb125c402b78407b8def9c52c5c9f1c3d0037ec0c320c8435db314b5019a4233ef628441f39d36096b9709a969d2283b51d593d8fb53fb4906e4357b6531e10f087a107b2b89fcdf7ee6a3ceff5bacdd96b87770a449d77e70ff01711a6028155ca51b04ed5b9c78e0d9d5edac9fa742a23182b75a7c82f38ce36e7f61ec8adb3c9fdd071fe6a44dc3b50478f3658",
+ "spend_index": [
+ 0,
+ 1,
+ 2241195222,
+ 4294967295
+ ],
+ "result": [
+ "fbd57d70f59cc8564c04cbe05b90fca6510655e46d14cd7e380c1fd337c258d2",
+ "7a4eb4ca724c0a4c0213100d9b7c6f930422e4218d35a940165e4cfb3f130658",
+ "4a9dd17fd4f6f68a122394ae66c695637d7fdb0f49f59edb917806923a25b18e",
+ "97f3848d984da92ad3baeed4f2ab8757e4a1d645dcd3f437a1a80cffa2d32efe"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 4,
+ "Witness": false,
+ "Version": 2138978941,
+ "scriptSigs": true
+ },
+ "hex_tx": "7d3a7e7f0275a01a4e000000000000000000000000000000000000000000000000000000003416da7800a2727c85eeaa277a000000000000000000000000000000000000000000000000000000008a062e10fda4016027218088115c0a566dfd58ef389ae369e7c46ca01fe4478621ad39094e8e827f759536a9688e2810f1f50b23b0ca743fc677c714be50a31362aa94ebf7573ce52a2a486ce518b257bf400444b1cfc1c1d8621ed3de8981607a6048d45ddc8a5fa5633513b71223b99564bc8e22b52a42bdb4152028b2519d82076b168d305cd4f7a10ca47424a397df0a1ad60e55083650578e94f7c76311fc7f4d1527ab119acf44220cbda555aa2859d69ed0fb7c329992ecd4073e0d36c8920310ac693d1cf43f5c5c19234527e6f3da2f0d6e0c953c090ad2e5210cd90bedecec478d7eae037f5454844ad144e3124c4f148bbd62183b67899e11f981464faa2777f7d0a15addc90d8b9f6bef444f0eaa64a6f0593e4646dc79a3c8edf2a1720eb1d0891d0247a3cceddffb4b4523c7c2b6f8dbe5fd9eb258ca0904ec0a35e13f5ac642efb1b3820ea77b2666bc25ffb3167c56b8b7cb96e5ac415aaabc6d581c54185778662bb2386187e41503ca7e410008b09388bf24c47acb10978ad2b3ed941d1a89bf44f5913617c9b3c50edee7fd5d42beecd02790b058554ecc1c1377be1614d0c0bd7d0a3ee217042e6eed7b479cf45dc8caeb0c8d73c63b343fe76f81a9929752d86dd73335f4304466e436508eede269640785aeb08bd513427767918520da622dc83b3fc74ea99f3d61cd073af15c5a6710760800f11b6361f2a25d1b4ab0125736b9a07051bd961663888dd5cfe3a65a79df650c41b8215c2c4c3387c14501a82116ab6e9f7124380c132dfcac494ccfc8cf987f1d7d8751dee86b7af18ba2493c45a12c11ec2737eca80e96123c9a678b73660b706da76a8dd3b3951888425090dddd1849decadac72dd03dc3b4155256d6379f8146a5d1bb1ab9f20d4216c8aa99314a0833dfce4b04ca8fd74855fddfffa01d3b61ea1c01eb63e4ac9bdea80807cc0473d58fbd5ffbff4bf6705766abc6c2b592a4291f84bee8b6659ca92d6652eb8dc625d67198031277a02ad2375d259a1b89c552b9ea8d1dcfe813154a7fffcd7678e4de2b6d4b5302ce3baf756a8692850bb000c987578cec72f7ab8ddb4c9ebaf9ae3dc7c97e84f38e901cf2da028bcca10239bfe568b2c625c3fa4f1b9e3d40bee5a1aabadf9bfc0ff8583eac4a95a81555b1569633744d6c0b09dbd87b9e914293e32a5a6abb57fd24b659c8b9ed62259d489f9115c45fd77e9882ec861c206506b61b7767b2d96baec3b5b68e74d5db478d06d94a5dba60f927f0c4732061f40cb1f8fb15101907687ec0ebf92c1e939f9a57983d036940c1849cbc6db36b3c979cc55cfcae1a7cfc061fba2d86b8606de74298fdbf4fab9d5e521d393ef953803df37ef3f556704055a56dbac8196c83e146a88b9916dcc089656c8fff94f79f30428d008a7a51f6507aced962fe3d3b19fa15b6c8f742e53cd1b4245b6895fad892837077ab9182fba16250fe9602ff83bf1a72f84ea38751b217c8d7f0f45ff0d4561deb9d8468f8a0f08d3547e61e90b7ea92e8f7eeb6456990bc594d013e5096cfe29252f0efef8db29f32f763a30e93cc07f7916cf142d1b1b4c30885f5df6edb2918729b307cc0081bd06f8882fc69fbbde3927fe6e1712fe7f9dc3d3ce845c2232075cea309c7d50d758086bab845ea1d6cd6b985ed7ce426de20275c72e49e64d760da34f38a9858a3896fff020ef7144b3aa2e4e924505a86cda8c9b69a9e43cae6c33e8b21d2a275679f3de01eee64435e060317ea05821daa31d335fa8729305110b2",
+ "spend_index": [
+ 0,
+ 1,
+ 1305917170,
+ 4294967295
+ ],
+ "result": [
+ "fc195d4db6372da39b2c2b11a1b9c848b9940ea4d1c656832ffcc6b8dc1f4103",
+ "3776d9678ef3b5ded3bbd787a089e370f7cc2cea3b5e1d4c2ce522d954142a61",
+ "7bc475e72431de33427d3bfd6dfdeb6a23113cc7357003f6f0140bec3ba76142",
+ "5e7572ecca53b57b4ba9bc5891d9d3ebf6d80b7b37c60c3f834953bd5e2d326e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 6,
+ "Witness": false,
+ "Version": -294915705,
+ "scriptSigs": false
+ },
+ "hex_tx": "87f16bee063b22436400000000000000000000000000000000000000000000000000000000d4a5120400b186c1459b435bb000000000000000000000000000000000000000000000000000000000f766765c00d2f1a611e2a8f5b60000000000000000000000000000000000000000000000000000000039f3b98600d9b00db56c4553c700000000000000000000000000000000000000000000000000000000cebf0e8c00e022321210fada07000000000000000000000000000000000000000000000000000000005d6594bb0040e8dfbdbcdb2f86000000000000000000000000000000000000000000000000000000000af613a3003f6db8ee060be5a9a7e0ee5d57c87486d17ae1ef277ae1ecfb56007e6613f7a589dec0784d04bd12b55b0e807ee2ba79724856c847d1aa26fabddde471a1e31abc2fbf0590353d9e7561e2da2eeaa68514f6e3a289c5aee9806c61680184a1589f75bd2cb596077ab1aa6b03110ae8fa8b8a5fe0fe68caf2c74305c23271b7c221421ba1a8b62a5a3d0865af4b32c2c26956583bb826f65aac3968eb2d4044cff0e32db16506201f0db4a73fd5663c0d8ae9bd8760a64e36427e8b06f3b89278d7f980a982d5291df5ed05e59e6da75f0a51c3caf8834d49327aec670e0ac8bfb3df257f260519cfb4fdadc108cc3db9319420d2685bfabe605a0ccea020d2865d9af14f4e3da06a45023450ead96ba0bf665a5935dd02d6dc5ae778136fd996fcdbd5ec8423b931c4a00f9333863338dd7a4c7d4f432a81f2cb4aef11a2dcfd4f38d1a2fd5c5699a0e2911a378ed992335647c62c1742f781baa9d62f75f1d34061438a6b537038a2eb96ac1994ef21e6ca294558cfed77b43e84d0737b962b6265bdd5264e34e388863087141ee73c37bbdad44a306d6d01202c33684c9846c0ab8672c2ae0dc215fccd47088561c8f5a297ee801a2932ad8f87439ae6dfcc4fb1ec02a895fc38757f2ae2437030cd8d3cf44654ab53a8aae980ba8a2c7f816b4e0ab7b07b9d9d6f1a1cc61c7474e491d4a39e50931456dc194c48cadcd4baa145e2f115497098c40846fe099d852fb62dfff3ae491d6edded0974968418054abcc9205fe70a858a7a0e98f55fecca60aeeae68b9f725ecf643c7362873a56bdcac43cb4fc0785f84719d47bf12ce2bb5576632def2c881f10dba013cad3a3559eed014eecbe9a312bd7d7dcf6e7312de36a3ad310a72a24f12c5ae9e2ea43c8f4a5f7ada4dddebf352c3ce865cab0478783b45be54b36fee788b84e9d13cf229a2ddafdef61b8538636ff0f1e4b9fa2a236ff74608be595941aced141ad1700b30ec1ee709d8692d224ebc67d3fef441ef4e9a8419598086ee01c632f503a068a0ebaff69a50b6bbfc32b72f954cd02348e5f6e67f3cbc7017963238f82292bef830cbc763c1bfc6c8acc3ba5871759c6b2010922bb50cf793f54d0c3c5b59637381fcc03902b29c227881147b9c3f6357c863580058bd483b8a74e1c1c4f53f6ce8e614290cf499d4b74bf68d48c6cc8eec4b2d714a9e9e828207b70fe9830b25a4c40c91715b683ffbb0fdf3c5856cfaec220cbf400ecd80551c69c9b001481b27f54bb2fcd75355bc2046830507c625419eb677dd06cd06b591ed7a388b12b9af78e3f78897aca4b6e7a646a650ffc4a4bb866d758d3fa9da20520e8aa15ea370ad0ceb9e973097467aa22b3d94dddad3d516d873460906f8953e58011b5a08dc5f26bd428d11eab34a871d9249946d58446826f2ffb9fbb93fb020983073c785ea260aa15df12d07fe549d3a7ba96088767eb4c276617b768d86b323d4957c842777560b4533a548f3561643f2b1b7dc1e23ecfdc4152af084d57977571dbdaf3c777b559f65e9e60e794c57314bdf8c8d9a1f75055c40c52ae0fc5d6b9f4355e968d0186b3f9570b69a686f0b7b80c14e7dd188cc59325a9cc35026022c8b9918fa2fff5fd09eae04e4b4a5945e032ccdb72c5fa3e60edc932973dd21fbf48f333f881829d1c1e2752b7f61d4fb063e9735609819e7f373704c629d1fc2ab5fa0323211c6ca6db1fdd2f4fc82084ccc3ba373625b760ede4d89189844aa1639ee46f1e4b97e1f7a4ad73b7",
+ "spend_index": [
+ 0,
+ 1,
+ 1110732603,
+ 4294967295
+ ],
+ "result": [
+ "a76937970d2a6cbb89815985e1c250fe926653d190acf2c89948710cdb0c665a",
+ "67c0a507a7ab1bdedcd53ed21fea39e218fc0c20881e25df91224c0c86cf5a51",
+ "28825f9efc56ee11571b204d728ce9c584bea95267e832a673dd2bcfe8323d49",
+ "065c5a476e658952244105c9a461c8bebadfdc82bfaa8f2149488efd88176e6e"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 5,
+ "Witness": false,
+ "Version": 272222305,
+ "scriptSigs": true
+ },
+ "hex_tx": "61c8391009518e09c300000000000000000000000000000000000000000000000000000000453a077a00f5322949e2eda1b3000000000000000000000000000000000000000000000000000000003c8bf33dfac0cf7f4a6b5c1d40b03812966620314f8a6225837a06feb6216fa82036c0ba8d70489215b4616e8aa341aaf83c3662a3a958b76c3f9ae7819a5a22b8fe0d9bd2d2c330c1a7f7fe4b860db1a60a6ac8d4cbf177a87532ef0263570c377183344bdcae19ada6594e012c5731651560342ded3b48b96acdb0c6be50f58169bed868c13c27229dc7a0945fcd7ae1ee00c4d1ab417cba72fbc589b8eb4bc22c020a424488da43cc41eac899d62e01cea5cb30da6c0ae2ba47ad77a60c4bfeba8b5370a0bdccde64835d7918f0d70747d5d2a06309b128e92fb81f4a21af39514a8e37cd11072542d8b3bcb0d20390aefa426d6f3c0b8eb70e012c14e3196442d03c24a58300000000000000000000000000000000000000000000000000000000381b152ffd340117dc059b024bcbeeaab8fdc630ab9c87882eee6f7fc1c8fb78fc2c723119fe5eb3fb7a042add14a3e7014471cd103b9b64b7daf954db237c874f728a74093b08f3dcbc0771238f610bd5a2c1e10561abbb310b0d84d69bc53e95d18e834192a1a855745fcd97ac55ae35c1547d67624fd82ce69d6c8dfe3be57937d97dab84a69509634e32806618585ed7c722350757ce2ba0d8c8d4e20b5de264aacdf368ce4bf0dba4b018c5cd824e44b920978cf36de74aededa0c969175523f7a15257b83a7bf1b51cfe8e5b15a13ea6e8d0de34556e6c3b3f086f589082bf86800f7d2be765d47a6f6ad36b02d04b8b2d2b7ce73e979a2434e3f9855f1d9806b42cd58cc6ab4836ae630885d8a9b69b6dd652b61fe39af0cef3deb8b834376c5350aa2c4014d397f1b21dcf0c3ac025d2e566de0564be350b1c7b62f53b8c1900000000000000000000000000000000000000000000000000000000108c7fe70039110cd93375fc270000000000000000000000000000000000000000000000000000000096c1158fe70940a6a817da0da129ec2b31f8597f593a774f10e9793178dd889a1eb6ea459cc5ba66452c6c360d1b1957be78d17aa782f85b55488b10a4e26cbd0b973589f5fd713f18f2ace2e53b9d5540db88794998a6bc8b0060b85569e0582181fb04fbcd3ebdd5518e4a82101d1158577b57c176131fcab97c5b30941a9f042515cfcb12397c4a12962d655c51757bd3ee7da31cb50716f7e1c2bdbc4e88866149f118085ebb0bf79dc8653464a5c944d994e937f5f06b3888838d67d255b5f77efc1ff73956477d9fd16a2d37736d1b0aacf3c3f4881093fb41d5417b8e2a1f70e64cadde534077e273a5dc435bf61da07800000000000000000000000000000000000000000000000000000000de3a04c3fd1c01d0095f5b3571d99a651bc79ccfc06463aad8e701d70bab6a4ea89cfd3b0a72e02c9e4902c866a9cf6683074d7ef1be4ca9e8838375c3d1776695d02b73acad2f20b4579a4547d0e05f52931411b8b5ac6a00f63d4c9454d12209dc80b25252ec0e2b50034a1822b4b5581166236aca296afbd76ea4644bd17b0a80fb7d101de07067878ede3d179e8039af76cbd89a39274da70b4f02acd1d5762ed99f1f075d7ba53891fe2b81d8e256797f7ec6da5ed472fc02512c5e00987dc3a8241d50b648d0e8ece70fc70f4c04ea6fa039fc7988645ed9072c253a9025207a593a59f462a2e42f2ddee41620d11dc31310e0224c005c19b444ecc78fbe8e256f489352f0e81dd7af6a52cba9560157cf8339e7781829efcceb6f9bb06506aec38fcf18b4cc5ab2000000000000000000000000000000000000000000000000000000002d11889b5761d5011ffef2b4bf421afe3820812f8bb46b0a4caa46255025edc12dbb403834369e4a6a563130a636917fc9255a8f66aeac3ad5a1cb699126dfd8c2e54f0b3dd0ecc43ba66be98e23804f1f46c9874ca7624eb0293ab1c0e20b296c3fd8d10000000000000000000000000000000000000000000000000000000032187b311012248dbd1e7325bd0f5f9ac534e217374b070cd132c88a86000000000000000000000000000000000000000000000000000000006ccfb6db00aac41921057c645006896fa637c88be739c1364acfc641c44095a047f212d9edd51ff417f0cb95e6e5b4bf175cf5bf7f471d8049f19b7472ff0e2fb9ee0212cd22b68b5cd845e5a657604ce44a54f1c9257f55365874ab996feee51d5eb1cbf64e49fcc7a59a2c6ba06f96070090f318c7fc1f8739cad50a557adc405e66136a1fa086fd01a84b11bf783310f791f51288ffb063b14dbfa9a491aa8ab72c36e61e552f468d831aff3a639dac505b07eb9e37ed8e783c7f53f4380b61d3c5d3f931537bd29da2ca65498d719a149b89dbeb6748a42908c15b1535b8d53338c8b098268b7d87cd72b348cbb2e5962575a2443d0c9f3af9aca6b1922c4e89d8629a31676b8e9eb56a1af1f80ab64096c327d8f3b1be930e03fde7b887bebecd8c1ba7b43058502edc1dc41d298338decc8919c254435a8ed69dd1d4dd0aaf042e63fff946d38ed0a5a01e1bdd135e2a9c83d9b1269a10ca5cb4c65f8df4c686e681d27eee6056640ab273e8b5501980287a20e6a68588bfc5362044d2dce957e6b0c77bf7b063fad2678ea20bd10d8191fb81f02d844f696a60e203478b07d7ca753d66b2f81f40b3afd6740a46280725c8ac171dc361857d6e53b3348a4c122d72206f8c045ab87f937ab78654e9f448a39013c808ac58e1fb6b3be406bc53b40d30d7ff0d79a544ee5be60b67213394cc8bb9d086792e03da60208f0647e11706423142306a65a7f2d7f0cf08a402cba8d6ba34caf114ab20cdcf22350424d849a9514ac6ddb96a737be9c01acc919409ad32c74bf2b97d23c68e70917a63d8fa28b87e38f66570281ba2cad85c95477a700a6f6e070ebf0c2b90efd14ac153ecb8d885699a53a98bfa5babf3ce2fffbb744b476590c291643fcd5d8d0a8f2f40c8fdf3bea971cefe5229c5fa5eb00535b57965ef4c0f4a300e8a2f4dbd1d5b128dfd6df48e480f250f68a80b4473cb65dd8001d014f3856592562673ac8877b3d470032122404df93a6d562460cfb33f1919949cb4802987cdb4f1843302b1045602f0b1321082671c854f5b7caf3381f6707dd34809080f01cf999eb62f01efd0157101f62a9a6879d25dd557a3dfbfa7b11af27fc61a4cfb164c3f554db0c421910f9dc06054675ce7615f0b99f5da60fe82d391279854d3566b220f303f49541eeea5b67c997f72f1bb67a42d4e6334c8de11cb2f791a817e05fdb08d812743a7402bce9197e29ebfd9e999de913ca8769bc0e674612c0d567def8c1402f35fab9c6c81edcc03a8f7d975e0e7ab2627e83313e9ce4f9b12d56bafc2b8ce1397d0ad4643e7eec4db82673643e64c5cb833c19c13c0b74c96a4544e1d1cf33fe97f4a374980f4ff2116d582a784c8ebe01e31a31e1192eb78d6140670f9e4480588682e09edcc2ed7f2705305e058bc5d70694b94d3c3a6628abf900cb9a5c7964859535c49cad5fd5d875f8816340b392ae24577128ab5d1c9de7a8425",
+ "spend_index": [
+ 0,
+ 1,
+ 2869676934,
+ 4294967295
+ ],
+ "result": [
+ "ee6b346a4e975ff06aa71b2d00045a53a5e11c31f6e7b3f82f21484bb5cf8566",
+ "b9057ab45662d92efae0349b7f66fd857fbdeb10cc4ddc98b2f2e51a461fb30c",
+ "94528b90a2039bc506108d367bbf257a5c06e72fc58fbff1cea4a5ef33e4698b",
+ "7240f3929afc6c1a7094bcaee7f4d084539b6d454edc2368730a7708d4a7e6db"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 6,
+ "Witness": false,
+ "Version": -1826872246,
+ "scriptSigs": false
+ },
+ "hex_tx": "4a241c9302d12365ec00000000000000000000000000000000000000000000000000000000108ebb5200e960a377c5c83a81000000000000000000000000000000000000000000000000000000005a87644600bdf1d4cc060f618f5e1d2e4c43c8fcb5ec9822975995457d6f02f0e9b6922319ce2d3bca0325ce352e7726c00509268931c90b66d7c6daf1d8f664a7087ed8a8597a42df0984e9780618666ad36a9aa691c87c85a5714f3e0364d41eead90b63c1ee77626b3a84a4a7e66e02f68ed431f1a954549064889fb35ca43bd5afb682c4492dfc44c86ef03e4a5aa3eb22e346030de38487ac0095317f36db93c2293157e8d56968ba9761adbac0d411110c30674c4b14ef284cba11187691a72a1ef66c8cb1b58133e458dbe3517be8260cadb1f9b2c4104b6b42626a1322db0cc82b61385816f84cc544277fc53a7cbdbb09d7f65ff6d77159203bcedb0adef81e10c3354091fd7020ebe20bf853bddaf795596ab0c02e70af157d1559013681a7f54d0294877fbcfabe137138be3ef74dd35bdf7af6572d41b4b4b5027a60132b438cb37cb63aa7d2f1ecb6617ebea1cc7b9e7bfa500c647f04d8307a88c4e0537d68e5c6a0fe9980e3d60ba1b84e25043580e9f991d25236edf7cdbe9d57741f3ac9ea35f3583e33e51cd8f479cdc53903491fd3eb390c7decd2e42c11c566e632ffc3180bc7f441243d27c9d083a842c85ff88ae29119d379d894c0480eb9cc793fcc200f9ccb6ab3771be7cf2a54004c46b22be8095cd6b9f4476762581aff09c128298006ebf3ff3cb6a281554dfdb52f8e6ef4b0a1bda1c77b2ccd185e8ca098ffc40cbbbbc41b3a2e5fd3d07d9b3567a008d5c8046ea4213801f1c8f57e1c23ddd04d490f9f38493d1ad2727039676e22359d55633ed1719e5dbbf3fd51b47011b48fef1693f2c10094bf52f87f705c1442f2537daf0ce67a3b1246c5126214ee0bd216e218ae22f94c0fc61b7a21675bc8fa8a38743e483d0faa8261d629c847448d7cd53ebf30c474a83bf7ada56f9b55d6c2d511a7e0c16457bb66ea518379ac91bda11c765ea0e355539d43baec4092855fd8a0f484f50a64087dea748a75a696670b776cb2481f65e2e392b0a35527199f68bea64e78c04306a0451b32a5e59c2a4082050af27e99f447836051265bdc57370f9ec7852f213accfdfefddaab52e8965c94e1fa95658d7a029edb97196c94ef594adbc8b6b1431533aa4b8aa7753d1e5a8088ab64a53c6dada3835279811eb0fa4913b31ed418c8bb5be24e8b315546f8b82c90990f360a4eb000c8b45a5d72bd1d91381c018e12e5101b5fd7f1a13fbb45b003d474406edc7ce34b9a2d593bf7caacc4b52d438ee3d8f00a418accdc2c7344e51688894201410385a7a3948fe15f9ea44423e7c3042928cd367a690afab83af5cd2b890c0d69a2b6118da7af34199b4cc06bd4905715748779b4d7be96467479368b4aff7121308b960388193533612c021c65ea62f2ca0d74ee11cb2680ba25a21eef49adfacaf098ec17a4d5be2c2b451743c5a140b22e28fe96a22903dfcc6a63f1f37be56f8f8880a60aac3ed947a9f4541a830e9023c8769655597205a607c4166c283585036e614ca444cb9878d15a1ae3894da69ebf609d7b2094becac5441150fdf6eddcd24ea6cf4d00002ce72daaa305b8649f55dfa370148976582c3a589a5fe9d7fdb23580172720a23d316cb81a83d83d5b440720a3b6981f774dba3c11dfbdccb31d160f72cd8839b3a67a08bbf4ac144a9c6fb1a7f01a6d4177e50788a0b9a5395882e741ed0c65f717f566b02f9e4c3997f46b0a52c3cbc9809aeec5d55ebac828a21142901f5d9ea10040fb9aab0083fa88a7456c9ea748c698f21d92",
+ "spend_index": [
+ 0,
+ 1,
+ 575568086,
+ 4294967295
+ ],
+ "result": [
+ "5dd5906f251a5a753ba3ef3749f2c31171f4441a800ef9997179d439a81d5410",
+ "2769f08ead076d90d001028dcad018c11d21d71b70a618cba5dd00787c008507",
+ "4611f46892da7ef37639e6242550dc7722072b3a20eb1f63ce190d92e92978c5",
+ "6bd1b98061e20e755f3f82400a850792f9636c4f67984d5657b58bdabcaaf606"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 1,
+ "Outputs": 7,
+ "Witness": false,
+ "Version": 1596452751,
+ "scriptSigs": true
+ },
+ "hex_tx": "8fef275f01fe49fdbb000000000000000000000000000000000000000000000000000000003fb453858a65a0959c27b6da7959f75e51d9a20de73c5d5313df615a82bbdd393e1d4be462e6d3f4ac48be4ef5dea637e06fa95aecf8a570547b6fba0ac4756647233c688ff095fd038dbe503e59210b38605f8405b51a469c2afd2766ca8e8437f9eccec71b586eabf524dd35d0acab8378d09d55044730e9572b803429f304f1d21f3a45938c2fdd2806f01f5708219546fa07dc9bc0903817ed4ac886ed3fff82070238dd889d3f39b7855ea48ac42844ca8cf7aaf21fdc2462255a5f3eaa9991c7676f9a606403cca61af4da1f47bdc29ef4b07d664a74bc76a5136f351418a64db6b83340d7fa2c1e9f62b92917295bfb1e5932e7a07e397e374424f62b546ec1a0d2c319aede4e7073c02a8e5fa72feb556bada1d8f3fc6b3a391ce7ad957c92eed821576e428ea72c9d18a3f6bf1e0983910ddb1525e0a9cd3690c78919849487e94c9c203136da237f548a2824fbcf3872f9a885dcf5dcbaa4f979e8054bf9c8440ecc67f709f11801c8b77f53d2bec233401aea58edc418bb52fbeeeb73de750afd6d6991d98ed5526a27ce76e6024173af3b55e9e67c0b7c7328c8a9098af189a472b09894c4a9f43792ff5c6ed92e98152eb79b9d86ba613c7e187201868998e95d92b6bd9f335f68dfc6c84fe654507be9e20e01b262b4c3099c33130e59192181a5dfe82b8d76ac53d0870905e807056c77d753cb0dfc2887973345a676bf0c245e2ccbce2d21f665d461424ee04e7fa3cc97b7bbfb65aa5a03b843cfb14ea058c7abe066ffb9262efbf3460029a59fae824a0421af6642c8276a9ed14c0622944877f3c22b0d7197cad24487fc9fa3c81cb9868224c4141226714bac6b21298fdecdb58d759e7e4af629de124514536827ef1bd153e552e6176da597705e6e9234194e8a28f87be47ec9b4ce9bc07566a7186009a8d0d7d8c2cd475ebbf10814f6e51d2a6a4d1766d977b644275fbd2302505e5ba0bc1228a39c778671c0d4c5bacb822bf1074bfb680182691149dff7187689f92d84f494192302a279cfc369d8e15551558f71ae1afe737a8285bb629c9d91917406bbab845c2869537a9c3c0a550d1ddea96366c817d6130c5e450fbc0352063e9720f80ae4fdf2f1ceedae79d16b3458b75a72bd69ef08d0a110e510d54ae0e52ae44f1ddd510a74ad04f901883615d3bdafbc76d917a10fcdd96bd205fa6b18175ead4db6149b436957f388991defe8a8bd0aa6813d684babd9c6868c180fdc20ba6c7c12d17ae590380a355c7b7e5b8c0bf385c45281ea80e5306c41443eaeeda6bae67432cb606ae1da4aacde09daf6db8f5c034aa9e3fe17b770bf439eb743e7ff68864114e0ca33ab6de41b67119b5ea9c26feeab700eb190d9e94bbbc09eaeb060c89549b3618158a9440d8f51e94f09d0fd542f713b12b2aff73373c48f4348a12944cc486f151d678da06b732ee4da6adae212640075fa692e295b95a042cc4a7643913c08b3872489f0a07b3a008ff943e599501f60d6a60843eef1a7323ca96610bcc77f03f4a36ac0d3e625c515c8803e603362fd76e6d6aead7816636a9dbb15d3684f995a0f9be4b070811f9d7edd8c31f11567e7c9adf35d918a005eb6baf9081590497c1f6f9e882271d1e374d21df74a07c0f136971964f69ce019699a3071efe791ae7aad8cdca4a86709916ec854b57ac31c8b93fe6a824b9793a5d8e4151c07331c8eca48c6fe4b09b56bc42f1fedf9e9def8a0f734d832d6e2cd9b78f049c06d9f26310e536aba69d16efc7aeabc5136414ecda08c0dd8f4725e692243df16e17ddc2acd76c138a02c798ef539c2b048bbfa98692f20659bd1a8bc17f59067ac729c0358af46153b674597a0a2c2f8523f4c21e42198c838a8ef94664c5a4bd691f4af43f7afb570017cf78ec311c148457b780515dc70e9aed0bdc978fd90b74bd75b327a96e0c8bb69871e17e6617b38b3de51b044250b6e4d910fc810cd36d82ec14a9e176946150dd691a40f8f8e52574a9fa78d226bc6a0dbfe4b94f7ed9d3619f4fa8379863e273b569b14dcb4714332de37402f9f0ee5d97a441f9ce5200025286bc6b37ea58ce5dc679f695de3c6ba067eab629365332a28ae02fde53679125b5d93c7f760455cab4582a492374f5555594169b11e6af3799d780f0eda7e88f51949208a6abddd1fa80e3f35636852e68c7bc0b09faa53286a57ab82ce770fdd443e6859f4036da74169d701cb04b37361422635fe1b3b5a7ab26f79d996cdccde795bf000",
+ "spend_index": [
+ 0,
+ 1,
+ 2439581743,
+ 4294967295
+ ],
+ "result": [
+ "0561d3777d16886c59dc321139a81652a2a26d0d3aacc2c8a4395abc2ed72106",
+ "26743f36d47a4672e1a8ea8830b07602e6b1c678a197671cf8a48c73add9ea5f",
+ "f196979a9156393464a226205342856f82fcc62abbc261ab8c2946f01acbbbb5",
+ "41776e4b5ef0612e56e84a77efa8df83a3554d84f4014c4c5df3e1560562a5bb"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 1,
+ "Witness": false,
+ "Version": -992228038,
+ "scriptSigs": false
+ },
+ "hex_tx": "3acddbc402bc0caa1000000000000000000000000000000000000000000000000000000000037880d9002373515e48d037ba00000000000000000000000000000000000000000000000000000000fb034aa200a3c107b4017f2ac44961d7e119c8a65a431d1ce4aea903feac3ba4a98980c1867d9db4b80697309cac4d2f756348ffcb8484d8a5eff8c82a5f1a9cab33558e98ef446b0358ca6c6bfdad11a07834e3109b9609d318295ea58cdb80ed4c0e40cd6e994fc58703fbcf603cf966136a3b9ea86531381adacb45f0ad0999346663d732a9313125a821c094cb1a55dfe031c91332853f0ba4ebd62b20ff6e968f7dcb69a128ebb28ca1739c8e799c3a4cada5c9ea33b0c49d6fc3413a82305f8f59b30a6b97b6c11c69e30075abca1248ec560f13fd7b9a66304fd75e",
+ "spend_index": [
+ 0,
+ 1,
+ 666533160,
+ 4294967295
+ ],
+ "result": [
+ "1974f6d3689556f16961d392d2a2bf6665774a95d3991a3c207c2169926ca6b3",
+ "496674f8a4c0b3b346643d324779120d5be39e88cc3a5d7be38c4616c4653644",
+ "02c31a6cf436367f5ded051aed47d0965cdbbfb8e14fcec9833f7f0c44e9d035",
+ "988c1e9159cddabc70e14486dcacfe2ea64cef3aa4d81c2c246ff6600cccf5a6"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 8,
+ "Witness": false,
+ "Version": -664652085,
+ "scriptSigs": true
+ },
+ "hex_tx": "cb3662d8027bcbf7f60000000000000000000000000000000000000000000000000000000095016521fd770136bc66af182202911250cee6c5b1038e5b4b853d5efc59c1700253f3585183d380c54f08b805994b8887917f0af61d64decbc672140c8aecbdabe3930ed585851b5590c33497e90c337852b0fad85246907f3a9768cb3b6537630fee802f9dcd4c7fb24001c4108d5c9124c36a8a9ec5ae26396244454237e9e8148a22ea0190054f39da11b8ac77fc13bc0bc6e2097caddd89973a6cc6867b3dfa2bb765337402621db7d6efb80ec92aef6f5f411ff67e5329567a0a2aa1edcea25552eedf2bf26c8cefddfd7ab778beeb540de8423f7cebc89af8d20b148c7657e0ef7993d88a70a6b091695f156d9c097df181de8e01ff636bbf7a8b1e2ea29b5832a6f5af3ef6c80e7e178d23a0b0e51e4a689617b95441c4bd767ac5330717813b1d10413626ed1b77a489aa363573d34fd54f07d1857b98bbe6ca549a5bf55fa412995ea7e8ca13b8aee7082d42f03a073f11eeec959189483c6b2a072f388e0bc126b9fdebf142a67be0b3475514b5fae1e271331d2d5865ef9ed150771547258e1d00000000000000000000000000000000000000000000000000000000b454ae62fd0701e6da317e90912ab6cc63214153758de06c9cdf5d46e3643e61f7dc6d0026123dc1bcd10e37ee3ef44c5f025d4ae537b8e3ab685089cc233d897fb089b2986692e35f22d84591af1a7b3fcc7cb5848f5037c99ae16c07fc99549820dfa158da97773b86fd38061f8324de927217bb7d28000b43303be10aced03637cecb33565cfe11f69b27f247e80e3d3aa1afce145bcb53e5e592c72dbffdd2600bb7f7b27852e6e436bda1224f152ff63e038b72f1fd71f5e53c9f7ab22974ae453505dd48a3c88b526e229417006b12c3796cb5184fb4c1bb0c189ddfc55ca77196bb9a11f00eac4599324cec962100d99a035917a29ea61bbfca5dfbd84a903334c104d2e0b9209085cd7a4b90c7db08e3ec36a15f65a215c8d14435e90a9c908b64ec88b815ed0aa7b2c2d592193acefc7b3e02c8c9908c3718ad2d35d139e1c997ff2f121cc636b1da9e4903fe47de4cede8ec6c08a5e23129562acc8868eecf8642c142fc2b5cf9cbc792a17d58387bf945df6cd136059c191ee1f3f8d8e4aa919c84217e558e9514ac7541997be3e1608ab76700ddf83e9d0abd78af7fa47c167f8ed8f840de5afee83fe0275697e8dc42f2449e07bbaf7f62f560912f05fa91849de6688445c1d07b66019367ad7d5b83d58187c8c93b404bb3024d8e98084cea773e8791e756c87e31323e72908e67e69788368e6cbfda79e3fbc66155deea140059acd53e626f1ff91d9f311fa7656c4a789b0ff413c55b6be5c53032f4ca9ed128e0d58d1b6c55dcdb59f7b90a4e1c4607510d6209a8bf995953138906ab3c2d967a280e4c2811ff57ba4fa0f67035e2bf9024106b1ed612f2009224439b1b2842ffde61deea4b9814bd8a5ff977529a5668afc59eb2763a93e064579cb05ac385181f374bf2d7c18f1c7af3df634251d1e5e3b953d124389982de3245d86a4e9c1946936dd3b55c917bf38a1c8395b056114d065008c8919645852c1e3b8822b3e7f338885b10dc74ab947f53a2f6b380c0b69f4d051dd026db658bc2f022f41ccc25e1da8eb30315033512836dda46c4674e46378d3674ffe8d0746a5a82fc7dc283e636a7d0931e71a59068b45d209bd70640775672388db9f5650b7a71ae0edf65fdd05ac1958fd0327868d569c23d35d400e2fcb784fe12314bd3b1f5338f7d93a26034f60d36208c71e7dd7928da1f0895caa301988e9f86ec972d1e7a12c3bd4b6609f14f704681523b01a25552c4bc77b217c0a7ae0a71f5dd8ce13c46515414c48379c89a114a65357c3dce83608347ef99b062080226368353b2273d3c7f94fa5f5c5cd0df9fd80b05a34f411e949da1850e0a453565fb0890ec10c165a8abf1cdf4606ae66fdebac10174f0ce40cf32f237b145db90b6fd915ad12e4b85077450f59d63f0ee9cb9ee48c777f8357766a70dbb68d2ad2b7ba33cd85c6e3be0a90d561813b82dc114b8d08a04ed742f11715accd1382eea179f73f51de77345a132711d425d6b5bbec08b1d6ff6df487132c7fe9be2c05abfd7f9059584533c503f3ff989e1ffd2bb622af3016f319c18abaf0ac8963163ff3dfaa1b52b50c1d06ee489c99e43aabdde819f6032cd57a0e2979c6a487b57b93a062d19829f55c38a3657b564aedc969184b65ca0b038be1aa54c931b3daf73c421c2ab4a7ec7fa65a1f7141fe97e8876bb1082822ae63d6985d58de4f1454880817c1e2a61eeded0933faa2336cde273b30da047ebc7b34fb802824947b0c1c7c0b133affe55154f88ff9071ceec83f479c1fdba0a4cf30521870191a4118b5d002c4ccfea5f91744b66d8e00ba1c11b208c720ffb77ef03ed229cdefba3facb3cb5ee939c9b1d2a7a0f20c85df17597d69d133466f234276e9fd6d3569ba2a4b2d4fa9d937181567dd2cb352c696a66bf6622f86f4d4a418820f1034f829506b687f62d3b22f225356a873e1caefa8c141d533b28dcc1b41b1aa5304214127e7a95b02d82d0ec6dc7e0b77dac914b59fd29e5ee9ab659067d43ec1972a3ed0f25b7ef70bd6f5e8520f91cf39ffdc2f0cb02a4385a4cedba018500ba734712b6d62356e6495f049c189222ad5063b8028ee2104e6ae32b3519d23a265ac7cb6efdb277763ff9e1dbee1f8789b77cbec15f186a2e55ef28980ee68950c864ee5a9bedabb0e9d38276617d9298c42ef7c62a9b3153db10b0971026fd7ef55570f75d5cfc66ae26d15d3f2b85533da7defff5cf5c892a9d693bc87243c2b385b25eb15f18bd1cab3307ae314bf572467b54957810f6a37b2fc55508e265c9c09d4f129b941a1221df796ff99dbc8a9d1ab46926388a1730c8f701c6c0057a51304796a57a49afe3c95515f126554997d55e1c4102fc068d48a12126e392d9f66a1e1aad2e9a6bb00dda31a787d8875b65d20fde8d5fe2e0618be0207cd6cddf6e18bcac2b9c92debf0c0a05d1f617c8f09569e462c5f5a5f2d4d59ae6bcc229bd8106b12e0694224992f946b944820fc2f2dd747cd20cbe21a68f6b0b79af7ff47a4481a150858bf8e0255393f20e4f06749e2ac0c2f255ea32a5349d4f055c631cea35f8e5fc1c3dd709659cb965c6536cc9d7d6d7b0bb0b215b26f7d530ef742e0d8562eb331db50308d99208b9d5dde4558dc0859cfddbf2be1f6f508b451ddaae6762dafe0c04fcdb7e68badf27540dcb175a1e3f6a6e3851261de8a357482b80af1850d923a16494a290c129c60f9ec0ffd19ea8ea0f97b6af",
+ "spend_index": [
+ 0,
+ 1,
+ 828453430,
+ 4294967295
+ ],
+ "result": [
+ "14223bb95cb5089ace31b5dd2fa54e633b9dd60cbe9622794ac6c7578255aeab",
+ "797f7aee1d48be9a28fc4f9316e689bb1ef5d309d0ad51a7f44e598fe96fe9d7",
+ "d9377c0a4b98b538853c775bd335bd2dfa620252880e9eb757f13553e32e6d0e",
+ "745147cc47733cf8bc8a5a562cbb61e3175f36e679dc61f198f0b6fe3bf3bc6b"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 6,
+ "Outputs": 1,
+ "Witness": false,
+ "Version": -1931027793,
+ "scriptSigs": false
+ },
+ "hex_tx": "afdae68c0620c4e058000000000000000000000000000000000000000000000000000000004f8d2d1e00650104588feead99000000000000000000000000000000000000000000000000000000001ac764b2005f8ef43b135c885b000000000000000000000000000000000000000000000000000000009f440d9a00541c069521d13cd000000000000000000000000000000000000000000000000000000000f6618135006f84fa6b678234430000000000000000000000000000000000000000000000000000000080dd391f00e4d2bd306fba136f00000000000000000000000000000000000000000000000000000000768c6d4d00257affc6013b885e35b58f727dc8b179bb70124ab89e49025858610b85f42f7ee3371540dfcf56395b5cc643d6d11a3ab736b7e4b57a4787665a7a3260fb0b213ada90e0eae735919c031f4774cb907b55ecf41c0fa8e4b6ee17b6a27988ee342d9359a138c0dd6d30f02c5810b1478ac0003f54a635a76028d2e542555072ea3eb1e8e0daed2aac38e4d2202ae2568f2b6ff839df9d1bff6df340d29f5c2f26919478b59cb14efa6fa2379238384974fc913b5471ec00eb97a4213d66d26286dbfa092dac2c2cab41d3a242f3a58374a3b38d4622716840a6d0",
+ "spend_index": [
+ 0,
+ 1,
+ 3362444138,
+ 4294967295
+ ],
+ "result": [
+ "67ab9ace43b9095f407f06235f14dd2f0de435cc176d84ccf7753f09d526a916",
+ "c8941602c1acf44bc263663f5d24ccdb050d58a0fc6a5a52d3c65e91b7a55768",
+ "a072439c88ad5d89e8f8ab06b07850788e54ecac24ea2875f025b71ac699db88",
+ "bbdb0d1a66f26cf1b26885c4a2163f7c4aaa4f9377413a94e5797bf45dd2a5b4"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 9,
+ "Outputs": 4,
+ "Witness": false,
+ "Version": -874883095,
+ "scriptSigs": true
+ },
+ "hex_tx": "e957dacb098545a2a20000000000000000000000000000000000000000000000000000000075fd30694825ebcd8f1e2e8342da01866f2f98334bcd4bcf63bd59af5d4c5e97ae1ee3f745a4d091cf2b4c2028be3d4afade8169a1cbe16f518784a42942cc2716c621f880c89f479fcab98aa39daf8c84e79ba7e200000000000000000000000000000000000000000000000000000000e6b2d11bc0ff4a5aa6810da2dbc4958b61a3f34de17d7bfe136ee243fd1136ea24d03b7fce5d98bce0a82405d8febe95aa7ec484ba72dcd918637687f646e38707a800968d8a96f7b4f6900041b1052a3ece6012706f1efa746fb5d1f8bb870d73eb0ebed1c54e980ddf5479244f7663002c94a83954006e6530e086e14014a1e53b3b8f93213b8a4c5343f337247ddbf471043d976c0fe27ce5fa25a5f3f7a4d1b8b679b179e3bd8075e711a7dd3c0953a673b6c7b14ee99f3dba804cda975bd187714b7f6b44972d68ec8ad400000000000000000000000000000000000000000000000000000000063af4f1009623c5357dae487500000000000000000000000000000000000000000000000000000000c2820587fd9d012809830ed0ee43648113c614a60ec62defa4627c78c4e0f74d2c5fec35e45ede7cd9122c86c2594c32cab8f78a6a2698bbb98f89bda48cc43cad7bf76116296b1f821f3fa60bb9ad18ed76c20d72ad8b62ae4afce66c6613807c1871c5db1c8487b80cc274ac7976a43fcda0c047ed385c853860dc9c8568d490303cbbf66f863ea1e1a621453539388561df7993139eed6a9a0c1d6fa4703aea5a522149d50b7fbe4e4b47bd763a19b1b70b24ba1cdaefadb6aad561ec5de926d8c17c8aeb3796ca3c93e2237025ddbfaacf1813ae29f75608913a183542977fca8f8cd280345cc61abe67a4c5b5e3a9a633330346bd9c6738f6a5e4f8e4f254863676745104a3076e2a3753fcc267ec596a77cbfe303f11f3881f753db96227bf782e8a31960c866b97e92d4a44fcc3af9ab8986ec6598a28ae9db0c222825ed28726ec00a091b536085737904bd01da260453ff9ccbc79a166eb21c4c00a6c0a2f4ab70cd5354abbc89b64adeb1995e2e39246855bbf335c4005b529d65a983f95452c88c299ec05296c53269204990eb481c5040eb1567ff8c132ec54b26ead680b59ad557be911759300000000000000000000000000000000000000000000000000000000c6fb0db0836334fdcb4c67336f070dcc70d24d625c5097c9b99e707776b7c1832b6682909c5daad5b83670510a6bde4d0b86ce0c96b74efdc6226b1a1f83c165afe56dea14455129b8c7fe5bc8de45ec4d77b8b38eee153f2a83fec943f58512c4432b76795b8885fe86cad5bc1bd65b518ae0e699b6c909efed50c6da3352647ef7791e8dbddd0192c01ef12881995e00000000000000000000000000000000000000000000000000000000435021bd00439c012c2bc78a9e00000000000000000000000000000000000000000000000000000000e9f9cabe003d9de2afdbc8746c0000000000000000000000000000000000000000000000000000000024fdd004fd9c01c3fb32ee1feaf1fdc4682dd4ef32de4a67869a89885783b0afa845136886b5f30aaf0241aa02a4815cfe2f7f2cce227a3bb5eb84d79789af7849d47f6230acbe4455231c2ff7ee5a30dc6d169a041a2aa1c3b753296f3b5cc82523a650afdd714404af6db979ef892dd4fbaba72354f30f686873491170ad12740e8b9547420fc5ba34444dbda398115c1fdd5c9284d98ded2d59a4220a2e52a8c954f1d17f150316f80c9d987175c080f8a8edc9a33bbc82413cd9cd8c6eff80875ef196bf0585e9306c348fc140016a99c66506e59109ebfb1a8e0120b3f557efc9915ca78244353d891fbc7e853a28486346834d0f750113bc34bf2c6b4c26e794df2df14778ca1a42ebf35033b8ab0747bf7d1a046dabe6cdc33061092d8aa9c10f6e5c207a84143606523a754405b362a2b3c514291066fc8f6849ca7d5ab9710d6cb5567a54f3f9b574a5f35da31930c5bd1a3b85d76b8cfde87c24357328110ba6c8531926639d65b386ef12b5b9c4acce40049a9f67ebe63a109a24a825354156a5ed403025b2109f6812f1b014eaba101ea6023940e39617279db6d1d762c38a626ca477fe4300000000000000000000000000000000000000000000000000000000d4f9b9e4005e92b09e040dfbac33a2ea2755c8262493bd17e8ba8591a83afa080308cda50b3ae9b5ce8601fb832476635cb38c22f0ced832dfce9179cccb2c47d243c2f0c55091dc7740a25366000618ac960e792cb1aeacb175ba9d3131659e9982f0a4faec22124975c92815cd010e061a04e2714c709dc3cb0555df751d5bf612c36ea45fce6043af9f5792b779c3bff965247d524e64e250d7b456f2767b021ce4949e015cb493e2c611301e8105c927ef3a9ae15b08032212b352d27d8e5a0497c211e5bb7ae996d8069b4fcc999a9c87a25ffad12cb1605658c7e10e2c577c5fc82a506744b0e97ba5e6ba06fb899fa58f761e046136c15715cdcb85c4033a05b326590ba85fb4e6374d425fa0c83069369ec7e4e79ca8a5199a6a5021e3b5b19681e9356e364d5ac65c37b15ca11ae3a69ffc0458a9cec356a29e27fa161d0b4ca746121cb4d8a7fc36c80ad0169fa58a034dd58bbd79683f225137d953e8906c17f8c40f8e61df754871d18e29950621dd33ba886677f8ff42b780f3b1b8e9b762f3d1af1256bc6f5a41cfe78b2b8bb9ec0e7f97b48ae7e645186a101d72f995ada4ac2cb3766a81c4be4ce6143d731bc8615a082a911e3d41523abd1367b455c86a6798c7a0d285c47259cddcd96c9c72e2e1d3858fed2d7d494d2ae56d42d963a767c74b133004b6289a35466609721dfb8c7104d989525af345649b980aa64c2dd2e5b22dff9d75b86ba49c7ee81b2a872ef4ba2ec76a4da4fc73e2448feb0b9f4b2aed0abd7b7d3ab0985b1052f1f1c4354ca63034050a2c440a369f39ec8366fd65edb0aab19907d18f34d573886cbe99e9ffb104136a663dd3b5475f23f1e76ee4f9e28f4b487a6367d336d88b6aba9d2439508a0747863c0f5fbf3d074ac863b7df9fa7cf663b89ad51c2faa53de17fe38f5305dc1097cf1c23cbb33a5e6511a6ffe751415043d4210ce46a79dd6e00cddfcdc785bbddab5c903256c71d5765ff455c8bfe511f0b649a3f8071014f02f03d2c6e14762a1dd45c3d9544a4c9981352038cb08b13bb708fe8a28b4345b4bdb4add8c5efb4953a155484961c6dee57a4e389bec716e8c22e772e48f0545a0d9d3230043d2c3f5e5ea9f70c0a0dde26a2fdba059fd80c276860160ec6afdac9ce9b397c0d25c4ae2cc48a508bc28ebef0abb8e6cb3651211f7c",
+ "spend_index": [
+ 0,
+ 1,
+ 162187532,
+ 4294967295
+ ],
+ "result": [
+ "0b14c77350be266662c94ab6e5f76050b4a0469ea1015aab3cf625bd35068cf8",
+ "db8732b5313cd230d6009e4ff51699d60a04e4353e591e3cbc3171af44ca5c5e",
+ "66da7e700214af7983f5b53dbae29faabd2189a67dba51601ca7f11e9d34d5fe",
+ "3070c3e90d0b5390886a34cb53e241c5a2319460a649a34e529dc26a15d4e1cc"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 1,
+ "Outputs": 6,
+ "Witness": false,
+ "Version": -958545809,
+ "scriptSigs": false
+ },
+ "hex_tx": "6fc0ddc601e38aa54c00000000000000000000000000000000000000000000000000000000873f54f9000d0bbad606fec9a289a0acc269c877da865916769ae8cc62ce89f4ea26e28f9f40bf05b52a829561155aae42e922a1dd18f540c85745c59e58ff76fb3301d098a7ad8634c2aa050cc83beb144bbb01170a4c1bf1ca1ce186433f67826a965ebb65a60358ac6855446dbf18393d22d8b87775031f98103793650ea36e99e9989c3f53490849378abb56fe00bc4330883644377541fc89c42661a8362a6f1693111491319afe1042c8c0b4f72434c2c778f4fb54cecf3ff89e775e817254e95fc04be0c436dc7e25ffd0f004851aba8796c6bf77e54aef1793264784af7739c846243d520b907967e6b3a79a582fecd923914b066718a8232658e7374b45c38473952343e45ba311a05412db5c745f5da4726313d07c0c5a24f773ce47a9d67957c0679f3a42a094d9478ff9ab0a87cce41e65b4af111478e6a7c613508fe6acca9cc4db0685849380a7e83a9796bc7f22eaaad7cb1c21aaac860eb4b653ad4d71b27d6f092059d9899dafe6589dfe571c24819d82e92afe96596900fe5dc48dd6c2d441416347f400e15d1b799727274350a510829755ba0cf1f675bc88e0a3b20a6201b38421bc293a4026bee02778c83f3b19c341f5d93eb71e69e4ebff461c884413a22f30b27c85a981f740e528dafe7a0dc9a5b4fc025bd01916c122946110cf049825032e8e7e758db978b2f66d5e24deaa245ffc2ebacc91f881b7a6843e43ca4b9a41caceb531b948fc74e92f9d457e06915476b1b15f03b7c53ed8f126e9304ee119b7a818ec9d0030d1a37490f7e69c8adc1b39c5c05899c08c28bb6b76c1dafa14a0b7f3fee2accbcbd01e50ab1c3d1eee738a866bf5a79ece5a4c962fd32f3aa20709fd7b45f0beb643ac3ba33480c1d8bc7c6bec514a6d8ec41fc8d88a5e0199abbb814edd7e706530a5a55c260034e081bdee78ebc1a8ce732c3b3ba02d0f5e38b0bbf6cae18794976581bacfc3b9d7d537757a36ab1fa5f4ccc8892160e736d69016ffae3dd8e6cfe5da67316c42ca4bd899d1f5304a830939b68c512c1d8f0a1cc341b538313136077d9205ed88615cc2a7a5c7d2d106e80d77c3f32e73534ef6dadcf5d9e0b87e5842b6fabe4358710ea71942a3489ee69a77027f7b5c053b4254fb6cb7aab584eaf515d469f1e58b707fec1c9f335ce7f04505c5ece43fd8bf944ce0c4b1cc510528c826d016caccfc30cbc87ca721a25cd9e8514b192fc03dac8baa93e61185b61b7d0b3e6adb979716251ee883553076b0653fe2658f9bcfba7c765ce79249a60e44a5aaaf4228f6eaafbf6e5d4a1626bd0e07ec7fab15a7c30bf4cbd1976a8e56baa6918204af3f0766f58041d00819faab5eefef348bb1c1e486429d7ba37c2da29bd6aa21e574242c544eb26ed5ea4c0e8d48e05cdce9f2ead031b2ae8cd46896beb9441b60c332512f5f1ad0bdb71aa52eb7ba6e69e91effd34be469cc4a51a1729e7197750e019616d26bec795e6f66c8572716eb8d8443d7039d7b5a37b53ff73090531e943e95e708b1106b09346f6e17c9b1a1dd8c34c943794299e38723a38119b9b9dc67da4f1bbf8d273251932d8d1fc78a4afcb2e45d59c92fb16c8735f6f370c25edf6e43ae0b72d24ce7b027e5d09778569dfd2e542a9de12d495ee952e4ff98f082c36be41a464425cbd8b14e49a0c23e978d5bb4bf901fd8b82160599cfe2d09bb10c5adcc59c55cfee9502308f4cd1985c615b2a288c5c97e416293e160b328a43cdce05e1d6c1555084761a439a2bd7cd686a5231fd3",
+ "spend_index": [
+ 0,
+ 1,
+ 3791416821,
+ 4294967295
+ ],
+ "result": [
+ "2e5006ac1922ac0c1ba24205e9adad753b39e7b10ada6a0a73caad4626a1535d",
+ "e3d7d29935fa2dbd398b89c234b3138091ce1c28a384970d745226e973bad9f1",
+ "c75c2b038cdc9f9af15f6b8a92bafc2369db3c1794354c40860ed783e20bb81e",
+ "bfe8372f7fdf65775f70a5ad3576192001c460aca3f57eb560facc45ada13f0a"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 3,
+ "Outputs": 3,
+ "Witness": false,
+ "Version": 28001504,
+ "scriptSigs": true
+ },
+ "hex_tx": "e044ab010340fa7ac1000000000000000000000000000000000000000000000000000000007cfa2e5917675ccc65ec2e4f6a5805c9ce83cea2bace928f8d70e25aaca507b0aea1dcfa00000000000000000000000000000000000000000000000000000000e10b5859fdb001877400ea9b1efa85855559c057c74c71e0e5c3959b36aed3f7203cb8bb86d73691348b0963223e8f780cf6347dbb73d0272be706d7a5e4c443e764c6d3a7cf6b477e06d95e49512340bb87a579721db5b7274fae15ee19545dd479a386a87d4a7c7e1d3a488e572e18f30cdf93bf2355945b299140675b3dff9f0ba3cd2ef22cfb2a4eb7d3d80980473310efc821bfe8fa56112ca4ce7994dcb269d4e41c39c118c2e555f89a120dfc2f8e47b7822fa709595f63e48a2e2b4b58bbc1d526f3f42237ee4f4a068c351b3b3e0d05024ca5c7b75a0e2e8cc5fb55177b8ea9a166109ac000515f30a59412be6f33e963d96899d3363ca50ea14ca78ffd6f29d2c78ef195fda6313a3deda1b592a2ce0e0ee4dadb1208f9f99e14078e484578d6fa88d91bcedfacc53b695d175c613b10ef42c5b279249c741b92c525200d52801c50afac12ec1b502f80e14765479af03ec65071cba119b68ba26f65284ae935414cab6667a0b643a44edea4b41bf9f0698e55cbaa9db64bf9b5c1cff02f485c1af6dd7ef0a16d8ca3ee1b1dc4118ffe250bdb113c834c3dddd1800bd55ff81956ea4054eeeed296af81add5f00801f9fdbabc8d29b958e947a6000000000000000000000000000000000000000000000000000000006362e53cfd6b01d40085bb5cb824f485eff1864e3d4749b50a38308fb6e2eee2b8595834b4bd89a33adab0dce1d55a1dad7453e60d4367435478a27d4ec517c6a8f578fb71bb2d6f504ac9d1db3a508cbe07324af806480af1218795faf985b97213f4e24f13acf39790c2a059e4a6e0ded11fd80906e71632cd6fc14708b4d3ec5d9e7e246d80f8c16cb37184c3f5ee897d2313cd103dc8446bac19d46f7835bc84749275f550d6d2b26e0298223898a342d86fd0f2e1025f97f847a11643cf74bd402f9fdfd73955305ffd3e98a60f703700190b676fe2b165b2666135266da41fb878eb02ab4740703594b80e2cd4745deb573b8c24982253709e713c77f1aaf00656623e62855b46449019d2590ef572a22615dcf438450a5321a008f1c82387db66fb4fe7f425811bad034df990724f37afbfdb610e6fabecbfcee59a124c0eccd8887832b739e3312eeb5ef1891ea02a7cc0609feed848548f48573ed5ed4c80e35844feb0f03e795469033fdcbcae946a312603a9d820f3b114ce1bc810c835828e295c467a41651a88e631884f46cfc19231eeb980d8010b9d9990c688280ec250da2cf6b4c80ef26ecccd58d68f38657131641694ac3811a5032dd3eba2867c4b25d837f60941d7bc691b1964e8dfebff94ea0ade2649d53c18a65767a6503b12772d1d7584a6bcd9a25bca845235d12393ba6f147861e79f2d145fd3691d315210d445be9f970d927c1937eb71031d61de998c910c4ab8f02f5489fb50e7f6276261c9da4ff7faaa226acbd24acc021f149d2daaefd15868136187a5eaa35876cac95c239f9ad5badc9d6bc8651d4c17338a92cb88328eb391c887ddbe7b57b7999bfc66f8b88867ac15a618e3f8be4e4dbd10d96872c627cdfe645fc78a38bc0fb087a34266cf5990a764221b1b4ca2ab92d37266cacb0091f8802ccdff63ca4787edfa0ff24df50e2255dc79619bfa756215b3fdb1539730a28c56baae728ebf0b6efe5063f37f2b36fffd185dbd5606657c7f96c2b75e6c8d7014e2cc4c514a4fce5adf7ff4f60f1ba90d9dbd3693cd6b3e86f125bd2aff4ddca60ab72f6afc7392d30ede4470092e83e92ad0cc938e98f8e49bf332eddf4cc50cc84cd0817a24ef5189c0da12a9e572a49a0ceabb6ee7c953a477cb089d597f54a5a873ff6e1e49d6dba7099fdcdaa82054d64cd4f8ef7c282775bafc31cfd435e669d102e7aa1ca7769fdc63e68e51039541eee399f20cf3f5e3a863d3e962a124031dd08a8d8d0043c35903537e03ce98d041dbfda7e679e07e4726f70ce6ceb957b15de5c88a9516ed39598098a21978eed2dcde79b10ae8378b951af7ec9ce672f56a12b2718ce991b2d88694daebab4ba9ed00215d67556d0e3c88164cf8619c812611022f0195843eed22",
+ "spend_index": [
+ 0,
+ 1,
+ 3820598746,
+ 4294967295
+ ],
+ "result": [
+ "a052c1319b824ac2c74620fe9e34b98e7704ff278e29e9d23b412106f23c4cc3",
+ "df732fdf2991619c2c1c8e5e0cc03dfe12f224259a5fc5578689571566280ca7",
+ "925ff3fc61a3204a96a40efc87b5c6830a0f1a1791204d12cfca674d0e1f4498",
+ "4f8f73c50d9fac235513880b77dbeb50cd5a37b9488a6d11828d0fdc49bb63c6"
+ ]
+ },
+ {
+ "desc": {
+ "Inputs": 2,
+ "Outputs": 2,
+ "Witness": false,
+ "Version": 365301493,
+ "scriptSigs": false
+ },
+ "hex_tx": "f50ec615021d38a93e00000000000000000000000000000000000000000000000000000000f31203eb002037e7ffd9301c6800000000000000000000000000000000000000000000000000000000d3fcbbaa00fb8133f202fa8882e48115c743c8e2d189ebda48f2358eae7232b1cbb268237cb7e56a298523d9d195f916c0ab03156cbaa63861ef45f5e66e1e40125f65e3889722e69b82a4c7c3cdfdc28259beb010c63b43356472e08b36e4872bb15b0a180a47a75d3b17f066b4d0126923f69a28f7daecfc60c523605a4dcbd9bbfe25543744004643f121fa5b1089d4898a920b776d1cfdb466102ed3426eb1202b857420a9dc350a3b2b359dc6e10e0e572fc7492dc2ab4d243e67d7067adc190f8e91158cc691365b374d80801ed126b03f2cd25fd2fc82f63c373c6772503264c8d76efd7523cb2b950a8de0f9be4f3334e335c4aa724a94c273ca23e899633417ba9433f6cb9f33d82fd55e6e5c24c21897821cbe79c7e191a9bd72a108c4f6bc23277e1f3a7ba7a0be9614c6175e64334100785b59386b8e5629d459f72972d8c4b218f3b3eb0786f8f71f8f0a1ec9cac6beb70a778419d03d03909801ad795869a7826b39f682917de9b2791d49951e67f8993956e43ab9bec8e8469ab1de37fc57f3a21ca084a45bd55bb3a9cbe102d47d920ce5cdd4446c801160a41be9601936412d03fe24a54ebf8570",
+ "spend_index": [
+ 0,
+ 1,
+ 701516357,
+ 4294967295
+ ],
+ "result": [
+ "d132f573cccb094cff83da9ef8e921e025c5c1c882c0566feab1b4823cf79563",
+ "c9bb3447a0d33de729b44d1e6a712e68af64b6c9238d1d824999ead42baf9f67",
+ "16d589f35d842209bcaed71275bda304a5e486bc962c96b0ad933a169f623ac1",
+ "0b703dfabbc5645f1840cb2c647a7f991d768e7640fbcf87d1277c580c60ef81"
+ ]
+ },
+ "Inserted without comma at end to make diffs cleaner..."
+]
\ No newline at end of file
diff --git a/bip-0119/vectors/tx_invalid.json b/bip-0119/vectors/tx_invalid.json
new file mode 100644
index 0000000000..31ce563a3e
--- /dev/null
+++ b/bip-0119/vectors/tx_invalid.json
@@ -0,0 +1,126 @@
+[
+["The following are deserialized transactions which are invalid."],
+["They are in the form"],
+["[[[prevout hash, prevout index, prevout scriptPubKey, amount?], [input 2], ...],"],
+["serializedTransaction, verifyFlags, [{\"if_unset\": [\"flag A\", ...], \"then_unset\": [\"flag X\", ...]}]?]"],
+["Use BADTX for verifyFlags if it is expected to fail CheckTransaction()"],
+["Objects that are only a single string (like this one) are ignored"],
+
+["CheckTemplateVerify (CTV) Tests"],
+["Modified Segwit OP_CTV Spend Failed if Amount Mutated"],
+[[["10bf165531fbdfac386f018d92d72dce3ad73af1f183f6fac2c7a2a1050aa51b",
+ 0,
+ "0x00 0x20 0x9e650578b4f13cde08d16211f3635239e22ba3e108ba7f5fa4bd6c12f8c8219a",
+ 155000]],
+"020000000001011ba50a05a1a2c7c2faf683f1f13ad73ace2dd7928d016f38acdffb315516bf100000000000000000000ae90300000000000017a9142b697af70a75926b158a2ea0aab8054eb18490ac87d00700000000000017a9143177919dae74db1c4cd3e6e69861091c6aee9eb287b80b00000000000017a91417d751e7c17c8264e90e4831fed9c47804b2bbc887a00f00000000000017a914a46167b1fbca936b56dda9710a0c16a53fd32fe687881300000000000017a914b4a5ddbdda32760d1c61dd131007fd7e67d650e187701700000000000017a91480909aab0729614b1162d86563cbfb0c71d5bc9e87581b00000000000017a914997c99e26f67463a1f9770003f90603360408bed87401f00000000000017a9149fef27cd2e724889aa522ac6b5eb35de7582727487282300000000000017a914c7c616d8323c7046de863e2301ec0c7884626e9687102700000000000017a914b590ca292351b64cbf725bad01c3ba6da808ab0b870122200a2891d90df11c7714549c76b80b29c86d544110d958a6dabcfcd5cda1612427b300000000",
+"DEFAULT_CHECK_TEMPLATE_VERIFY_HASH,WITNESS,P2SH"],
+
+["Modified Segwit OP_CTV Spend Failed if # inputs Mutated"],
+[[["7438c73c9a554540dce173b485e888683e9ae5beae3ae94142e77ae2cc024e3c",
+ 0,
+ "0x00 0x20 0xc19287614d027e87b85ace418cb0fc2d89241392370f0f7cf2ebb06b861c85f0",
+ 155000],
+ ["24040d2cd61f2ecb67e9fe5634c1d90e59b6b16028ff03003cf20f398ce27e44",
+ 0,
+ "1",
+ 155000]],
+ "020000000001023c4e02cce27ae74241e93aaebee59a3e6888e885b473e1dc4045559a3cc73874000000000000000000447ee28c390ff23c0003ff2860b1b6590ed9c13456fee967cb2e1fd62c0d04240000000000000000000ae90300000000000017a91406651b0a47731127630ccc27d07fb9afc041846987d00700000000000017a914c758d7ce652d5ed562253ed00e9afc34ea1f76bf87b80b00000000000017a914fe8740b477b23838679c7eaa6e452e66c58a72bc87a00f00000000000017a914cc07d98fc32e2ff65f62076f2824d63bd5a1628787881300000000000017a914acfb84e8356788c7a8312194d1833e5d5677d58e87701700000000000017a91409aad9fbb6609e4486fa5b04afbbde40659388f787581b00000000000017a914ffd3dc8f12ebb700dd45a6a58914347533b6728587401f00000000000017a914781456255e72a09dfab2211dc151165c62ab7af987282300000000000017a914ee01dfa11feb2bc68b22d6909052647c8c001ec787102700000000000017a9145dd4e76cb2cef90e09f181c55fdc42717f3d948787012220cf100c0bb5dc85c104d87c31e7b57a4a7791cc2091dc87ddaac40c91edda7f6bb30000000000",
+ "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH,WITNESS,P2SH"],
+["Wrong Size CTV Argument is Discouraged"],
+[[["13e313be0d1eab290bcf2b58f4ad76c3f4fd46b2ac4273c607cdc7f5a4170794",
+ 0,
+ "0x00 0x20 0xaeba7cb39e708a34dd186698a80cc34e70bb92921a01f853ac691bb572b52d62",
+ 155000]],
+ "02000000000101940717a4f5c7cd07c67342acb246fdf4c376adf4582bcf0b29ab1e0dbe13e3130000000000000000000ae90300000000000017a914f0ccedba146f6390e5961b2a0a39cfba046c312987d00700000000000017a91458d4792223eebb552801d6690b5985513fbddaca87b80b00000000000017a914774b6fe872b65890c610ec6edda928703fe8503e87a00f00000000000017a9148ad37662e56b5f2e472e4bdc205f0dcde8708fd787881300000000000017a9149e8680d850f172186f4e16cee442f0d0121fd46e87701700000000000017a9141394792d48889f70878ce2ee3b151de33d4b774987581b00000000000017a9142444dbb85cf5dfa3e94d2a970a4d4bb795495df687401f00000000000017a914b0437ba6b526e697e695d4f8a53482d26547b64f87282300000000000017a91408ceb5466bc28db2122f954ca59d4a4a08fc133b87102700000000000017a91486f51c990634abc769d6d9d01608ff99f93b050387010251b300000000",
+"DEFAULT_CHECK_TEMPLATE_VERIFY_HASH,WITNESS,P2SH,DISCOURAGE_UPGRADABLE_NOPS", [
+ {
+ "if_unset":["DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ "then_unset":["DISCOURAGE_UPGRADABLE_NOPS"]
+ }
+]],
+
+["Empty Stack is Rejected for CTV"],
+[[["e658e5b94eba5931faf2379a61a75a05b153648690527d35f7143bed462a6ebc",
+ 0,
+ "0x00 0x20 0x6c9cc4747e7d287ac1abf8c65152a78d369213583e306b7d3163e12c561abaa2",
+ 155000]],
+ "02000000000101bc6e2a46ed3b14f7357d5290866453b1055aa7619a37f2fa3159ba4eb9e558e60000000000000000000ae90300000000000017a914b038d0ca030a6d6bc4a06bda13ae1413ce96f37e87d00700000000000017a914fa5716162fb8f5f3cafdce1c1f5533e182c83f4d87b80b00000000000017a91417d10dea89621354333f4dfcbdafe18ec6a794da87a00f00000000000017a9142abb09f63aaecdfbe0e92fedc0afedf19194360187881300000000000017a914aab8b0219014272348de62cbc195e20151b7735787701700000000000017a914a507b83449359c82a195fc9bab99fa1b7c8289eb87581b00000000000017a91401ea6e7336fb9d5e5f36994eecade840ba938d0687401f00000000000017a914e5a474adbd25d66bb70c9b0b6a27f3eebf70b3f587282300000000000017a914d4ae33b227632cf0434f054782558baf9aa6e42d87102700000000000017a9147e4cca8f6c63cb7a56dd3c6edd2acbd031813de9870106b3746375685100000000",
+ "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH,WITNESS,P2SH",
+ [{"if_unset": ["DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ "then_unset": ["DISCOURAGE_UPGRADABLE_NOPS"]}]],
+
+["Wrong Size Stack Argument is Discouraged for CTV"],
+[[["e658e5b94eba5931faf2379a61a75a05b153648690527d35f7143bed462a6ebc",
+ 0,
+ "0x00 0x20 0x6c9cc4747e7d287ac1abf8c65152a78d369213583e306b7d3163e12c561abaa2",
+ 155000]],
+"02000000000101bc6e2a46ed3b14f7357d5290866453b1055aa7619a37f2fa3159ba4eb9e558e60000000000000000000ae90300000000000017a914b038d0ca030a6d6bc4a06bda13ae1413ce96f37e87d00700000000000017a914fa5716162fb8f5f3cafdce1c1f5533e182c83f4d87b80b00000000000017a91417d10dea89621354333f4dfcbdafe18ec6a794da87a00f00000000000017a9142abb09f63aaecdfbe0e92fedc0afedf19194360187881300000000000017a914aab8b0219014272348de62cbc195e20151b7735787701700000000000017a914a507b83449359c82a195fc9bab99fa1b7c8289eb87581b00000000000017a91401ea6e7336fb9d5e5f36994eecade840ba938d0687401f00000000000017a914e5a474adbd25d66bb70c9b0b6a27f3eebf70b3f587282300000000000017a914d4ae33b227632cf0434f054782558baf9aa6e42d87102700000000000017a9147e4cca8f6c63cb7a56dd3c6edd2acbd031813de98702015106b3746375685100000000",
+"DEFAULT_CHECK_TEMPLATE_VERIFY_HASH,WITNESS,P2SH,DISCOURAGE_UPGRADABLE_NOPS",
+[{"if_unset": ["DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ "then_unset": ["DISCOURAGE_UPGRADABLE_NOPS"]}]],
+
+["Wrong TX Hash passed via the stack fails CTV"],
+[[["1303ae3fc607b6eb3a4da63d3d7f4722b595db87890943618e11c3905662cae4",
+ 0,
+ "0x00 0x20 0x6c9cc4747e7d287ac1abf8c65152a78d369213583e306b7d3163e12c561abaa2",
+ 155000]],
+ "02000000000101e4ca625690c3118e6143098987db95b522477f3d3da64d3aebb607c63fae03130000000000000000000ae90300000000000017a9145850541d205b7b1feb1bc10112f9d739fa9a7dc287d00700000000000017a914d76b85e77e20777d5ec9d7d9998ae0c062d4669087b80b00000000000017a914c79f4a39b0580e4ec90e1b4989fc6124e4135cc187a00f00000000000017a91469635f1f4c06d66591282a02303b1435ee888d9487881300000000000017a91410d3b9b2aaffae25b6098169e2dc69928849215387701700000000000017a91456e4a3e5a3a49b9a66240288e79a8a5e8e31d05587581b00000000000017a9143936403d1a70b32c1e0e6920f9cd99cbc8a8345787401f00000000000017a9146ec4fa5a4e329f9d92ea29b65fa48c6ec1470ffa87282300000000000017a914f66743d56210c98bce8a44742b2ecfa9b7f48fdb87102700000000000017a914555c65f1c355993b46003311931eb08cf457209b870220a2638b51a692e6a8b39e87c431edde4fc1ada3dedaf9665875ac8353af44c50706b3746375685100000000",
+ "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH,WITNESS,P2SH",
+ [{"if_unset": ["DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ "then_unset": ["DISCOURAGE_UPGRADABLE_NOPS"]}]],
+
+["Embedded CTV Impossible with Bare P2SH due to hash cycle"],
+[[["6a869fd9a0395f35e412ad3eb7fffa61a59263b1ad16aeb5fcc30e032bc3a8bf",
+ 0,
+ "OP_HASH160 0x14 0x40aec8967698985eb369afd3ad3dc571110e6a10 OP_EQUAL",
+ 155000]],
+ "0200000001bfa8c32b030ec3fcb5ae16adb16392a561faffb73ead12e4355f39a0d99f866a000000002322203b8d241649e612058fd2f1b4decbe9141284f0e4dd297d95b0da01a5d8791e4bb3000000000ae90300000000000017a914b04d55bbfedf606a08795fb0c2655bb3212f2bde87d00700000000000017a914d079c2cfad655234e68159422727eefa78811b4787b80b00000000000017a9145ea3edd87eb790af8051da692f4d59e5be6ffd4b87a00f00000000000017a914e17e2c4f4fcae1ef0d5ef96c740565426009ca2187881300000000000017a9144769d9f3b6fdf14f1223d9e7f11be7873bcbcde387701700000000000017a914064529bab7b89253159c9043ef128f37f78add7a87581b00000000000017a9147bae64476db031d744b442ddee9af3e60ef1e4ea87401f00000000000017a914dd2d96d0ba673c0b9d5950223c334f19f2b6f4a487282300000000000017a9148abaaa7b977855f96afacea4c79e3caf5e7482c487102700000000000017a9140dab14b1ee04aea522639ee27d29a5f6a57758c18700000000",
+ "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH,P2SH",
+ [{"if_unset": ["DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ "then_unset": ["DISCOURAGE_UPGRADABLE_NOPS"]}]],
+
+["CTV at pos 2 with >1 Input Fails if too few inputs"],
+[[["eeda9ea077b04abec103ffbba6bcf41cd67cdfdabe5ccc6ed766b9cd4ed4808a",
+ 0,
+ "0x20 0x3e123dbe62352fa40471c195aebd3cdec43cca8728520c8a2d5737009fa05b0b OP_CHECKTEMPLATEVERIFY",
+ 155000]],
+"02000000018a80d44ecdb966d76ecc5cbedadf7cd61cf4bca6bbff03c1be4ab077a09edaee0000000000000000000ae80300000000000017a9144dd991d2f69eed133bb9d16e298703c830e1fb2387d00700000000000017a9147a50ac55b0af704dfffc797c507db803488ad44787b80b00000000000017a914caab97b53be0b75526e011bc49b0101365f611b887a00f00000000000017a91448c947e1b16103782a7dcba1dd5896936fbc7d2587881300000000000017a914ff075d852727e7e32ff5e11b13d254cb553fb73287701700000000000017a914761069764474d5ef5d0e068e88e4ebe2edd2336087581b00000000000017a914cd76c979ed6421f5d39380b5eb3d0dc7f56e864b87401f00000000000017a91417e7563571166469e14275be7ef00d91927eee0387282300000000000017a9140f9ddd36a76392fec584f05b34d33282fbd4921287102700000000000017a91417603536acce13cf7496387f8169a7f832f08f4c8700000000",
+"DEFAULT_CHECK_TEMPLATE_VERIFY_HASH",
+[{"if_unset": ["DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ "then_unset": ["DISCOURAGE_UPGRADABLE_NOPS"]}]],
+
+["CTV at pos 2 with >1 Input Fails if inputs in wrong order"],
+[[["eeda9ea077b04abec103ffbba6bcf41cd67cdfdabe5ccc6ed766b9cd4ed4808a",
+ 0,
+ "0x20 0x3e123dbe62352fa40471c195aebd3cdec43cca8728520c8a2d5737009fa05b0b OP_CHECKTEMPLATEVERIFY",
+ 155000],
+ ["b6d623f1e5eaaaa83a21739f60ac173818ce6b9e13ca18ddda74e9dbe6124c0b", 0, "1", 155000]],
+"02000000028a80d44ecdb966d76ecc5cbedadf7cd61cf4bca6bbff03c1be4ab077a09edaee0000000000000000000b4c12e6dbe974dadd18ca139e6bce183817ac609f73213aa8aaeae5f123d6b60000000000000000000ae80300000000000017a9144dd991d2f69eed133bb9d16e298703c830e1fb2387d00700000000000017a9147a50ac55b0af704dfffc797c507db803488ad44787b80b00000000000017a914caab97b53be0b75526e011bc49b0101365f611b887a00f00000000000017a91448c947e1b16103782a7dcba1dd5896936fbc7d2587881300000000000017a914ff075d852727e7e32ff5e11b13d254cb553fb73287701700000000000017a914761069764474d5ef5d0e068e88e4ebe2edd2336087581b00000000000017a914cd76c979ed6421f5d39380b5eb3d0dc7f56e864b87401f00000000000017a91417e7563571166469e14275be7ef00d91927eee0387282300000000000017a9140f9ddd36a76392fec584f05b34d33282fbd4921287102700000000000017a91417603536acce13cf7496387f8169a7f832f08f4c8700000000",
+"DEFAULT_CHECK_TEMPLATE_VERIFY_HASH",
+[{"if_unset": ["DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ "then_unset": ["DISCOURAGE_UPGRADABLE_NOPS"]}]],
+
+["CTV at pos 2 with >1 Input Fails if scriptSig of other input modified"],
+[[["eeda9ea077b04abec103ffbba6bcf41cd67cdfdabe5ccc6ed766b9cd4ed4808a",
+ 0,
+ "0x20 0x3e123dbe62352fa40471c195aebd3cdec43cca8728520c8a2d5737009fa05b0b OP_CHECKTEMPLATEVERIFY",
+ 155000],
+ ["b6d623f1e5eaaaa83a21739f60ac173818ce6b9e13ca18ddda74e9dbe6124c0b", 0, "1", 155000]],
+"02000000020b4c12e6dbe974dadd18ca139e6bce183817ac609f73213aa8aaeae5f123d6b6000000000151000000008a80d44ecdb966d76ecc5cbedadf7cd61cf4bca6bbff03c1be4ab077a09edaee0000000000000000000ae80300000000000017a9144dd991d2f69eed133bb9d16e298703c830e1fb2387d00700000000000017a9147a50ac55b0af704dfffc797c507db803488ad44787b80b00000000000017a914caab97b53be0b75526e011bc49b0101365f611b887a00f00000000000017a91448c947e1b16103782a7dcba1dd5896936fbc7d2587881300000000000017a914ff075d852727e7e32ff5e11b13d254cb553fb73287701700000000000017a914761069764474d5ef5d0e068e88e4ebe2edd2336087581b00000000000017a914cd76c979ed6421f5d39380b5eb3d0dc7f56e864b87401f00000000000017a91417e7563571166469e14275be7ef00d91927eee0387282300000000000017a9140f9ddd36a76392fec584f05b34d33282fbd4921287102700000000000017a91417603536acce13cf7496387f8169a7f832f08f4c8700000000",
+"DEFAULT_CHECK_TEMPLATE_VERIFY_HASH",
+[{"if_unset": ["DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ "then_unset": ["DISCOURAGE_UPGRADABLE_NOPS"]}]],
+
+["CTV at pos 1 with specific scriptsigs fails with incorrect scriptSig"],
+[[["a2522fa96033c5736f3142ff616426cd03a3d0f077f609e22c5a33a96e04e597",
+ 0,
+ "0x20 0x4870387ef3dc7b392294140a323ec7b38dc138710f0931ce27f386a57128ea63 OP_CHECKTEMPLATEVERIFY",
+ 155000],
+ ["b6d623f1e5eaaaa83a21739f60ac173818ce6b9e13ca18ddda74e9dbe6124c0b", 0, "1", 155000]],
+"020000000297e5046ea9335a2ce209f677f0d0a303cd266461ff42316f73c53360a92f52a2000000000151000000000b4c12e6dbe974dadd18ca139e6bce183817ac609f73213aa8aaeae5f123d6b6000000000151000000000ae80300000000000017a9143f163a8747557345ce2e6fe00c1894f2f281795e87d00700000000000017a9144cf13dfda93a7413b7e646611735656e5457657087b80b00000000000017a914868998b49df649c37a88d48c9d4a5b37290e507287a00f00000000000017a914034f9914a77571a6396482e9881745c92c3037c687881300000000000017a914a8238003e1732e2baf4334a8546d72be99af9bae87701700000000000017a91491dbac5d67d5941115a03fc7eaec09f31a5b4dfc87581b00000000000017a914e0c0f19fec3b2993b9c116c798b5429d4515596687401f00000000000017a914d6b40d98d94530f1a1eb57614680813c81a95ccd87282300000000000017a914fb0bfb072bb79611a4323981828108a3cf54b0a687102700000000000017a9149e2d11f06ba667e981b802af10be8dabd08eafff8700000000",
+"DEFAULT_CHECK_TEMPLATE_VERIFY_HASH",
+[{"if_unset": ["DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ "then_unset": ["DISCOURAGE_UPGRADABLE_NOPS"]}]],
+
+["Make diffs cleaner by leaving a comment here without comma at the end"]
+]
diff --git a/bip-0119/vectors/tx_valid.json b/bip-0119/vectors/tx_valid.json
new file mode 100644
index 0000000000..ae81070c96
--- /dev/null
+++ b/bip-0119/vectors/tx_valid.json
@@ -0,0 +1,161 @@
+[
+["The following are deserialized transactions which are valid."],
+["They are in the form"],
+["[[[prevout hash, prevout index, prevout scriptPubKey, amount?], [input 2], ...],"],
+["serializedTransaction, excluded verifyFlags, always included verifyFlags?, skip excluded one by one?]"],
+["Objects that are only a single string (like this one) are ignored"],
+
+["Check that CTV is Processed with a Taproot Spend"],
+[[["f90521604b56c392ffa17a01bcae5914b8cf7728cc6cec00d90838818cc5465f", 0, "1 0x20 0x24f5fe807bcee7774dc515f0b7ee8d6ae39eefd1b590264c52ff867e22c49419", 155000]],
+"020000000001015f46c58c813808d900ec6ccc2877cfb81459aebc017aa1ff92c3564b602105f90000000000000000000ae80300000000000017a914ce0036ae7d49f06967dd92cc1ffff4a878c457f987d00700000000000017a91406e00c3b362e65e03507a2858d7b6499b668669887b80b00000000000017a9142ee42c65592c59b69bfefbd03781140c67e5232487a00f00000000000017a9146b3df16a1e6651d582ca6598900cb4f2d6c9dfb887881300000000000017a914877d55932d4f38b476d4db27e4efbe159ff0a07187701700000000000017a91441e9dc892e861d252d513d594ba833cd6bc8917087581b00000000000017a914b93075800c693dcc78b0553bf9d1cf879d76a02487401f00000000000017a914e9f0ea3a2cae0ad01114e2ec3502ef08bbc50af487282300000000000017a9149a645b5293bdf8be72cb9d1460bce7d64445cfad87102700000000000017a91451e5d6b2ee24ae128234c92245df3624620ea7d3870222209eb65498bfcd4eb90e61c2c5e323a9c16c8bfd8d53ba649915bcdb572099c12fb321c0b7e0105780185688d998a8f8438aa07637a5799755688ec80175cb26c0406e0200000000",
+"NONE", "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+["Check that CTV upgradability works (taproot)"],
+[[["f90521604b56c392ffa17a01bcae5914b8cf7728cc6cec00d90838818cc5465f", 0, "1 0x20 0x24f5fe807bcee7774dc515f0b7ee8d6ae39eefd1b590264c52ff867e22c49419", 155000]],
+"020000000001015f46c58c813808d900ec6ccc2877cfb81459aebc017aa1ff92c3564b602105f90000000000000000000ae80300000000000017a914ce0036ae7d49f06967dd92cc1ffff4a878c457f987d00700000000000017a91406e00c3b362e65e03507a2858d7b6499b668669887b80b00000000000017a9142ee42c65592c59b69bfefbd03781140c67e5232487a00f00000000000017a9146b3df16a1e6651d582ca6598900cb4f2d6c9dfb887881300000000000017a914877d55932d4f38b476d4db27e4efbe159ff0a07187701700000000000017a91441e9dc892e861d252d513d594ba833cd6bc8917087581b00000000000017a914b93075800c693dcc78b0553bf9d1cf879d76a02487401f00000000000017a914e9f0ea3a2cae0ad01114e2ec3502ef08bbc50af487282300000000000017a9149a645b5293bdf8be72cb9d1460bce7d64445cfad87102700000000000017a91451e5d6b2ee24ae128234c92245df3624620ea7d3870222209eb65498bfcd4eb90e61c2c5e323a9c16c8bfd8d53ba649915bcdb572099c12fb321c0b7e0105780185688d998a8f8438aa07637a5799755688ec80175cb26c0406e0200000000",
+"DISCOURAGE_UPGRADABLE_NOPS", "NONE", true],
+
+["Segwit v0 CTV Spend"],
+[[["c16621d89637274011a8fb02ac487d283367f33d36de8c1ec8e323e55cb149cb",
+ 0,
+ "0x00 0x20 0xf47ad51491d952cb1fad0d3f208dde482561d2170ebbbbc08e2e0292eeb4ec3d",
+ 155000]],
+ "02000000000101cb49b15ce523e3c81e8cde363df36733287d48ac02fba81140273796d82166c10000000000000000000ae80300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d1870122207427029cbb0a48361ba1b83e4fff21918618477be3d217d83b2ff846815305f6b300000000",
+ "NONE", "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+["Check that CTV upgradability works (Segwit v0)"],
+[[["c16621d89637274011a8fb02ac487d283367f33d36de8c1ec8e323e55cb149cb",
+ 0,
+ "0x00 0x20 0xf47ad51491d952cb1fad0d3f208dde482561d2170ebbbbc08e2e0292eeb4ec3d",
+ 155000]],
+ "02000000000101cb49b15ce523e3c81e8cde363df36733287d48ac02fba81140273796d82166c10000000000000000000ae80300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d1870122207427029cbb0a48361ba1b83e4fff21918618477be3d217d83b2ff846815305f6b300000000",
+"DISCOURAGE_UPGRADABLE_NOPS", "NONE", true],
+
+ ["CTV reserves different sized args for future upgrades"],
+[[["e8e9805801b7fb44814531de0dd498b955651b9c25a85a043d73f18970622647",
+ 0,
+ "0x00 0x20 0x65f15821061635e6807f06701bf0a12d8e89dcff88df5968bd0822c9dbb52f1c",
+ 155000]],
+ "020000000001014726627089f1733d045aa8259c1b6555b998d40dde31458144fbb7015880e9e80000000000000000000ae90300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d18702015101b300000000",
+ "DISCOURAGE_UPGRADABLE_NOPS"],
+
+ ["CheckTemplateVerify Argument from Witness Stack"],
+[[["e8e9805801b7fb44814531de0dd498b955651b9c25a85a043d73f18970622647",
+ 0,
+ "0x00 0x20 0x65f15821061635e6807f06701bf0a12d8e89dcff88df5968bd0822c9dbb52f1c",
+ 155000]],
+ "020000000001014726627089f1733d045aa8259c1b6555b998d40dde31458144fbb7015880e9e80000000000000000000ae90300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d18702204d5783a61241bdef19c3480e094cc933c91d2bde995c8c50407099184b501f4301b300000000",
+ "NONE", "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ ["CheckTemplateVerify Argument from Witness Stack"],
+[[["e8e9805801b7fb44814531de0dd498b955651b9c25a85a043d73f18970622647",
+ 0,
+ "0x00 0x20 0x65f15821061635e6807f06701bf0a12d8e89dcff88df5968bd0822c9dbb52f1c",
+ 155000]],
+ "020000000001014726627089f1733d045aa8259c1b6555b998d40dde31458144fbb7015880e9e80000000000000000000ae90300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d18702204d5783a61241bdef19c3480e094cc933c91d2bde995c8c50407099184b501f4301b300000000",
+ "DISCOURAGE_UPGRADABLE_NOPS", "NONE", true],
+
+ ["BEGIN CTV congestion control tree level with 4 levels:"],
+ ["CTV congestion control tree level 0"],
+[[["d0246d069143263bca9a2b176fcf64bd8e4975c7670ed33659b4b8f88d3e7446",
+ 0,
+ "0x20 0x10618b50aa1120e9e940bbea8b6d081019e38fbb9b956b0ab4f61631d05727ca OP_CHECKTEMPLATEVERIFY",
+ 16600]],
+ "020000000146743e8df8b8b45936d30e67c775498ebd64cf6f172b9aca3b264391066d24d000000000000000000002781e0000000000002220bceb923d731eddf09705690d6ee697d1b3d57279ad96910cfb66a8d43a638800b3781e00000000000022201210e50077518896fd1661bffc2c1e88ad6e204ec4e8755407b42a97347c1e1bb300000000",
+ "DISCOURAGE_UPGRADABLE_NOPS", "NONE", true],
+["CTV congestion control tree level 1"],
+[[["b69f866d47ebb75eeecfbc3b9b641f926f11035b64ff27a5a5e88b9c065bddf5",
+ 0,
+ "0x20 0xbceb923d731eddf09705690d6ee697d1b3d57279ad96910cfb66a8d43a638800 OP_CHECKTEMPLATEVERIFY",
+ 7800]],
+ "0200000001f5dd5b069c8be8a5a527ff645b03116f921f649b3bbccfee5eb7eb476d869fb600000000000000000002480d00000000000022204c683607ca7950380df10647b223f656cd73d1f7ad67b30caf60d78337f913b2b3480d0000000000002220805bddd8b95a3cf3729b62703de37a1533b11634de76aa4a18605b640f1f3208b300000000",
+ "DISCOURAGE_UPGRADABLE_NOPS", "NONE", true],
+["CTV congestion control tree level 2"],
+[[["7d331a33880504fa94478c9687f3f41322ec76f81edad8e72491cbb81eea4754",
+ 0,
+ "0x20 0x4c683607ca7950380df10647b223f656cd73d1f7ad67b30caf60d78337f913b2 OP_CHECKTEMPLATEVERIFY",
+ 3400]],
+ "02000000015447ea1eb8cb9124e7d8da1ef876ec2213f4f387968c4794fa040588331a337d00000000000000000002b004000000000000222084ac6e0fdbe91b09d1bf68158643ad68e0b3e64373738fb35711de0835011079b3b0040000000000002220241af26179a8e861cca473244723978127c16531f71fbcc33563c4f099651f8fb300000000",
+ "DISCOURAGE_UPGRADABLE_NOPS", "NONE", true],
+["CTV congestion control tree level 3"],
+[[["e630b2357e02d1611a0615ce3964c408823ce3269974bd94e57ddea96900da70",
+ 0,
+ "0x20 0x84ac6e0fdbe91b09d1bf68158643ad68e0b3e64373738fb35711de0835011079 OP_CHECKTEMPLATEVERIFY",
+ 1200]],
+ "020000000170da0069a9de7de594bd749926e33c8208c46439ce15061a61d1027e35b230e60000000000000000000264000000000000001600141ca3bdf6bd2b1fc27420316a0d13f81fcdb85cb0640000000000000016001489d611c79700d6b4ae73d853ed49b86621d5802100000000",
+ "DISCOURAGE_UPGRADABLE_NOPS", "NONE", true],
+ ["END"],
+
+ ["BEGIN CTV congestion control tree level with 4 levels:"],
+ ["CTV congestion control tree level 0"],
+[[["d0246d069143263bca9a2b176fcf64bd8e4975c7670ed33659b4b8f88d3e7446",
+ 0,
+ "0x20 0x10618b50aa1120e9e940bbea8b6d081019e38fbb9b956b0ab4f61631d05727ca OP_CHECKTEMPLATEVERIFY",
+ 16600]],
+ "020000000146743e8df8b8b45936d30e67c775498ebd64cf6f172b9aca3b264391066d24d000000000000000000002781e0000000000002220bceb923d731eddf09705690d6ee697d1b3d57279ad96910cfb66a8d43a638800b3781e00000000000022201210e50077518896fd1661bffc2c1e88ad6e204ec4e8755407b42a97347c1e1bb300000000",
+ "NONE", "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+["CTV congestion control tree level 1"],
+[[["b69f866d47ebb75eeecfbc3b9b641f926f11035b64ff27a5a5e88b9c065bddf5",
+ 0,
+ "0x20 0xbceb923d731eddf09705690d6ee697d1b3d57279ad96910cfb66a8d43a638800 OP_CHECKTEMPLATEVERIFY",
+ 7800]],
+ "0200000001f5dd5b069c8be8a5a527ff645b03116f921f649b3bbccfee5eb7eb476d869fb600000000000000000002480d00000000000022204c683607ca7950380df10647b223f656cd73d1f7ad67b30caf60d78337f913b2b3480d0000000000002220805bddd8b95a3cf3729b62703de37a1533b11634de76aa4a18605b640f1f3208b300000000",
+ "NONE", "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+["CTV congestion control tree level 2"],
+[[["7d331a33880504fa94478c9687f3f41322ec76f81edad8e72491cbb81eea4754",
+ 0,
+ "0x20 0x4c683607ca7950380df10647b223f656cd73d1f7ad67b30caf60d78337f913b2 OP_CHECKTEMPLATEVERIFY",
+ 3400]],
+ "02000000015447ea1eb8cb9124e7d8da1ef876ec2213f4f387968c4794fa040588331a337d00000000000000000002b004000000000000222084ac6e0fdbe91b09d1bf68158643ad68e0b3e64373738fb35711de0835011079b3b0040000000000002220241af26179a8e861cca473244723978127c16531f71fbcc33563c4f099651f8fb300000000",
+ "NONE", "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+["CTV congestion control tree level 3"],
+[[["e630b2357e02d1611a0615ce3964c408823ce3269974bd94e57ddea96900da70",
+ 0,
+ "0x20 0x84ac6e0fdbe91b09d1bf68158643ad68e0b3e64373738fb35711de0835011079 OP_CHECKTEMPLATEVERIFY",
+ 1200]],
+ "020000000170da0069a9de7de594bd749926e33c8208c46439ce15061a61d1027e35b230e60000000000000000000264000000000000001600141ca3bdf6bd2b1fc27420316a0d13f81fcdb85cb0640000000000000016001489d611c79700d6b4ae73d853ed49b86621d5802100000000",
+ "NONE", "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ ["END"],
+
+ ["Test CTV with a specific scriptsig"],
+[[["32858fe9a6348d4ee5fcfce78f6dbca0b54dff169ff4cc41439adca4e5d30746",
+ 0,
+ "1",
+ 155000],
+ ["357722dce671e5aa52abd617002baa8d5d970cef43feca3bf2d4c8b1e5d53d11",
+ 0,
+ "0x20 0x08a5903863a0562c0b5608521a8a77ca02e669eb01f3981eede6bf6f2f38c2c2 OP_CHECKTEMPLATEVERIFY",
+ 155000]],
+ "0200000002113dd5e5b1c8d4f23bcafe43ef0c975d8daa2b0017d6ab52aae571e6dc227735000000000151000000004607d3e5a4dc9a4341ccf49f16ff4db5a0bc6d8fe7fcfce54e8d34a6e98f8532000000000100000000000ae80300000000000017a9146422bb825e07ab99ab915223ac67f195a4fb761987d00700000000000017a914cc9fa001f8c9ff9dfdecf0ec1356d37c808aec2d87b80b00000000000017a914092f42f35fd05eaf816a090ad8f1adec8394132d87a00f00000000000017a9147cfd2a76093289ebabf860d3071b92756dbde1b787881300000000000017a914c3d81e1a59c256bff75c535878e1701943a9e48987701700000000000017a914029ddf1319c05ff38cd974ba99fdcf1cb4b88b9687581b00000000000017a9148c95279a9fd452ad7b1cb7a35fd08e7ff55946af87401f00000000000017a9149216fef0f965b2f1890a420aa725cb86ba47a9c087282300000000000017a9141424c24d8cd907a36310db639ec7d194c62d620087102700000000000017a9145b278b155e6dd103b4bf5ba78e4a95c16926c9bd8700000000",
+ "DISCOURAGE_UPGRADABLE_NOPS,CLEANSTACK", "NONE", true],
+[[["32858fe9a6348d4ee5fcfce78f6dbca0b54dff169ff4cc41439adca4e5d30746",
+ 0,
+ "1",
+ 155000],
+ ["357722dce671e5aa52abd617002baa8d5d970cef43feca3bf2d4c8b1e5d53d11",
+ 0,
+ "0x20 0x08a5903863a0562c0b5608521a8a77ca02e669eb01f3981eede6bf6f2f38c2c2 OP_CHECKTEMPLATEVERIFY",
+ 155000]],
+ "0200000002113dd5e5b1c8d4f23bcafe43ef0c975d8daa2b0017d6ab52aae571e6dc227735000000000151000000004607d3e5a4dc9a4341ccf49f16ff4db5a0bc6d8fe7fcfce54e8d34a6e98f8532000000000100000000000ae80300000000000017a9146422bb825e07ab99ab915223ac67f195a4fb761987d00700000000000017a914cc9fa001f8c9ff9dfdecf0ec1356d37c808aec2d87b80b00000000000017a914092f42f35fd05eaf816a090ad8f1adec8394132d87a00f00000000000017a9147cfd2a76093289ebabf860d3071b92756dbde1b787881300000000000017a914c3d81e1a59c256bff75c535878e1701943a9e48987701700000000000017a914029ddf1319c05ff38cd974ba99fdcf1cb4b88b9687581b00000000000017a9148c95279a9fd452ad7b1cb7a35fd08e7ff55946af87401f00000000000017a9149216fef0f965b2f1890a420aa725cb86ba47a9c087282300000000000017a9141424c24d8cd907a36310db639ec7d194c62d620087102700000000000017a9145b278b155e6dd103b4bf5ba78e4a95c16926c9bd8700000000",
+ "CLEANSTACK", "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+ ["Test CTV with a specific scriptsig at different index"],
+ [[["e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5",
+ 0,
+ "1",
+ 155000],
+ ["c88e4b769a9211d2bca7516dbeacf250585dc825e41e34a65607a444b97fb782",
+ 0,
+ "0x20 0xcc06acb181a8e9893c53c92fcfcb56fc004a360964af02cfd15b9f3321385f86 OP_CHECKTEMPLATEVERIFY",
+ 155000]],
+"0200000002d58631133c4d4f6188abbd0fa0a7aa64bfde05ce4297e3349b38599ceebaf2e20000000001510000000082b77fb944a40756a6341ee425c85d5850f2acbe6d51a7bcd211929a764b8ec8000000000100000000000ae80300000000000017a914d63e77972529f4db5b32efaa4e06f66ae0b5dc0987d00700000000000017a91488b6705f8c9568c52b55ed712c257f84f64a49f587b80b00000000000017a9142be57e9a179f8d9ff8f33a788d4b54512ea9e36087a00f00000000000017a91429261b4f65796f618908de9f51669014e2e2e04f87881300000000000017a914e3a1e1d24cbba3ca9369248082988bad3ceafcfb87701700000000000017a91403801b0a9591f3b5a00a5ea60fb34dc12b4a691187581b00000000000017a91465248bc2c732db2d88db0b0d677c1514b101025b87401f00000000000017a91420021e3dc4e80c7192c1a3cd04026d22d0f8d38287282300000000000017a914df27596dbff2028791bd7692846e65d16d8fed0d87102700000000000017a9142ed128e911cab04d3277d3635f79d5e3d7e6f4c48700000000",
+"DISCOURAGE_UPGRADABLE_NOPS,CLEANSTACK", "NONE", true],
+ [[["e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5",
+ 0,
+ "1",
+ 155000],
+ ["c88e4b769a9211d2bca7516dbeacf250585dc825e41e34a65607a444b97fb782",
+ 0,
+ "0x20 0xcc06acb181a8e9893c53c92fcfcb56fc004a360964af02cfd15b9f3321385f86 OP_CHECKTEMPLATEVERIFY",
+ 155000]],
+"0200000002d58631133c4d4f6188abbd0fa0a7aa64bfde05ce4297e3349b38599ceebaf2e20000000001510000000082b77fb944a40756a6341ee425c85d5850f2acbe6d51a7bcd211929a764b8ec8000000000100000000000ae80300000000000017a914d63e77972529f4db5b32efaa4e06f66ae0b5dc0987d00700000000000017a91488b6705f8c9568c52b55ed712c257f84f64a49f587b80b00000000000017a9142be57e9a179f8d9ff8f33a788d4b54512ea9e36087a00f00000000000017a91429261b4f65796f618908de9f51669014e2e2e04f87881300000000000017a914e3a1e1d24cbba3ca9369248082988bad3ceafcfb87701700000000000017a91403801b0a9591f3b5a00a5ea60fb34dc12b4a691187581b00000000000017a91465248bc2c732db2d88db0b0d677c1514b101025b87401f00000000000017a91420021e3dc4e80c7192c1a3cd04026d22d0f8d38287282300000000000017a914df27596dbff2028791bd7692846e65d16d8fed0d87102700000000000017a9142ed128e911cab04d3277d3635f79d5e3d7e6f4c48700000000",
+ "CLEANSTACK", "DEFAULT_CHECK_TEMPLATE_VERIFY_HASH"],
+
+["Make diffs cleaner by leaving a comment here without comma at the end"]
+]
diff --git a/bip-0120.mediawiki b/bip-0120.mediawiki
index b951e93eaf..c9c11e549f 100644
--- a/bip-0120.mediawiki
+++ b/bip-0120.mediawiki
@@ -52,7 +52,7 @@ A proof of payment for a transaction T, here called PoP(T), is used to prove tha
OP_RETURN
-{|
+{|
! Field !! Size [B] !! Description
|-
| <version> || 2 || Version, little endian, currently 0x01 0x00
@@ -77,7 +77,7 @@ An illustration of the PoP data structure and its original payment is shown belo
|input2 4,ffffffff | 1,pay to B |
| | 4,pay to C |
+------------------------------------------------+
-
+
PoP(T)
+-------------------------------------------------------------+
| inputs | outputs |
diff --git a/bip-0122.mediawiki b/bip-0122.mediawiki
index 3fb5df870c..6243c64fef 100644
--- a/bip-0122.mediawiki
+++ b/bip-0122.mediawiki
@@ -43,7 +43,7 @@ Where:
| rowspan="3" | type
| tx
| for transactions.
-| rowspan="3" | required
+| rowspan="3" | required
|-
| block
| for blocks (supports both hash or height).
@@ -75,9 +75,9 @@ The '''chain ID''' of a chain is the block hash of the corresponding genesis blo
So, for example:
-Bitcoin main : 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
+Bitcoin main : 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
Bitcoin test : 000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943
-Bitcoin regtest: 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206
+Bitcoin regtest: 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206
An example of forked chain (Feathercoin, that forked Litecoin):
@@ -87,7 +87,7 @@ An example of forked chain (Feathercoin, that forked Litecoin):
==Examples==
diff --git a/bip-0123.mediawiki b/bip-0123.mediawiki
index 2404937b8e..9ee87c12a3 100644
--- a/bip-0123.mediawiki
+++ b/bip-0123.mediawiki
@@ -25,7 +25,7 @@ This BIP is dual-licensed under the Creative Commons CC0 1.0 Universal and GNU A
==Motivation==
-Bitcoin is a system involving a number of different standards. Some standards are absolute requirements for interoperability while others can be considered optional, giving implementors a choice of whether to support them.
+Bitcoin is a system involving a number of different standards. Some standards are absolute requirements for interoperability while others can be considered optional, giving implementers a choice of whether to support them.
In order to have a BIP process which more closely reflects the interoperability requirements, it is necessary to categorize BIPs accordingly. Lower layers present considerably greater challenges in getting standards accepted and deployed.
@@ -72,7 +72,7 @@ There's room at this layer to allow for competing standards without breaking bas
===4. Applications Layer===
-The applications layer specifies high level structures, abstractions, and conventions that allow different applications to support similar features and share data.
+The applications layer specifies high level structures, abstractions, and conventions that allow different applications to support similar features and share data.
==Classification of existing BIPs==
diff --git a/bip-0125.mediawiki b/bip-0125.mediawiki
index e43ddb1a45..f4060cfa1a 100644
--- a/bip-0125.mediawiki
+++ b/bip-0125.mediawiki
@@ -6,7 +6,7 @@
Peter Todd
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0125
- Status: Proposed
+ Status: Final
Type: Standards Track
Created: 2015-12-04
License: PD
@@ -132,7 +132,7 @@ confirmed, and so some users advocated that replacement should be
disallowed.
To address those concerns, a variation on RBF was created that
-required that the replacement transaction pay all of same outputs as
+required that the replacement transaction pay all of the same outputs as
the original transaction in equal or greater amount. This was called
RBF First Seen Safe (RBF-FSS), and the original RBF became known as
full-RBF. Although agreeable to recipients who relied on the
@@ -151,8 +151,8 @@ of full-RBF.
There are no known problematic interactions between opt-in full-RBF and
other uses of nSequence. Specifically, opt-in full-RBF is compatible
with consensus-enforced locktime as provided in the Bitcoin 0.1
-implementation, draft BIP68 (Relative lock-time using consensus-enforced
-sequence numbers), and draft BIP112 (CHECKSEQUENCEVERIFY).
+implementation, BIP68 (Relative lock-time using consensus-enforced
+sequence numbers), and BIP112 (CHECKSEQUENCEVERIFY).
==Deployment==
diff --git a/bip-0126.mediawiki b/bip-0126.mediawiki
index f498b1cb33..2c04eb4551 100644
--- a/bip-0126.mediawiki
+++ b/bip-0126.mediawiki
@@ -14,7 +14,7 @@
When a Bitcoin transaction contains inputs that reference previous transaction outputs sent to different Bitcoin addresses, personally identifiable information of the user will leak into the blockchain in an uncontrolled manner. While undesirable, these transactions are frequently unavoidable due to the natural fragmentation of wallet balances over time.
-This document proposes a set of best practice guidelines which minimize the uncontrolled disclosure of personally identifiable information by defining standard forms for transactions containing heterogenous input scripts.
+This document proposes a set of best practice guidelines which minimize the uncontrolled disclosure of personally identifiable information by defining standard forms for transactions containing heterogeneous input scripts.
==Copyright==
@@ -23,8 +23,8 @@ This BIP is in the public domain.
==Definitions==
* '''Heterogenous input script transaction (HIT)''': A transaction containing multiple inputs where the scripts of the previous transaction outputs being consumed are not identical (e.g. a transaction spending outputs which were sent to more than one Bitcoin address)
-* '''Unavoidable heterogenous input script transaction''': A HIT created as a result of a user’s desire to create a new output with a value larger than the value of his wallet's largest existing unspent output
-* '''Intentional heterogenous input script transaction''': A HIT created as part of a user protection protocol for reducing uncontrolled disclosure of personally-identifying information (PII)
+* '''Unavoidable heterogeneous input script transaction''': A HIT created as a result of a user’s desire to create a new output with a value larger than the value of his wallet's largest existing unspent output
+* '''Intentional heterogeneous input script transaction''': A HIT created as part of a user protection protocol for reducing uncontrolled disclosure of personally-identifying information (PII)
Throughout this procedure, when input scripts are evaluated for uniqueness, "input script" should be interpreted to mean, "the script of the previous output referenced by an input to a transaction".
@@ -33,10 +33,10 @@ Throughout this procedure, when input scripts are evaluated for uniqueness, "inp
The recommendations in this document are designed to accomplish three goals:
# Maximise the effectiveness of user-protecting protocols: Users may find that protection protocols are counterproductive if such transactions have a distinctive fingerprint which renders them ineffective.
-# Minimise the adverse consequences of unavoidable heterogenous input transactions: If unavoidable HITs are indistinguishable from intentional HITs, a user creating an unavoidable HIT benefits from ambiguity with respect to graph analysis.
+# Minimise the adverse consequences of unavoidable heterogeneous input transactions: If unavoidable HITs are indistinguishable from intentional HITs, a user creating an unavoidable HIT benefits from ambiguity with respect to graph analysis.
# Limiting the effect on UTXO set growth: To date, non-standardized intentional HITs tend to increase the network's UTXO set with each transaction; this standard attempts to minimize this effect by standardizing unavoidable and intentional HITs to limit UTXO set growth.
-In order to achieve these goals, this specification proposes a set of best practices for heterogenous input script transaction creation. These practices accommodate all applicable requirements of both intentional and unavoidable HITs while maximising the effectiveness of both in terms of preventing uncontrolled disclosure of PII.
+In order to achieve these goals, this specification proposes a set of best practices for heterogeneous input script transaction creation. These practices accommodate all applicable requirements of both intentional and unavoidable HITs while maximising the effectiveness of both in terms of preventing uncontrolled disclosure of PII.
In order to achieve this, two forms of HIT are proposed: Standard form and alternate form.
@@ -44,13 +44,13 @@ In order to achieve this, two forms of HIT are proposed: Standard form and alter
Applications which wish to comply both with this procedure and BIP69 should apply this procedure prior to applying BIP69.
-==Standard form heterogenous input script transaction==
+==Standard form heterogeneous input script transaction==
===Rules===
A HIT is Standard form if it adheres to all of the following rules:
-# The number of unique output scripts must be equal to the number of unique inputs scripts (irrespective of the number of inputs and outputs).
+# The number of unique output scripts must be equal to the number of unique input scripts (irrespective of the number of inputs and outputs).
# All output scripts must be unique.
# At least one pair of outputs must be of equal value.
# The largest output in the transaction is a member of a set containing at least two identically-sized outputs.
@@ -63,7 +63,7 @@ The requirement that all output scripts are unique prevents address reuse. Restr
The requirement for at least one pair of outputs in an intentional HIT to be of equal value results in optimal behavior, and causes intentional HITs to resemble unavoidable HITs.
-==Alternate form heterogenous input script transactions==
+==Alternate form heterogeneous input script transactions==
The formation of a standard form HIT is not possible in the following cases:
@@ -88,7 +88,7 @@ Clients which create intentional HITs must have the capability to form alternate
An HIT formed via the preceding procedure will adhere to the following conditions:
-# The number of unique inputs scripts must exceed the number of output scripts.
+# The number of unique input scripts must exceed the number of output scripts.
# All output scripts must be unique.
# At least one pair of outputs must be of equal value.
## "Standard outputs" refers to the set of outputs with equal value
@@ -100,7 +100,7 @@ An HIT formed via the preceding procedure will adhere to the following condition
## The sum of the inputs in the set minus the value of the change output is equal to the standard value with a tolerance equal to the transaction fee.
## Change outputs with a value of zero (virtual change outputs) are permitted. The are defined for the purpose of testing whether or not a HIT adheres to this specification but are not present in the version of the transaction which is broadcast to the network.
-==Non-compliant heterogenous input script transactions==
+==Non-compliant heterogeneous input script transactions==
If a user wishes to create an output that is larger than half the total size of their spendable outputs, or if their inputs are not distributed in a manner in which the alternate form procedure can be completed, then the user can not create a transaction which is compliant with this procedure.
diff --git a/bip-0127.mediawiki b/bip-0127.mediawiki
index 15c7755f3f..87071d8eaf 100644
--- a/bip-0127.mediawiki
+++ b/bip-0127.mediawiki
@@ -124,7 +124,7 @@ message FinalProof {
// Bitcoin transaction.
bytes proof_tx = 1;
- // The metadata of the ouputs used in the proof transaction.
+ // The metadata of the outputs used in the proof transaction.
repeated OutputMeta output_metadata = 2;
}
@@ -219,6 +219,7 @@ A work-in-progress implementation of a tool that produces and verifies proofs
in the described format can be found here:
https://github.com/stevenroose/reserves
+An implementation of the custom proof PSBTs is part of the [https://bitcoindevkit.org/ BDK], and can be found here: https://crates.io/crates/bdk-reserves
== Footnotes ==
diff --git a/bip-0129.mediawiki b/bip-0129.mediawiki
index 8719fe420f..1eaf55d68c 100644
--- a/bip-0129.mediawiki
+++ b/bip-0129.mediawiki
@@ -47,11 +47,14 @@ Concerns #4 and #5 should be handled by Signers and are out of scope of this pro
==Specification==
===Prerequisites===
-This proposal assumes the parties in the multisig support [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP-0032], [https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki BIP-0322], [https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the descriptor language] and [https://tools.ietf.org/html/rfc3686 AES encryption].
+This proposal assumes the parties in the multisig support [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP-0032], [https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki BIP-0322], [https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki BIP-0380 Output Script Descriptors] ([https://github.com/bitcoin/bips/blob/master/bip-0381.mediawiki BIP-0381],[https://github.com/bitcoin/bips/blob/master/bip-0382.mediawiki BIP-0382],[https://github.com/bitcoin/bips/blob/master/bip-0383.mediawiki BIP-0383]) and [https://tools.ietf.org/html/rfc3686 AES encryption].
===File Extensions===
All descriptor and key records should have a .bsms file extension. Encrypted data should have a .dat extension.
+===Newline===
+This specification uses line feed (LF) control character \n.
+
===Roles===
====Coordinator====
@@ -92,7 +95,7 @@ The Signer is any software or hardware that controls the private keys and can si
* The Coordinator verifies that the included SIG is valid given the KEY.
* If all key records look good, the Coordinator fills in all necessary information to generate a descriptor record.
* The first line in the descriptor record must be the specification version (BSMS 1.0 as of this writing). The second line must be a descriptor or a descriptor template. The third line must be a comma-separated list of derivation path restrictions. The paths must start with / and use non-hardened derivation. If there are no template or restrictions, it must say No path restrictions. The fourth line must be the wallet's first address. If there are path restrictions, use the first address from the first path restriction.
-* The Coordinator calculates the MAC for the record. The first 16 bytes of the MAC serves as the IV for the encryption..
+* The Coordinator calculates the MAC for the record. The first 16 bytes of the MAC serves as the IV for the encryption..
* The Coordinator encrypts the descriptor record with the ENCRYPTION_KEY and IV.
* The Coordinator encodes the MAC and the ciphertext into hexadecimal format, then concatenates the results: (MAC || ciphertext).
* The Coordinator sends the encrypted descriptor record to all participating Signers.
@@ -107,7 +110,7 @@ The Signer is any software or hardware that controls the private keys and can si
* The Signer checks that its KEY is included in the descriptor or descriptor template, using path and fingerprint information provided. The check must perform an exact match on the KEYs and not using shortcuts such as matching fingerprints, which is trivial to spoof.
* The Signer verifies that it is compatible with the derivation path restrictions.
* The Signer verifies that the wallet's first address is valid.
-* For confirmation, the Signer must display to the user the wallet's first address and policy parameters, including, but not limited to: the derivation path restrictions, M, N, and the position(s) of the Signer's own KEY in the policy script. The total number of Signers, N, is important to prevent a KEY insertion attack. The position is important for scripts where KEY order matters. When applicable, all positions of the KEY must be displayed. The full descriptor or descriptor template must also be available for review upon user request.
+* For confirmation, the Signer must display to the user the wallet's first address and policy parameters, including, but not limited to: the derivation path restrictions, M, N, and the position(s) of the Signer's own KEY in the policy script. The total number of Signers, N, is important to prevent a KEY insertion attack. The position is important for scripts where KEY order matters. When applicable, all positions of the KEY must be displayed. The full descriptor or descriptor template must also be available for review upon user request.
* Parties must check with each other that all Signers have the same confirmation (except for the KEY positions).
* If all checks pass, the Signer must persist the descriptor record in its storage.
@@ -123,8 +126,8 @@ We define three modes of encryption.
# EXTENDED : the TOKEN is a 128-bit nonce.
The TOKEN can be converted to one of these formats:
-* A decimal number (recommended). The number must not exceed the maximum value of the nonce.
-* A mnemonic phrase using [https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP-0039] word list. This would be 6 words in STANDARD mode. This encoding is not recommended in EXTENDED mode as it can result in potential confusion between seed mnemonics and TOKEN mnemonics.
+* A decimal number (recommended). The number must not exceed the maximum value of the nonce.
+* A mnemonic phrase using [https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP-0039] word list. This would be 6 words in STANDARD mode. This encoding is not recommended in EXTENDED mode as it can result in potential confusion between seed mnemonics and TOKEN mnemonics.
* A QR code.
* Other formats.
@@ -141,7 +144,7 @@ Whereas:
* Password = "No SPOF"
* Salt = TOKEN
* c = 2048
-* dkLen = 256
+* dkLen = 256 bits (32 bytes)
* DKey = Derived ENCRYPTION_KEY
====Encryption Scheme====
@@ -452,7 +455,7 @@ sh(wsh(multi(2,[793cc70b/48'/0'/0'/1']xpub6ErVmcYYHmavsMgxEcTZyzN5sqth1ZyRpFNJC2
==Acknowledgement==
-Special thanks to Pavol Rusnak, Dmitry Petukhov, Christopher Allen, Craig Raw, Robert Spigler, Gregory Sanders, Ta Tat Tai, Michael Flaxman, Pieter Wuille, Salvatore Ingala, Andrew Chow and others for their feedback on the specification.
+Special thanks to Pavol Rusnak, Dmitry Petukhov, Christopher Allen, Craig Raw, Robert Spigler, Gregory Sanders, Ta Tat Tai, Michael Flaxman, Pieter Wuille, Salvatore Ingala, Ava Chow and others for their feedback on the specification.
==References==
diff --git a/bip-0130.mediawiki b/bip-0130.mediawiki
index 8d96c0c8a3..d88329fd7b 100644
--- a/bip-0130.mediawiki
+++ b/bip-0130.mediawiki
@@ -5,7 +5,7 @@
Author: Suhas Daftuar
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0130
- Status: Proposed
+ Status: Final
Type: Standards Track
Created: 2015-05-08
License: PD
diff --git a/bip-0131.mediawiki b/bip-0131.mediawiki
index 25ba3a7e14..f279ec1f35 100644
--- a/bip-0131.mediawiki
+++ b/bip-0131.mediawiki
@@ -59,7 +59,7 @@ inputs present in the transaction.
A coalescing transaction is formulated the exact same way as a version 1 transaction
with one exception: each input is treated as a "wildcard input".
-A wildcard input beings the value of all inputs with the exact same scriptPubKey
+A wildcard input being the value of all inputs with the exact same scriptPubKey
in a block lower or equal to the block the wildcard input is confirmed into.
== Changes needed to implement ==
diff --git a/bip-0132.mediawiki b/bip-0132.mediawiki
index e7aed29248..2b2b26c367 100644
--- a/bip-0132.mediawiki
+++ b/bip-0132.mediawiki
@@ -48,7 +48,7 @@ The author doesn't believe this is a problem because a BIP cannot be forced on c
== Process ==
-* '''Submit for Comments.''' The first BIP champion named in the proposal can call a "submit for comments" at any time by posting to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev Dev Mailing List] mailling with the BIP number and a statement that the champion intends to immediately submit the BIP for comments.
+* '''Submit for Comments.''' The first BIP champion named in the proposal can call a "submit for comments" at any time by posting to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev Dev Mailing List] mailing with the BIP number and a statement that the champion intends to immediately submit the BIP for comments.
** The BIP must have been assigned BIP-number (i.e. been approved by the BIP editor) to be submitted for comments.
* '''Comments.'''
** After a BIP has been submitted for comments, a two-week waiting period begins in which the community should transition from making suggestions about a proposal to publishing their opinions or concerns on the proposal.
@@ -83,7 +83,7 @@ The author doesn't believe this is a problem because a BIP cannot be forced on c
** User communities
* A person may be represented by any number of segments, but a committee cannot re-use the same resource as another committee in the same segment.
-'''Committee Declarations.'''
+'''Committee Declarations.'''
* At any point, a Committee Declaration can be posted.
* This Declaration must contain details about:
** The segment the Committee is representing
diff --git a/bip-0133.mediawiki b/bip-0133.mediawiki
index c109f12ff9..b37370d9b4 100644
--- a/bip-0133.mediawiki
+++ b/bip-0133.mediawiki
@@ -5,7 +5,7 @@
Author: Alex Morcos
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0133
- Status: Draft
+ Status: Final
Type: Standards Track
Created: 2016-02-13
License: PD
diff --git a/bip-0134.mediawiki b/bip-0134.mediawiki
index b7c33cf91c..4af4844eaf 100644
--- a/bip-0134.mediawiki
+++ b/bip-0134.mediawiki
@@ -58,7 +58,7 @@ various decades ago with the XML format. The idea is that we give each
field a name and this means that new fields can be added or optional fields
can be omitted from individual transactions. Some other ideas are the
standardization of data-formats (like integer and string encoding) so
-we create a more consistent system.
+we create a more consistent system.
One thing we shall not inherit from XML is its text-based format. Instead
we use the [https://github.com/bitcoinclassic/documentation/blob/master/spec/compactmessageformat.md Compact Message Format]
(CMF) which is optimized to keep the size small and fast to parse.
diff --git a/bip-0135.mediawiki b/bip-0135.mediawiki
index 1324746d59..40c06dd947 100644
--- a/bip-0135.mediawiki
+++ b/bip-0135.mediawiki
@@ -170,7 +170,7 @@ A given deployment SHALL remain in the DEFINED state until it either passes the
starttime (and becomes STARTED) or the timeout time (and becomes FAILED).
Once a deployment has STARTED, the signal for that deployment SHALL be tallied
-over the the past windowsize blocks whenever a new block is received on that
+over the past windowsize blocks whenever a new block is received on that
chain.
A transition from the STARTED state to the LOCKED_IN state SHALL only occur
@@ -183,7 +183,7 @@ when all of these are true:
A similar height synchronization precondition SHALL exist for the transition from
LOCKED_IN to ACTIVE.
These synchronization conditions are expressed by the "mod(height, windowsize) = 0"
-clauses in the diagram, and have been been added so that backward compatibility
+clauses in the diagram, and have been added so that backward compatibility
with BIP9's use of the 2016-block re-targeting periods can be configured for
existing deployments (see above 'Optional full backward compatibility' section).
@@ -261,7 +261,7 @@ proposal, although a conventional fallow period of 3 months is RECOMMENDED.
Due to the constraints set by BIP 34, BIP 66 and BIP 65, there are only
0x7FFFFFFB possible nVersion values available. This limits to at most 30
independent deployments.
-By restricting the top 3 bits to 001 we we are left with 29 out of those for
+By restricting the top 3 bits to 001 we are left with 29 out of those for
the purposes of this proposal, and support two future upgrades for different
mechanisms (top bits 010 and 011).
@@ -274,7 +274,7 @@ mechanisms (top bits 010 and 011).
The following guidelines are suggested for selecting the parameters for a fork:
# '''name''' SHOULD be selected such that no two forks, concurrent or otherwise, ever use the same name.
-# '''bit''' SHOULD be selected such that no two concurrent forks use the same bit. Implementors should make an effort to consult resources such as [2] to establish whether the bit they wish to use can reasonably be assumed to be unclaimed by a concurrent fork, and to announce their use ('claim') of a bit for a fork purpose on various project mailing lists, to reduce chance of collisions.
+# '''bit''' SHOULD be selected such that no two concurrent forks use the same bit. Implementers should make an effort to consult resources such as [2] to establish whether the bit they wish to use can reasonably be assumed to be unclaimed by a concurrent fork, and to announce their use ('claim') of a bit for a fork purpose on various project mailing lists, to reduce chance of collisions.
# '''starttime''' SHOULD be set to some date in the future, approximately one month after a software release date which includes the fork signaling. This allows for some release delays, while preventing triggers as a result of parties running pre-release software.
# '''timeout''' is RECOMMENDED to be 1 year (31536000 seconds) after starttime.
# '''windowsize''' SHOULD be set large enough to allow reception of an adequately precise signal. A good high-resolution value would be 2016 blocks as used in BIP9. It is NOT RECOMMENDED to use a windowsize less than 100 blocks.
diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki
index 19dd536488..ccba17fc52 100644
--- a/bip-0137.mediawiki
+++ b/bip-0137.mediawiki
@@ -15,7 +15,7 @@
This document describes a signature format for signing messages with Bitcoin private keys.
-The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exist in the field today. Note: that a new signature format has been defined which has a number of advantages over this BIP, but to be backwards compatible with existing implementations this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme.
+The specification is intended to describe the standard for signatures of messages that can be signed and verified between different clients that exist in the field today. Note: that a new signature format has been defined which has a number of advantages over this BIP, but to be backwards compatible with existing implementations this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme.
One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [2]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures.
@@ -25,7 +25,7 @@ This BIP is licensed under the 2-clause BSD license.
==Motivation==
-Since Bitcoin private keys can not only be used to sign Bitcoin transactions, but also any other message, it has become customary to use them to sign various messages for differing purposes. Some applications of signing messages with a Bitcoin private key are as follows: proof of funds for collateral, credit worthiness, enterence to events, airdrops, audits as well as other applications. While there was no BIP written for how to digitally sign messages with Bitcoin private keys with P2PKH addresses it is a fairly well understood process, however with the introduction of Segwit (both in the form of P2SH and bech32) addresses, it is unclear how to distinguish a P2PKH, P2SH, or bech32 address from one another. This BIP proposes a standard signature format that will allow clients to distinguish between the different address formats.
+Since Bitcoin private keys can not only be used to sign Bitcoin transactions, but also any other message, it has become customary to use them to sign various messages for differing purposes. Some applications of signing messages with a Bitcoin private key are as follows: proof of funds for collateral, credit worthiness, entrance to events, airdrops, audits as well as other applications. While there was no BIP written for how to digitally sign messages with Bitcoin private keys with P2PKH addresses it is a fairly well understood process, however with the introduction of Segwit (both in the form of P2SH and bech32) addresses, it is unclear how to distinguish a P2PKH, P2SH, or bech32 address from one another. This BIP proposes a standard signature format that will allow clients to distinguish between the different address formats.
==Specification==
@@ -116,7 +116,7 @@ Since this format includes P2PKH keys, it is backwards compatible, but keep in m
==Implications==
-Message signing is an important use case and potentially underused due to the fact that, up until now, there has not been a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determing a signature's validity. This BIP can also be updated as new signature formats emerge.
+Message signing is an important use case and potentially underused due to the fact that, up until now, there has not been a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determining a signature's validity. This BIP can also be updated as new signature formats emerge.
==Acknowledgements==
diff --git a/bip-0140.mediawiki b/bip-0140.mediawiki
index 88131f49ec..c8f22f7899 100644
--- a/bip-0140.mediawiki
+++ b/bip-0140.mediawiki
@@ -62,7 +62,7 @@ This is the standard ''m-of-n'' script defined in [https://github.com/bitcoin/bi
The existing OP_CHECKMULTISIG and OP_CHECKMULTISIGVERIFY have a bug[[https://bitcoin.org/en/developer-guide#multisig|Developer Documentation - Multisig]] that pops one argument too many from the stack. This bug is not reproduced in the implementation of OP_CHECKSIGEX, so the canonical solution of pushing a dummy value onto the stack is not necessary.
The normalization is achieved by normalizing the transaction before computing the signaturehash, i.e., the hash that is signed.
-The transaction must be normalized by replacing all transaction IDs in the inputs by their normalized variants and stripping the signature scripts. The normalized transction IDs are computed as described in the previous section. This normalization step is performed both when creating the signatures as well as when checking the signatures.
+The transaction must be normalized by replacing all transaction IDs in the inputs by their normalized variants and stripping the signature scripts. The normalized transaction IDs are computed as described in the previous section. This normalization step is performed both when creating the signatures as well as when checking the signatures.
=== Tracking Normalized Transaction IDs ===
diff --git a/bip-0141.mediawiki b/bip-0141.mediawiki
index 8528729693..4ba6798426 100644
--- a/bip-0141.mediawiki
+++ b/bip-0141.mediawiki
@@ -43,20 +43,20 @@ By removing this data from the transaction structure committed to the transactio
A new data structure, witness, is defined. Each transaction will have 2 IDs.
Definition of txid remains unchanged: the double SHA256 of the traditional serialization format:
-
+
[nVersion][txins][txouts][nLockTime]
-
+
A new wtxid is defined: the double SHA256 of the new serialization with witness data:
-
+
[nVersion][marker][flag][txins][txouts][witness][nLockTime]
-
+
Format of nVersion, txins, txouts, and nLockTime are same as traditional serialization.
The marker MUST be a 1-byte zero value: 0x00.
The flag MUST be a 1-byte non-zero value. Currently, 0x01 MUST be used.
-The witness is a serialization of all witness data of the transaction. Each txin is associated with a witness field. A witness field starts with a var_int to indicate the number of stack items for the txin. It is followed by stack items, with each item starts with a var_int to indicate the length. Witness data is NOT script.
+The witness is a serialization of all witness fields of the transaction. Each txin is associated with a witness field. A witness field starts with a var_int to indicate the number of stack items for the txin. It is followed by stack items, with each item starts with a var_int to indicate the length. Witness data is NOT script.
A non-witness program (defined hereinafter) txin MUST be associated with an empty witness field, represented by a 0x00. If all txins are not witness program, a transaction's wtxid is equal to its txid.
@@ -67,14 +67,14 @@ A new block rule is added which requires a commitment to the wtxid.
A witness root hash is calculated with all those wtxid as leaves, in a way similar to the hashMerkleRoot in the block header.
The commitment is recorded in a scriptPubKey of the coinbase transaction. It must be at least 38 bytes, with the first 6-byte of 0x6a24aa21a9ed, that is:
-
+
1-byte - OP_RETURN (0x6a)
1-byte - Push the following 36 bytes (0x24)
4-byte - Commitment header (0xaa21a9ed)
32-byte - Commitment hash: Double-SHA256(witness root hash|witness reserved value)
-
+
39th byte onwards: Optional data with no consensus meaning
-
+
and the coinbase's input's witness must consist of a single 32-byte array for the witness reserved value.
If there are more than one scriptPubKey matching the pattern, the one with highest output index is assumed to be the commitment.
@@ -83,19 +83,23 @@ If all transactions in a block do not have witness data, the commitment is optio
=== Witness program ===
-A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a 1-byte push opcode (for 0 to 16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program".
+A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a 1-byte push opcode (one of OP_0,OP_1,OP_2,...,OP_16) followed by a direct data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program".
+In more detail, this means a scriptPubKey or redeemScript which consists of (in order):
+* First, byte 0x00 (OP_0) or any byte between 0x51 (OP_1) and 0x60 (OP_16) inclusive (the version byte).
+* Then, a byte ''L'' between 0x02 (push of 2 bytes) and 0x28 (push of 40 bytes) inclusive.
+* Finally, ''L'' arbitrary bytes (the witness program).
There are two cases in which witness validation logic are triggered. Each case determines the location of the witness version byte and program, as well as the form of the scriptSig:
# Triggered by a scriptPubKey that is exactly a push of a version byte, plus a push of a witness program. The scriptSig must be exactly empty or validation fails. (''"native witness program"'')
# Triggered when a scriptPubKey is a P2SH script, and the BIP16 redeemScript pushed in the scriptSig is exactly a push of a version byte plus a push of a witness program. The scriptSig must be exactly a push of the BIP16 redeemScript or validation fails. (''"P2SH witness program"'')
-If the version byte is 0, and the witness program is 20 bytes:
+If the version byte is 0, and the witness program is 20 bytes (''L = 20''):
* It is interpreted as a pay-to-witness-public-key-hash (P2WPKH) program.
* The witness must consist of exactly 2 items (≤ 520 bytes each). The first one a signature, and the second one a public key.
* The HASH160 of the public key must match the 20-byte witness program.
* After normal script evaluation, the signature is verified against the public key with CHECKSIG operation. The verification must result in a single TRUE on the stack.
-If the version byte is 0, and the witness program is 32 bytes:
+If the version byte is 0, and the witness program is 32 bytes (''L = 32''):
* It is interpreted as a pay-to-witness-script-hash (P2WSH) program.
* The witness must consist of an input stack to feed to the script, followed by a serialized script (witnessScript).
* The witnessScript (≤ 10,000 bytes) is popped off the initial witness stack. SHA256 of the witnessScript must match the 32-byte witness program.
@@ -276,7 +280,7 @@ These commitments could be included in the extensible commitment structure throu
Since a version byte is pushed before a witness program, and programs with unknown versions are always considered as anyone-can-spend script, it is possible to introduce any new script system with a soft fork. The witness as a structure is not restricted by any existing script semantics and constraints, the 520-byte push limit in particular, and therefore allows arbitrarily large scripts and signatures.
-Examples of new script system include Schnorr signatures which reduce the size of multisig transactions dramatically, Lamport signature which is quantum computing resistance, and Merklized abstract syntax trees which allow very compact witness for conditional scripts with extreme complexity.
+Examples of new script systems include Schnorr signatures, which reduce the size of multisig transactions dramatically; Lamport signatures, which are quantum computing resistant; and Merklized abstract syntax trees, which allow very compact witnesses for conditional scripts with extreme complexity.
=== Per-input lock-time and relative-lock-time ===
@@ -303,7 +307,7 @@ As a soft fork, older software will continue to operate without modification. N
This BIP will be deployed by "version bits" BIP9 with the name "segwit" and using bit 1.
-For Bitcoin mainnet, the BIP9 starttime will be midnight 15 november 2016 UTC (Epoch timestamp 1479168000) and BIP9 timeout will be midnight 15 november 2017 UTC (Epoch timestamp 1510704000).
+For Bitcoin mainnet, the BIP9 starttime will be midnight 15 November 2016 UTC (Epoch timestamp 1479168000) and BIP9 timeout will be midnight 15 November 2017 UTC (Epoch timestamp 1510704000).
For Bitcoin testnet, the BIP9 starttime will be midnight 1 May 2016 UTC (Epoch timestamp 1462060800) and BIP9 timeout will be midnight 1 May 2017 UTC (Epoch timestamp 1493596800).
diff --git a/bip-0142.mediawiki b/bip-0142.mediawiki
index b11095b8b1..49ed8dca94 100644
--- a/bip-0142.mediawiki
+++ b/bip-0142.mediawiki
@@ -24,14 +24,14 @@ To define standard payment address for native segregated witness (segwit) transa
The new Bitcoin address format defined is for the Pay-to-Witness-Public-Key-Hash (P2WPKH) and Pay-to-Witness-Script-Hash (P2WSH) transaction described in segregated witness soft fork (BIP141). The scriptPubKey is an OP_0 followed by a push of 20-byte-hash (P2WPKH) or 32-byte hash (P2WSH).
The new address is encoded in a way similar to existing address formats:
-
+
base58-encode:
[1-byte address version]
[1-byte witness program version]
[0x00]
[20/32-byte-hash]
[4-byte checksum]
-
+
For P2WPKH address, the address version is 6 (0x06) for a main-network address or 3 (0x03) for a testnet address.
For P2WSH address, the address version is 10 (0x0A) for a main-network address or 40 (0x28) for a testnet address.
@@ -123,25 +123,25 @@ This proposal is forward-compatible with future versions of witness programs of
== Example ==
The following public key,
-
+
0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
-
+
when encoded as a P2PKH template, would become:
-
+
DUP HASH160 <010966776006953D5567439E5E39F86A0D273BEE> EQUALVERIFY CHECKSIG
With the corresponding version 1 Bitcoin address being:
-
+
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
-
-When the same public key is encoded as P2WPKH, the scriptPubKey becomes:
-
+
+When the same public key is encoded as P2WPKH, the scriptPubKey becomes:
+
OP_0 <010966776006953D5567439E5E39F86A0D273BEE>
Using 0x06 as address version, followed by 0x00 as witness program version, and a 0x00 padding, the equivalent P2WPKH address is:
-
+
p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm
-
+
== Reference implementation ==
https://github.com/theuni/bitcoin/commit/ede1b57058ac8efdefe61f67395affb48f2c0d80
diff --git a/bip-0143.mediawiki b/bip-0143.mediawiki
index 81763a0774..3146b5ffd4 100644
--- a/bip-0143.mediawiki
+++ b/bip-0143.mediawiki
@@ -31,7 +31,7 @@ A new transaction digest algorithm is defined, but only applicable to sigops in
1. nVersion of the transaction (4-byte little endian)
2. hashPrevouts (32-byte hash)
3. hashSequence (32-byte hash)
- 4. outpoint (32-byte hash + 4-byte little endian)
+ 4. outpoint (32-byte hash + 4-byte little endian)
5. scriptCode of the input (serialized as scripts inside CTxOuts)
6. value of the output spent by this input (8-byte little endian)
7. nSequence of the input (4-byte little endian)
@@ -39,12 +39,12 @@ A new transaction digest algorithm is defined, but only applicable to sigops in
9. nLocktime of the transaction (4-byte little endian)
10. sighash type of the signature (4-byte little endian)
-Semantics of the original sighash types remain unchanged, except the followings:
+Semantics of the original sighash types remain unchanged, except the following:
# The way of serialization is changed;
# All sighash types commit to the amount being spent by the signed input;
# FindAndDelete of the signature is not applied to the scriptCode;
# OP_CODESEPARATOR(s) after the last executed OP_CODESEPARATOR are not removed from the scriptCode (the last executed OP_CODESEPARATOR and any script before it are always removed);
-# SINGLE does not commit to the input index. When ANYONECANPAY is not set, the semantics are unchanged since hashPrevouts and outpoint together implictly commit to the input index. When SINGLE is used with ANYONECANPAY, omission of the index commitment allows permutation of the input-output pairs, as long as each pair is located at an equivalent index.
+# SINGLE does not commit to the input index. When ANYONECANPAY is not set, the semantics are unchanged since hashPrevouts and outpoint together implicitly commit to the input index. When SINGLE is used with ANYONECANPAY, omission of the index commitment allows permutation of the input-output pairs, as long as each pair is located at an equivalent index.
The items 1, 4, 7, 9, 10 have the same meaning as the original algorithm.
@@ -77,7 +77,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit
uint256 hashPrevouts;
uint256 hashSequence;
uint256 hashOutputs;
-
+
if (!(nHashType & SIGHASH_ANYONECANPAY)) {
CHashWriter ss(SER_GETHASH, 0);
for (unsigned int n = 0; n < txTo.vin.size(); n++) {
@@ -85,7 +85,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit
}
hashPrevouts = ss.GetHash();
}
-
+
if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
CHashWriter ss(SER_GETHASH, 0);
for (unsigned int n = 0; n < txTo.vin.size(); n++) {
@@ -93,7 +93,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit
}
hashSequence = ss.GetHash();
}
-
+
if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
CHashWriter ss(SER_GETHASH, 0);
for (unsigned int n = 0; n < txTo.vout.size(); n++) {
@@ -105,7 +105,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit
ss << txTo.vout[nIn];
hashOutputs = ss.GetHash();
}
-
+
CHashWriter ss(SER_GETHASH, 0);
// Version
ss << txTo.nVersion;
@@ -114,7 +114,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit
ss << hashSequence;
// The input being signed (replacing the scriptSig with scriptCode + amount)
// The prevout may already be contained in hashPrevout, and the nSequence
- // may already be contain in hashSequence.
+ // may already be contained in hashSequence.
ss << txTo.vin[nIn].prevout;
ss << static_cast(scriptCode);
ss << amount;
@@ -125,7 +125,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit
ss << txTo.nLockTime;
// Sighash type
ss << nHashType;
-
+
return ss.GetHash();
@@ -139,42 +139,42 @@ Since this policy is preparation for a future softfork proposal, to avoid potent
To ensure consistency in consensus-critical behaviour, developers should test their implementations against all the tests below. More tests related to this proposal could be found under https://github.com/bitcoin/bitcoin/tree/master/src/test/data .
=== Native P2WPKH ===
-
+
The following is an unsigned transaction:
0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f0000000000eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000
-
+
nVersion: 01000000
txin: 02 fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f 00000000 00 eeffffff
ef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a 01000000 00 ffffffff
txout: 02 202cb20600000000 1976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac
9093510d00000000 1976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac
nLockTime: 11000000
-
+
The first input comes from an ordinary P2PK:
scriptPubKey : 2103c9f4836b9a4f77fc0d81f7bcb01b7f1b35916864b9476c241ce9fc198bd25432ac value: 6.25
private key : bbc27228ddcb9209d7fd6f36b02f7dfa6252af40bb2f1cbc7a557da8027ff866
-
+
The second input comes from a P2WPKH witness program:
scriptPubKey : 00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1, value: 6
private key : 619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9
public key : 025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357
-
+
To sign it with a nHashType of 1 (SIGHASH_ALL):
-
+
hashPrevouts:
dSHA256(fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000ef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a01000000)
= 96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37
-
+
hashSequence:
dSHA256(eeffffffffffffff)
= 52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b
-
+
hashOutputs:
dSHA256(202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac)
= 863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5
-
+
hash preimage: 0100000096b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd3752b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3bef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a010000001976a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac0046c32300000000ffffffff863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e51100000001000000
-
+
nVersion: 01000000
hashPrevouts: 96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37
hashSequence: 52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b
@@ -185,12 +185,12 @@ To ensure consistency in consensus-critical behaviour, developers should test th
hashOutputs: 863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5
nLockTime: 11000000
nHashType: 01000000
-
+
sigHash: c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670
- signature: 304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee
-
+ signature: 304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee01
+
The serialized signed transaction is: 01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000
-
+
nVersion: 01000000
marker: 00
flag: 01
@@ -203,38 +203,38 @@ To ensure consistency in consensus-critical behaviour, developers should test th
nLockTime: 11000000
=== P2SH-P2WPKH ===
-
-
+
+
The following is an unsigned transaction: 0100000001db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a54770100000000feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac92040000
-
+
nVersion: 01000000
txin: 01 db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477 01000000 00 feffffff
txout: 02 b8b4eb0b00000000 1976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac
0008af2f00000000 1976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac
nLockTime: 92040000
-
+
The input comes from a P2SH-P2WPKH witness program:
scriptPubKey : a9144733f37cf4db86fbc2efed2500b4f4e49f31202387, value: 10
redeemScript : 001479091972186c449eb1ded22b78e40d009bdf0089
private key : eb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf
public key : 03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873
-
+
To sign it with a nHashType of 1 (SIGHASH_ALL):
-
+
hashPrevouts:
dSHA256(db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a547701000000)
= b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a
-
+
hashSequence:
dSHA256(feffffff)
= 18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198
-
+
hashOutputs:
dSHA256(b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac)
= de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83
-
+
hash preimage: 01000000b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001976a91479091972186c449eb1ded22b78e40d009bdf008988ac00ca9a3b00000000feffffffde984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c839204000001000000
-
+
nVersion: 01000000
hashPrevouts: b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a
hashSequence: 18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198
@@ -245,10 +245,10 @@ To ensure consistency in consensus-critical behaviour, developers should test th
hashOutputs: de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83
nLockTime: 92040000
nHashType: 01000000
-
+
sigHash: 64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6
signature: 3044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb01
-
+
The serialized signed transaction is: 01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001716001479091972186c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000
nVersion: 01000000
marker: 00
@@ -263,33 +263,33 @@ To ensure consistency in consensus-critical behaviour, developers should test th
This example shows how OP_CODESEPARATOR and out-of-range SIGHASH_SINGLE are processed:
-
-
+
+
The following is an unsigned transaction:
0100000002fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e0000000000ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac00000000
-
+
nVersion: 01000000
txin: 02 fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e 00000000 00 ffffffff
0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f8 00000000 00 ffffffff
txout: 01 00f2052a01000000 1976a914a30741f8145e5acadf23f751864167f32e0963f788ac
nLockTime: 00000000
-
+
The first input comes from an ordinary P2PK:
scriptPubKey: 21036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8ac value: 1.5625
private key: b8f28a772fccbf9b4f58a4f027e07dc2e35e7cd80529975e292ea34f84c4580c
signature: 304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201 (SIGHASH_ALL)
-
+
The second input comes from a native P2WSH witness program:
scriptPubKey : 00205d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0, value: 49
witnessScript: 21026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac
<026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880ae> CHECKSIGVERIFY CODESEPARATOR <0255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465> CHECKSIG
-
+
To sign it with a nHashType of 3 (SIGHASH_SINGLE):
-
+
hashPrevouts:
dSHA256(fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000000815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f800000000)
= ef546acf4a020de3898d1b8956176bb507e6211b5ed3619cd08b6ea7e2a09d41
-
+
nVersion: 01000000
hashPrevouts: ef546acf4a020de3898d1b8956176bb507e6211b5ed3619cd08b6ea7e2a09d41
hashSequence: 0000000000000000000000000000000000000000000000000000000000000000
@@ -300,7 +300,7 @@ This example shows how OP_CODESEPARATOR and out-of-range SIGH
hashOutputs: 0000000000000000000000000000000000000000000000000000000000000000 (this is the second input but there is only one output)
nLockTime: 00000000
nHashType: 03000000
-
+
scriptCode: 4721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac
^^
(please note that the not-yet-executed OP_CODESEPARATOR is not removed from the scriptCode)
@@ -309,7 +309,7 @@ This example shows how OP_CODESEPARATOR and out-of-range SIGH
public key: 026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880ae
private key: 8e02b539b1500aa7c81cf3fed177448a546f19d2be416c0c61ff28e577d8d0cd
signature: 3044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e2703
-
+
scriptCode: 23210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac
(everything up to the last executed OP_CODESEPARATOR, including that OP_CODESEPARATOR, are removed)
preimage: 01000000ef546acf4a020de3898d1b8956176bb507e6211b5ed3619cd08b6ea7e2a09d4100000000000000000000000000000000000000000000000000000000000000000815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000023210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac0011102401000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000003000000
@@ -317,36 +317,36 @@ This example shows how OP_CODESEPARATOR and out-of-range SIGH
public key: 0255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465
private key: 86bf2ed75935a0cbef03b89d72034bb4c189d381037a5ac121a70016db8896ec
signature: 304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503
-
+
The serialized signed transaction is: 01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000
This example shows how unexecuted OP_CODESEPARATOR is processed, and SINGLE|ANYONECANPAY does not commit to the input index:
-
-
+
+
The following is an unsigned transaction:
0100000002e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac00000000
-
+
nVersion: 01000000
txin: 02 e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc001 00000000 00 ffffffff
80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b 00000000 00 ffffffff
txout: 02 8096980000000000 1976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac
8096980000000000 1976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac
nLockTime: 00000000
-
+
The first input comes from a native P2WSH witness program:
scriptPubKey: 0020ba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d value: 0.16777215
witnessScript:0063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac
0 IF CODESEPARATOR ENDIF <0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98> CHECKSIG
-
+
The second input comes from a native P2WSH witness program:
scriptPubKey: 0020d9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537 value: 0.16777215
witnessScript:5163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac
1 IF CODESEPARATOR ENDIF <0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98> CHECKSIG
-
+
To sign it with a nHashType of 0x83 (SINGLE|ANYONECANPAY):
-
+
nVersion: 01000000
hashPrevouts: 0000000000000000000000000000000000000000000000000000000000000000
hashSequence: 0000000000000000000000000000000000000000000000000000000000000000
@@ -357,7 +357,7 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an
hashOutputs: (see below)
nLockTime: 00000000
nHashType: 83000000
-
+
outpoint: e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc00100000000
scriptCode: 270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac
(since the OP_CODESEPARATOR is not executed, nothing is removed from the scriptCode)
@@ -367,7 +367,7 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an
public key: 0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98
private key: f52b3484edd96598e02a9c89c4492e9c1e2031f471c49fd721fe68b3ce37780d
signature: 3045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683
-
+
outpoint: 80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b00000000
scriptCode: 2468210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac
(everything up to the last executed OP_CODESEPARATOR, including that OP_CODESEPARATOR, are removed)
@@ -377,7 +377,7 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an
public key: 0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98
private key: f52b3484edd96598e02a9c89c4492e9c1e2031f471c49fd721fe68b3ce37780d
signature: 30440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83
-
+
The serialized signed transaction is:
01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000
nVersion: 01000000
@@ -390,7 +390,7 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an
witness 02 483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683 270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac
02 4730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83 275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac
nLockTime: 00000000
-
+
Since SINGLE|ANYONECANPAY does not commit to the input index, the signatures are still valid when the input-output pairs are swapped:
0100000000010280e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffffe9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff0280969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac80969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000
nVersion: 01000000
@@ -408,37 +408,37 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an
This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 different SIGHASH types.
-
-
+
+
The following is an unsigned transaction: 010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000
-
+
nVersion: 01000000
txin: 01 36641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e 01000000 00 ffffffff
txout: 02 00e9a43500000000 1976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688ac
c0832f0500000000 1976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac
nLockTime: 00000000
-
+
The input comes from a P2SH-P2WSH 6-of-6 multisig witness program:
scriptPubKey : a9149993a429037b5d912407a71c252019287b8d27a587, value: 9.87654321
redeemScript : 0020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54
witnessScript: 56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae
-
+
hashPrevouts:
dSHA256(36641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000)
= 74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0
-
+
hashSequence:
dSHA256(ffffffff)
= 3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044
-
+
hashOutputs for ALL:
dSHA256(00e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac)
= bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc
-
+
hashOutputs for SINGLE:
dSHA256(00e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688ac)
= 9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f708
-
+
hash preimage for ALL: 0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa03bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e7066504436641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc0000000001000000
nVersion: 01000000
hashPrevouts: 74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0
@@ -454,7 +454,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe
public key: 0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3
private key: 730fff80e1413068a05b57d6a58261f07551163369787f349438ea38ca80fac6
signature: 304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01
-
+
hash preimage for NONE: 0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000002000000
nVersion: 01000000
hashPrevouts: 74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0
@@ -470,7 +470,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe
public key: 03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b
private key: 11fa3d25a17cbc22b29c44a484ba552b5a53149d106d3d853e22fdd05a2d8bb3
signature: 3044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502
-
+
hash preimage for SINGLE: 0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f7080000000003000000
nVersion: 01000000
hashPrevouts: 74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0
@@ -486,7 +486,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe
public key: 034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a
private key: 77bf4141a87d55bdd7f3cd0bdccf6e9e642935fec45f2f30047be7b799120661
signature: 3044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403
-
+
hash preimage for ALL|ANYONECANPAY: 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc0000000081000000
nVersion: 01000000
hashPrevouts: 0000000000000000000000000000000000000000000000000000000000000000
@@ -502,7 +502,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe
public key: 033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4
private key: 14af36970f5025ea3e8b5542c0f8ebe7763e674838d08808896b63c3351ffe49
signature: 3045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381
-
+
hash preimage for NONE|ANYONECANPAY: 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000082000000
nVersion: 01000000
hashPrevouts: 0000000000000000000000000000000000000000000000000000000000000000
@@ -518,7 +518,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe
public key: 03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16
private key: fe9a95c19eef81dde2b95c1284ef39be497d128e2aa46916fb02d552485e0323
signature: 3045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a0882
-
+
hash preimage for SINGLE|ANYONECANPAY: 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f7080000000083000000
nVersion: 01000000
hashPrevouts: 0000000000000000000000000000000000000000000000000000000000000000
@@ -534,7 +534,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe
public key: 02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b
private key: 428a7aee9f0c2af0cd19af3cf1c78149951ea528726989b2e83e4778d2c3f890
signature: 30440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783
-
+
The serialized signed transaction is: 0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000
@@ -542,35 +542,35 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe
These examples show that FindAndDelete for the signature is not applied. The transactions are generated in an unconventional way. Instead of signing using a private key, the signatures are pre-determined as part of witnessScript. The public keys are generated with key recovery, using the fixed signatures and the sighash defined in this proposal. Therefore, the private keys are unknown.
-
+
The following is an unsigned transaction: 010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff0101000000000000000000000000
-
+
nVersion: 01000000
txin: 01 69c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1 4c1d0000 00 ffffffff
txout: 01 0100000000000000 00
nLockTime: 00000000
-
+
The input comes from a P2WSH witness program:
- scriptPubKey : 00209e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19, value: 200000
+ scriptPubKey : 00209e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19, value: 0.00200000
redeemScript : OP_CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01>
ad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01
-
+
To sign it with a nHashType of 1 (SIGHASH_ALL):
-
+
hashPrevouts:
dSHA256(69c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d0000)
= b67c76d200c6ce72962d919dc107884b9d5d0e26f2aea7474b46a1904c53359f
-
+
hashSequence:
dSHA256(ffffffff)
= 3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044
-
+
hashOutputs:
dSHA256(010000000000000000)
= e5d196bfb21caca9dbd654cafb3b4dc0c4882c8927d2eb300d9539dd0b934228
-
+
hash preimage: 01000000b67c76d200c6ce72962d919dc107884b9d5d0e26f2aea7474b46a1904c53359f3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e7066504469c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d00004aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01400d030000000000ffffffffe5d196bfb21caca9dbd654cafb3b4dc0c4882c8927d2eb300d9539dd0b9342280000000001000000
-
+
nVersion: 01000000
hashPrevouts: b67c76d200c6ce72962d919dc107884b9d5d0e26f2aea7474b46a1904c53359f
hashSequence: 3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044
@@ -581,11 +581,11 @@ These examples show that FindAndDelete for the signature is not app
hashOutputs: e5d196bfb21caca9dbd654cafb3b4dc0c4882c8927d2eb300d9539dd0b934228
nLockTime: 00000000
nHashType: 01000000
-
+
sigHash: 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23
signature: 30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e 01
pubkey: 02a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c
-
+
The serialized signed transaction is: 0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000
nVersion: 01000000
@@ -597,11 +597,11 @@ These examples show that FindAndDelete for the signature is not app
2102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c
4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01
nLockTime: 00000000
-
-
+
+
The following transaction is a OP_CHECKMULTISIGVERIFY version of the FindAndDelete examples: 010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000
-
+
redeemScript: OP_2 OP_CHECKMULTISIGVERIFY <30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> <304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601>
hash preimage: 0100000039283953eb1e26994dde57b7f9362a79a8c523e2f8deba943c27e826a005f1e63bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e706650449275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d00009552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175400d030000000000ffffffffe5d196bfb21caca9dbd654cafb3b4dc0c4882c8927d2eb300d9539dd0b9342280000000001000000
sighash: c1628a1e7c67f14ca0c27c06e4fdeec2e6d1a73c7a91d7c046ff83e835aebb72
@@ -618,7 +618,7 @@ The new serialization format is described in BIP144 [[bip-0144.mediawiki|BI
== Deployment ==
-This proposal is deployed with Segregated Witness softfork (BIP 141)
+This proposal is deployed with Segregated Witness softfork (BIP 141)
== Backward compatibility ==
diff --git a/bip-0144.mediawiki b/bip-0144.mediawiki
index 8ec2191c82..56e075a40f 100644
--- a/bip-0144.mediawiki
+++ b/bip-0144.mediawiki
@@ -79,7 +79,7 @@ The serialization has the following structure:
Parsers supporting this BIP will be able to distinguish between the old serialization format (without the witness) and this one. The marker byte is set to zero so that this structure will never parse as a valid transaction in a parser that does not support this BIP. If parsing were to succeed, such a transaction would contain no inputs and a single output.
-If the witness is empty, the old serialization format must be used.
+If the witness is empty, the old serialization format must be used.
Currently, the only witness objects type supported are script witnesses which consist of a stack of byte arrays. It is encoded as a var_int item count followed by each item encoded as a var_int length followed by a string of bytes. Each txin has its own script witness. The number of script witnesses is not explicitly encoded as it is implied by txin_count. Empty script witnesses are encoded as a zero byte. The order of the script witnesses follows the same order as the associated txins.
diff --git a/bip-0150.mediawiki b/bip-0150.mediawiki
index 277341db55..bddc2e11b7 100644
--- a/bip-0150.mediawiki
+++ b/bip-0150.mediawiki
@@ -5,7 +5,7 @@
Author: Jonas Schnelli
Comments-Summary: Discouraged for implementation (one person)
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0150
- Status: Draft
+ Status: Deferred
Type: Standards Track
Created: 2016-03-23
License: PD
diff --git a/bip-0151.mediawiki b/bip-0151.mediawiki
index 005c5527c2..01a04d1771 100644
--- a/bip-0151.mediawiki
+++ b/bip-0151.mediawiki
@@ -5,10 +5,11 @@
Author: Jonas Schnelli
Comments-Summary: Controversial; some recommendation, and some discouragement
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0151
- Status: Withdrawn
+ Status: Replaced
Type: Standards Track
Created: 2016-03-23
License: PD
+ Superseded-By: 324
== Abstract ==
@@ -84,13 +85,13 @@ a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output is used
Poly1305, also by Daniel Bernstein [4], is a one-time Carter-Wegman MAC that computes a 128 bit integrity tag given a message and a single-use
256 bit secret key.
-The chacha20-poly1305@openssh.com specified and defined by openssh [5] combines these two primitives into an authenticated encryption mode. The construction used is based on that proposed for TLS by Adam Langley [6], but differs in the layout of data passed to the MAC and in the addition of encyption of the packet lengths.
+The chacha20-poly1305@openssh.com specified and defined by openssh [5] combines these two primitives into an authenticated encryption mode. The construction used is based on that proposed for TLS by Adam Langley [6], but differs in the layout of data passed to the MAC and in the addition of encryption of the packet lengths.
K_1 must be used to only encrypt the payload size of the encrypted message to avoid leaking information by revealing the message size.
K_2 must be used in conjunction with poly1305 to build an AEAD.
-Optimized implementations of ChaCha20-Poly1305 are very fast in general, therefore it is very likely that encrypted messages require less CPU cycles per byte then the current unencrypted p2p message format. A quick analysis by Pieter Wuille of the current ''standard implementations'' has shown that SHA256 requires more CPU cycles per byte then ChaCha20 & Poly1304.
+Optimized implementations of ChaCha20-Poly1305 are very fast in general, therefore it is very likely that encrypted messages require less CPU cycles per byte than the current unencrypted p2p message format. A quick analysis by Pieter Wuille of the current ''standard implementations'' has shown that SHA256 requires more CPU cycles per byte than ChaCha20 & Poly1304.
=== The encack message type ===
diff --git a/bip-0152.mediawiki b/bip-0152.mediawiki
index 8200714b95..a2ca16cee2 100644
--- a/bip-0152.mediawiki
+++ b/bip-0152.mediawiki
@@ -195,7 +195,7 @@ Compact blocks version 2 is almost identical to version 1, but supports segregat
# Note that this spec does not change the requirement that nodes only relay information about blocks which they have fully validated in response to GETDATA/GETHEADERS/GETBLOCKS/etc requests. Nodes which announce using CMPCTBLOCK message and then receive a request for associated block data SHOULD ensure that messages do not go unresponded to, and that the appropriate data is provided after the block has been validated, subject to standard message-response ordering requirements. Note that no requirement is added that the node respond to the request with the new block included in eg GETHEADERS or GETBLOCKS messages, but the node SHOULD re-announce the block using the associated announcement methods after validation has completed if it is not included in the original response. On the other hand, nodes SHOULD delay responding to GETDATA requests for the block until validation has completed, stalling all message processing for the associated peer. REJECT messages are not considered "responses" for the purpose of this section.
-# As a result of the above requirements, implementors may wish to consider the potential for the introduction of delays in responses while remote peers validate blocks, avoiding delay-causing requests where possible.
+# As a result of the above requirements, implementers may wish to consider the potential for the introduction of delays in responses while remote peers validate blocks, avoiding delay-causing requests where possible.
==Justification==
@@ -209,9 +209,9 @@ There are several design goals for the Short ID calculation:
* '''Space''' cmpctblock messages are never optional in this protocol, and contain a short ID for each non-prefilled transaction in the block. Thus, the size of short IDs is directly proportional to the maximum bandwidth savings possible.
* '''Collision resistance''' It should be hard for network participants to create transactions that cause collisions. If an attacker were able to cause such collisions, filling mempools (and, thus, blocks) with them would cause poor network propagation of new (or non-attacker, in the case of a miner) blocks.
-SipHash is a secure, fast, and simple 64-bit MAC designed for network traffic authentication and collision-resistant hash tables. We truncate the output from SipHash-2-4 to 48 bits (see next section) in order to minimize space. The resulting 48-bit hash is certainly not large enough to avoid intentionally created individual collisons, but by using the block hash as a key to SipHash, an attacker cannot predict what keys will be used once their transactions are actually included in a relayed block. We mix in a per-connection 64-bit nonce to obtain independent short IDs on every connection, so that even block creators cannot control where collisions occur, and random collisions only ever affect a small number of connections at any given time. The mixing is done using SHA256(block_header || nonce), which is slow compared to SipHash, but only done once per block. It also adds the ability for nodes to choose the nonce in a better than random way to minimize collisions, though that is not necessary for correct behaviour. Conversely, nodes can also abuse this ability to increase their ability to introduce collisions in the blocks they relay themselves. However, they can already cause more problems by simply refusing to relay blocks. That is inevitable, and this design only seeks to prevent network-wide misbehavior.
+SipHash is a secure, fast, and simple 64-bit MAC designed for network traffic authentication and collision-resistant hash tables. We truncate the output from SipHash-2-4 to 48 bits (see next section) in order to minimize space. The resulting 48-bit hash is certainly not large enough to avoid intentionally created individual collisions, but by using the block hash as a key to SipHash, an attacker cannot predict what keys will be used once their transactions are actually included in a relayed block. We mix in a per-connection 64-bit nonce to obtain independent short IDs on every connection, so that even block creators cannot control where collisions occur, and random collisions only ever affect a small number of connections at any given time. The mixing is done using SHA256(block_header || nonce), which is slow compared to SipHash, but only done once per block. It also adds the ability for nodes to choose the nonce in a better than random way to minimize collisions, though that is not necessary for correct behaviour. Conversely, nodes can also abuse this ability to increase their ability to introduce collisions in the blocks they relay themselves. However, they can already cause more problems by simply refusing to relay blocks. That is inevitable, and this design only seeks to prevent network-wide misbehavior.
-====Random collision probabilty====
+====Random collision probability====
Thanks to the block-header-based SipHash keys, we can assume that the only collisions on links between honest nodes are random ones.
diff --git a/bip-0154.mediawiki b/bip-0154.mediawiki
index c1e4cdb5d4..8e64787975 100644
--- a/bip-0154.mediawiki
+++ b/bip-0154.mediawiki
@@ -71,7 +71,7 @@ solve the challenge and reconnect, or discard it and find a different peer (or w
There are two POW identifiers currently. When a new identifier is introduced, it should be added with an increment of 1
to the last identifier in the list. When an identifier is deprecated, its status should be changed to Deprecated but it should
-retain its place in the list indefinitely.
+retain its place in the list indefinitely.
{|class="wikitable"
! ID !! Algorithm Name !! Work !! Param size !! Solution size !! Provably Secure !! SPH Resistance !! Status
@@ -166,14 +166,14 @@ Solution format:
Additional notes:
* The initial nonce value used for finding a graph with a suitable solution should be randomized, or a challenger may deliberately pick a challenge with "poor" outcomes to fool a node into spending more than predicted time solving.
-* Further information on the recommended challenge parameters can be found here: http://bc-2.jp/cuckoo-profile.pdf
+* Further information on the recommended challenge parameters can be found here: https://web.archive.org/web/20230207054058/http://bc-2.jp/cuckoo-profile.pdf
===Purpose Identifiers===
There is only one Purpose Identifier currently. In the future, more Purpose Identifiers could be added for at-DoS-risk operations,
such as bloom filters. When a new identifier is introduced, it should be added with an increment of 1 to the last identifier in the
list. When an identifier is deprecated, its status should be changed to Deprecated but it should retain its place in
-the list indefinitely.
+the list indefinitely.
{|class="wikitable"
! ID !! Purpose Name !! Description !! Status
@@ -236,7 +236,7 @@ Normally mid-layer (all but the last) POW algorithms have a zero-length input. E
|-
| 1..4 || pow-id || 1 || sha256
|-
-| 5 || pow-params (config_length) || 9 ||
+| 5 || pow-params (config_length) || 9 ||
|-
| 6..9 || pow-params (target) || 0x207fffff || Resulting hash must be <= the compact hash 0x207fffff*
|-
@@ -248,7 +248,7 @@ Normally mid-layer (all but the last) POW algorithms have a zero-length input. E
|-
| 19..22 || pow-id || 2 || cuckoo-cycle
|-
-| 23 || pow-params (config_length) || 8 ||
+| 23 || pow-params (config_length) || 8 ||
|-
| 24 || pow-params (sizeshift) || 28
|-
diff --git a/bip-0155.mediawiki b/bip-0155.mediawiki
index 3e7b0d829d..413fb7501a 100644
--- a/bip-0155.mediawiki
+++ b/bip-0155.mediawiki
@@ -26,7 +26,7 @@ This BIP is licensed under the 2-clause BSD license.
===Motivation===
Tor v3 hidden services are part of the stable release of Tor since version 0.3.2.9. They have
-various advantages compared to the old hidden services, among which better encryption and privacy
+various advantages compared to the old hidden services, among which are better encryption and privacy
[https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt Tor Rendezvous Specification - Version 3].
These services have 256 bit addresses and thus do not fit in the existing addr message, which encapsulates onion addresses in OnionCat IPv6 addresses.
@@ -44,7 +44,7 @@ interpreted as described in RFC 2119[https://tools.ietf.org/html/rfc2119 RF
The addrv2 message is defined as a message where pchCommand == "addrv2".
It is serialized in the standard encoding for P2P messages.
-Its format is similar to the current addr message format, with the difference that the
+Its format is similar to the current addr message format, with the difference that the
fixed 16-byte IP address is replaced by a network ID and a variable-length address, and the services format has been changed to [https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer CompactSize].
This means that the message contains a serialized std::vector of the following structure:
@@ -117,6 +117,11 @@ The list of reserved network IDs is as follows:
| CJDNS
| 16
| Cjdns overlay network address
+|-
+| 0x07
+| YGGDRASIL
+| 16
+| Yggdrasil overlay network address
|}
Clients are RECOMMENDED to gossip addresses from all known networks even if they are currently not connected to some of them. That could help multi-homed nodes and make it more difficult for an observer to tell which networks a node is connected to.
@@ -184,6 +189,10 @@ I2P addresses MUST be sent with the I2P network ID, with the decode
Cjdns addresses are simply IPv6 addresses in the fc00::/8 range[https://github.com/cjdelisle/cjdns/blob/6e46fa41f5647d6b414612d9d63626b0b952746b/doc/Whitepaper.md#pulling-it-all-together Cjdns whitepaper: Pulling It All Together]. They MUST be sent with the CJDNS network ID.
+==Appendix E: Yggdrasil address encoding==
+
+Yggdrasil addresses are simply IPv6 addresses in the 0200::/7 range[https://yggdrasil-network.github.io/faq.html#will-yggdrasil-conflict-with-my-network-routing Yggdrasil FAQ]. They MUST be sent with the YGGDRASIL network ID.
+
==References==
diff --git a/bip-0156.mediawiki b/bip-0156.mediawiki
index dcfed1f6b4..3fa486a259 100644
--- a/bip-0156.mediawiki
+++ b/bip-0156.mediawiki
@@ -109,7 +109,7 @@ Figure 3
To avoid this issue, we suggest "per-inbound-edge" routing. Each inbound peer is
assigned a particular Dandelion destination. Each Dandelion transaction that
-arrives via this peer is forwarded to the same Dandelion destination.
+arrives via this peer is forwarded to the same Dandelion destination.
Per-inbound-edge routing breaks the described attack by blocking an adversary's
ability to construct useful fingerprints. Fingerprints arise when routing
decisions are made independently per transaction at each node. In this case, two
diff --git a/bip-0157.mediawiki b/bip-0157.mediawiki
index bb864aa91b..a07dba8f5b 100644
--- a/bip-0157.mediawiki
+++ b/bip-0157.mediawiki
@@ -355,7 +355,7 @@ random-access disk reads.
Nodes SHOULD NOT generate filters dynamically on request, as malicious peers may
be able to perform DoS attacks by requesting small filters derived from large
-blocks. This would require an asymmetical amount of I/O on the node to compute
+blocks. This would require an asymmetrical amount of I/O on the node to compute
and serve, similar to attacks against BIP 37 enabled nodes noted in BIP 111.
Nodes MAY prune block data after generating and storing all filters for a block.
@@ -396,7 +396,7 @@ Once the client has downloaded and verified all filter headers needed, ''and''
no outbound peers have sent conflicting headers, the client can download the
actual block filters it needs. The client MAY backfill filter headers before the
first verified one at this point if it only downloaded them starting at a later
-point. Clients SHOULD persist the verified filter headers for last 100 blocks in
+point. Clients SHOULD persist the verified filter headers for the last 100 blocks in
the chain (or whatever finality depth is desired), to compare against headers
received from new peers after restart. They MAY store more filter headers to
avoid redownloading them if a rescan is later necessary.
@@ -431,9 +431,9 @@ document proposes a solution purely at the P2P layer.
The constant interval of 1,000 blocks between checkpoints was chosen so that,
given the current chain height and rate of growth, the size of a
-cfcheckpt message is not drastically from a
-cfheaders between two checkpoints. Also, 1,000 is a nice round
-number, at least to those of us who think in decimal.
+cfcheckpt message is not drastically different from a
+cfheaders message between two checkpoints. Also, 1,000 is a nice
+round number, at least to those of us who think in decimal.
== Compatibility ==
diff --git a/bip-0158.mediawiki b/bip-0158.mediawiki
index ce4a4af949..ad4bfd0246 100644
--- a/bip-0158.mediawiki
+++ b/bip-0158.mediawiki
@@ -39,9 +39,6 @@ that is designed to reduce the filter size for regular wallets.
''CompactSize'' is a compact encoding of unsigned integers used in the Bitcoin
P2P protocol.
-''Data pushes'' are byte vectors pushed to the stack according to the rules of
-Bitcoin script.
-
''Bit streams'' are readable and writable streams of individual bits. The
following functions are used in the pseudocode in this document:
* new_bit_stream instantiates a new writable bit stream
@@ -85,7 +82,7 @@ one is able to select both Parameters independently, then more optimal values
can be
selectedhttps://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845.
Set membership queries against the hash outputs will have a false positive rate
-of M. To avoid integer overflow, the number of items N
+of 1 / M. To avoid integer overflow, the number of items N
MUST be <2^32 and M MUST be <2^32.
The items are first passed through the pseudorandom function ''SipHash'', which
@@ -189,7 +186,7 @@ golomb_decode(stream, P: uint) -> uint64:
A GCS is constructed from four parameters:
* L, a vector of N raw items
* P, the bit parameter of the Golomb-Rice coding
-* M, the target false positive rate
+* M, the inverse of the target false positive rate
* k, the 128-bit key used to randomize the SipHash outputs
The result is a byte vector with a minimum size of N * (P + 1)
@@ -273,10 +270,8 @@ This BIP defines one initial filter type:
The basic filter is designed to contain everything that a light client needs to
sync a regular Bitcoin wallet. A basic filter MUST contain exactly the
following items for each transaction in a block:
-* The previous output script (the script being spent) for each input, except
- for the coinbase transaction.
-* The scriptPubKey of each output, aside from all OP_RETURN output
- scripts.
+* The previous output script (the script being spent) for each input, except for the coinbase transaction.
+* The scriptPubKey of each output, aside from all OP_RETURN output scripts.
Any "nil" items MUST NOT be included into the final set of filter elements.
@@ -299,9 +294,9 @@ one is able to select P and M independently, then
setting M=1.497137 * 2^P is close to optimal
https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845.
-Empirical analysis also shows that was chosen as these parameters minimize the
-bandwidth utilized, considering both the expected number of blocks downloaded
-due to false positives and the size of the filters themselves.
+Empirical analysis also shows that these parameters minimize the bandwidth
+utilized, considering both the expected number of blocks downloaded due to false
+positives and the size of the filters themselves.
The parameter k MUST be set to the first 16 bytes of the hash
(in standard little-endian representation) of the block for which the filter is
@@ -314,6 +309,8 @@ complete serialization of a filter is:
* N, encoded as a CompactSize
* The bytes of the compressed filter itself
+A zero element filter MUST be written as one byte containing zeroes.
+
==== Signaling ====
This BIP allocates a new service bit:
@@ -347,7 +344,7 @@ Light client: [https://github.com/lightninglabs/neutrino]
Full-node indexing: https://github.com/Roasbeef/btcd/tree/segwit-cbf
-Golomb-Rice Coded sets: https://github.com/btcsuite/btcutil/blob/master/gcs
+Golomb-Rice Coded sets: https://github.com/btcsuite/btcd/tree/master/btcutil/gcs
== Appendix A: Alternatives ==
diff --git a/bip-0158/gentestvectors.go b/bip-0158/gentestvectors.go
index 3435eb3cf7..bf6d9a741e 100644
--- a/bip-0158/gentestvectors.go
+++ b/bip-0158/gentestvectors.go
@@ -2,7 +2,7 @@
// 5 blocks and collision space sizes of 1-32 bits. Change the RPC cert path
// and credentials to run on your system. The program assumes you're running
// a btcd with cfilter support, which mainline btcd doesn't have; in order to
-// circumvent this assumption, comment out the if block that checks for
+// circumvent this assumption, comment out the if block that checks the
// filter size of DefaultP.
package main
@@ -37,7 +37,7 @@ var (
{49291, "Tx pays to empty output script"},
{180480, "Tx spends from empty output script"},
{926485, "Duplicate pushdata 913bcc2be49cb534c20474c4dee1e9c4c317e7eb"},
- {987876, "Coinbase tx has unparseable output script"},
+ {987876, "Coinbase tx has unparsable output script"},
{1263442, "Includes witness data"},
{1414221, "Empty data"},
}
@@ -193,7 +193,7 @@ func main() {
block, err := client.GetBlock(blockHash)
if err != nil {
- fmt.Println("Couldn't get block hash: ", err.Error())
+ fmt.Println("Couldn't get block data: ", err.Error())
return
}
@@ -207,7 +207,7 @@ func main() {
prevOutputScripts, err := fetchPrevOutputScripts(client, block)
if err != nil {
- fmt.Println("Couldn't fetch prev output scipts: ", err)
+ fmt.Println("Couldn't fetch prev output scripts: ", err)
return
}
@@ -223,7 +223,7 @@ func main() {
}
// We'll now ensure that we've constructed the same filter as
- // the chain server we're fetching blocks form.
+ // the chain server we're fetching blocks from.
filter, err := client.GetCFilter(
blockHash, wire.GCSFilterRegular,
)
diff --git a/bip-0159.mediawiki b/bip-0159.mediawiki
index 022669254b..1211a0fafd 100644
--- a/bip-0159.mediawiki
+++ b/bip-0159.mediawiki
@@ -5,7 +5,7 @@
Author: Jonas Schnelli
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0159
- Status: Draft
+ Status: Final
Type: Standards Track
Created: 2017-05-11
License: BSD-2-Clause
@@ -13,15 +13,15 @@
== Abstract ==
-Define a service bit that allow pruned peers to signal their limited services
+Define a service bit that allows pruned peers to signal their limited services.
==Motivation==
-Pruned peers can offer the same services as traditional peer except of serving all historical blocks.
-Bitcoin right now only offers the NODE_NETWORK service bit which indicates that a peer can serve
+Pruned peers can offer the same services as traditional peers, except that of serving all historical blocks.
+Bitcoin right now only offers the NODE_NETWORK service bit to indicate that a peer can serve
all historical blocks.
-# Pruned peers can relay blocks, headers, transactions, addresses and can serve a limited number of historical blocks, thus they should have a way how to announce their service(s)
-# Peers no longer in initial block download should consider connecting some of its outbound connections to pruned peers to allow other peers to bootstrap from non-pruned peers
+# Pruned peers can relay blocks, headers, transactions, and addresses, but they only guarantee serving a minimum number of historical blocks; thus, they should have a way to announce their service(s)
+# Peers no longer in initial block download should consider connecting some of their outbound connections to pruned peers, to allow other peers to bootstrap from non-pruned peers
== Specification ==
@@ -34,6 +34,8 @@ This BIP proposes a new service bit
| NODE_NETWORK_LIMITED || bit 10 (0x400) || If signaled, the peer MUST be capable of serving at least the last 288 blocks (~2 days).
|}
+Pruned/limited peers MUST NOT set a service bit that signals serving the complete block chain (e.g., NODE_NETWORK). Rationale: nodes that signal serving the complete block chain may also signal NODE_NETWORK_LIMITED.
+
A safety buffer of 144 blocks to handle chain reorganizations SHOULD be taken into account when connecting to a peer signaling the NODE_NETWORK_LIMITED service bit.
=== Address relay ===
@@ -42,15 +44,17 @@ Full nodes following this BIP SHOULD relay address/services (addr
=== Counter-measures for peer fingerprinting ===
-Peers may have different prune depths (depending on the peers configuration, disk space, etc.) which can result in a fingerprinting weakness (finding the prune depth through getdata requests). NODE_NETWORK_LIMITED supporting peers SHOULD avoid leaking the prune depth and therefore not serve blocks deeper than the signaled NODE_NETWORK_LIMITED threshold (288 blocks).
+Peers may have different prune depths (depending on their configuration, disk space, etc.), which can result in a fingerprinting weakness (finding the prune depth through getdata requests).
+
+Pruned nodes should therefore avoid leaking the prune depth and SHOULD NOT serve blocks deeper than the signaled NODE_NETWORK_LIMITED threshold of 288 blocks.
=== Risks ===
Pruned peers following this BIP may consume more outbound bandwidth.
-Light clients (and such) who are not checking the nServiceFlags (service bits) from a relayed addr-message may unwillingly connect to a pruned peer and ask for (filtered) blocks at a depth below their pruned depth. Light clients should therefore check the service bits (and eventually connect to peers signaling NODE_NETWORK_LIMITED if they require [filtered] blocks around the tip). Light clients obtaining peer IPs though DNS seed should use the DNS filtering option.
+Light clients (and such) who are not checking the nServiceFlags (service bits) from a relayed addr-message may unwittingly connect to a pruned peer and ask for (filtered) blocks at a depth below the peer’s pruned depth. Light clients should therefore check the service bits and either (1) connect to peers signaling NODE_NETWORK_LIMITED that preferably do not also signal serving the full block chain, if they only require (filtered) blocks around the tip, or (2) connect to peers signaling serving the full block chain if they need data older than the latest 288 blocks. Light clients obtaining peer IPs through DNS seeds should use the DNS filtering option.
-== Compatibility ==
+== Compatibility ==
This proposal is backward compatible.
diff --git a/bip-0172.mediawiki b/bip-0172.mediawiki
new file mode 100644
index 0000000000..4e964aa1d8
--- /dev/null
+++ b/bip-0172.mediawiki
@@ -0,0 +1,138 @@
+
+
+== Abstract ==
+
+This BIP proposes to formally define and standardize Bitcoin's smallest indivisible unit (1/100,000,000 of a bitcoin) as "satoshi" (singular) or "satoshis" (plural), with "sats" as the standard abbreviated form. This standardization aims to improve clarity in communication, user interfaces, documentation, and development across the Bitcoin ecosystem.
+
+== Motivation ==
+
+As Bitcoin adoption grows, the need for a clear, standardized terminology for its subunits becomes increasingly important. Currently, there are various terms used to refer to Bitcoin's smallest unit (1/100,000,000 BTC), including "satoshi", "satoshis", "sat", "sats" and sometimes simply expressed as decimal values of bitcoin (0.00000001 BTC).
+
+This lack of standardization can lead to:
+
+# Confusion for newcomers to the Bitcoin ecosystem
+# Inconsistent user experiences across different applications and services
+# Ambiguity in technical documentation and discussions
+# Potential errors in development and implementation of Bitcoin-related software
+
+By formally establishing "satoshi"/"satoshis" as the standard term with "sats" as the recognized abbreviation, we can improve clarity and consistency throughout the ecosystem.
+
+== Specification ==
+
+This BIP formally defines:
+
+# The term "satoshi" (singular) or "satoshis" (plural) shall be the standard term for 1/100,000,000 of a bitcoin (0.00000001 BTC).
+# The abbreviation "sat" (singular) or "sats" (plural) shall be the standard short form for "satoshi"/"satoshis".
+# The relationship between units shall be expressed as:
+#* 1 bitcoin (BTC) = 100,000,000 satoshis
+#* 1 satoshi = 0.00000001 bitcoin
+# The terms "satoshi" and "sats" are not proper nouns when referring to the unit of currency and should not be capitalized except at the beginning of sentences or in titles.
+# Bitcoin-related applications, services, documentation, and communications are encouraged to use these standardized terms to promote consistency across the ecosystem.
+
+== Accessibility Considerations ==
+
+To ensure clarity and inclusiveness in user interfaces and assistive technologies, the following recommendations apply:
+
+# Pronunciation:
+#* The abbreviation "sat" should be pronounced as /sæt/, and "sats" (plural) should be pronounced as /sæts/ (rhyming with "cats") by screen readers and voice assistants.
+#* "Satoshi" (singular) is pronounced /səˈtoʊʃi/. "Satoshis" (plural) is pronounced /səˈtoʊʃiz/.
+
+# Singular vs. Plural: Preserve correct pluralization when reading amounts:
+#* "1 sat" should be read as "one satoshi" (/wʌn səˈtoʊʃi/)
+#* "100 sats" should be read as "one hundred satoshis" (/wʌn ˈhʌndrəd səˈtoʊʃiz/)
+
+# Readable Formats:
+#* Prefer full terms in accessibility modes (e.g., "satoshis" instead of "sats")
+#* Group digits to assist parsing (e.g., "12,345" instead of "12345")
+
+# Contextual Labels:
+#* Interfaces should use clear alt-text or aria-labels such as: alt="Transaction fee: 14 satoshis per virtual byte"
+#* This enables screen readers and other assistive technologies to accurately interpret and communicate the content
+
+== Rationale ==
+
+Satoshi Nakamoto, the creator of Bitcoin, established that one bitcoin would be divisible to eight decimal places, creating 100,000,000 units per bitcoin. The community has organically adopted the term "satoshi" to refer to this smallest unit.
+
+As Bitcoin's value has increased, expressing smaller values in fractional bitcoins has become increasingly unwieldy (e.g., 0.00000546 BTC). Using satoshis as the unit of account for smaller values (e.g., 546 sats) is more intuitive and less error-prone for humans.
+
+The term "satoshi" and its abbreviation "sats" have already gained widespread adoption within the Bitcoin community. This BIP seeks to formalize this existing convention rather than introduce new terminology.
+
+=== Analogous to Traditional Currency Systems ===
+
+The proposed bitcoin/satoshi (or BTC/sat) standard follows the established pattern of major world currencies, which typically have a primary unit and a smaller subunit. Most notably, the United States dollar—the world's primary reserve currency—uses dollars and cents in a two-tier denomination system. This familiar dollars/cents model has proven effective and intuitive for everyday transactions across different scales.
+The bitcoin/satoshi system mirrors this approach while accounting for Bitcoin's higher divisibility requirements. Furthermore, the phonetic similarity between "sat" and "cent" creates an intuitive bridge for newcomers to understand Bitcoin's smallest unit, making the learning curve less steep for those familiar with traditional currency systems. This natural familiarity leverages existing mental models of how currency denominations work.
+
+=== Comparison with Alternative Approaches ===
+
+Two notable proposals related to Bitcoin denomination have been put forward:
+
+Our proposal represents a minimally disruptive approach to standardization, formalizing existing common practice rather than introducing new terms (BIP-176) or redefining existing ones (BIP-177).
+
+==== BIP-176: Bits Denomination ====
+
+BIP-176 proposes using "bits" as a standard term for 100 satoshis (or 0.000001 BTC). While this proposal has merit for creating a middle-ground denomination that avoids small decimal places when bitcoin's value is high, our approach differs in that it:
+
+* Formalizes existing widely adopted terminology rather than introducing or prioritizing a different unit
+* Focuses on the fundamental base unit that cannot be subdivided further within the Bitcoin protocol
+* Maintains the simplicity of a two-tier system (bitcoin and satoshi) rather than adding a third tier
+
+==== BIP-177: Redefine Bitcoin's Base Unit ====
+
+BIP-177 takes a more radical approach by proposing to redefine the term "bitcoin" to refer to what is currently called a "satoshi" (1/100,000,000 of the current bitcoin). While this proposal aims to eliminate decimal points and simplify mental calculations, our approach differs in that it:
+
+* Preserves the established meaning of "bitcoin" which has global recognition and avoids potentially confusing redefinition
+* Maintains compatibility with existing systems, documentation, and user understanding
+* Achieves similar clarity benefits through standardization without requiring a fundamental redefinition of terms
+
+== Backwards Compatibility ==
+
+This proposal does not affect the technical operation of Bitcoin or its protocol. It is purely a standardization of terminology for human communication and user interfaces.
+
+Existing applications that use other terms or conventions can continue to operate but are encouraged to adopt the standardized terms to improve overall ecosystem clarity.
+
+== Copyright ==
+
+This BIP is licensed under the BSD 2-clause license.
+
+== Reference Implementation ==
+
+Not applicable as this is an Informational BIP that standardizes terminology rather than implementing technical changes.
+
+== Examples ==
+
+Before standardization, various formats might be used:
+* 0.00000100 BTC
+* 100 satoshi
+* 100 satoshis
+* 100 sat
+* 100 sats
+
+After standardization, the preferred formats would be:
+* 100 satoshis (formal)
+* 100 sats (abbreviated)
+
+== Acknowledgements ==
+
+Thanks to the entire Bitcoin community who has organically adopted the terms "satoshi" and "sats" over the years. If anyone can point to early references of the term being used in this way please leave a comment so we can amend this BIP to acknowledge it.
+
+== References ==
+
+# Satoshi Nakamoto. "Bitcoin: A Peer-to-Peer Electronic Cash System" (2008)
+# BIP-176: Bits Denomination (Jimmy Song)
+
+== Glossary ==
+
+* BTC: The current universal ticker symbol for bitcoin, the cryptocurrency.
+* Satoshi: The smallest unit of bitcoin, equal to 0.00000001 BTC.
+* Sats: Abbreviation for "satoshis".
\ No newline at end of file
diff --git a/bip-0173.mediawiki b/bip-0173.mediawiki
index 1fdd8bed3c..7087fffa20 100644
--- a/bip-0173.mediawiki
+++ b/bip-0173.mediawiki
@@ -11,6 +11,7 @@
Created: 2017-03-20
License: BSD-2-Clause
Replaces: 142
+ Superseded-By: 350
==Introduction==
@@ -403,3 +404,12 @@ separator).
This document is inspired by the [https://rusty.ozlabs.org/?p=578 address proposal] by Rusty Russell, the
[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2014-February/004402.html base32] proposal by Mark Friedenbach, and had input from Luke Dashjr,
Johnson Lau, Eric Lombrozo, Peter Todd, and various other reviewers.
+
+==Disclosures (added 2024)==
+
+Due to an oversight in the design of bech32, this checksum scheme is not always
+robust against
+[[https://gist.github.com/sipa/a9845b37c1b298a7301c33a04090b2eb|the insertion
+and deletion of fewer than 5 consecutive characters]]. Due to this weakness,
+[[bip-0350.mediawiki|BIP-350]] proposes using the scheme described in this BIP
+only for Native Segwit v0 outputs.
diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki
index f3de964f97..de666221e4 100644
--- a/bip-0174.mediawiki
+++ b/bip-0174.mediawiki
@@ -2,7 +2,7 @@
BIP: 174
Layer: Applications
Title: Partially Signed Bitcoin Transaction Format
- Author: Andrew Chow
+ Author: Ava Chow
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0174
Status: Final
@@ -65,7 +65,7 @@ be used as a separator and allow for easier unserializer implementation..
Where:
;
-: A compact size unsigned integer representing the type. This compact size unsigned integer must be minimally encoded, i.e. if the value can be represented using one byte, it must be represented as one byte. There can be multiple entries with the same within a specific , but the must be unique.
+: A [https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer compact size] unsigned integer representing the type. This compact size unsigned integer must be minimally encoded, i.e. if the value can be represented using one byte, it must be represented as one byte. There can be multiple entries with the same within a specific , but the must be unique.
;
: The compact size unsigned integer containing the combined length of and
;
@@ -98,18 +98,18 @@ The currently defined global types are as follows:
| PSBT_GLOBAL_UNSIGNED_TX = 0x00
| None
| No key data
-|
+|
| The transaction in network serialization. The scriptSigs and witnesses for each input must be empty. The transaction must be in the old serialization format (without witnesses).
| 0
-|
+| 2
| 0
| 174
|-
| Extended Public Key
| PSBT_GLOBAL_XPUB = 0x01
-|
+|
| The 78 byte serialized extended public key as defined by BIP 32. Extended public keys are those that can be used to derive public keys used in the inputs and outputs of this transaction. It should be the public key at the highest hardened derivation index so that the unhardened child keys used in the transaction can be derived.
-| <32-bit uint> <32-bit uint>*
+| <4 byte fingerprint> <32-bit little endian uint path element>*
| The master key fingerprint as defined by BIP 32 concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. The number of 32 bit unsigned integer indexes must match the depth provided in the extended public key.
|
|
@@ -120,73 +120,84 @@ The currently defined global types are as follows:
| PSBT_GLOBAL_TX_VERSION = 0x02
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian int version>
| The 32-bit little endian signed integer representing the version number of the transaction being created. Note that this is not the same as the PSBT version number specified by the PSBT_GLOBAL_VERSION field.
| 2
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
| Fallback Locktime
| PSBT_GLOBAL_FALLBACK_LOCKTIME = 0x03
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint locktime>
| The 32-bit little endian unsigned integer representing the transaction locktime to use if no inputs specify a required locktime.
|
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
| Input Count
| PSBT_GLOBAL_INPUT_COUNT = 0x04
| None
| No key data
-|
+|
| Compact size unsigned integer representing the number of inputs in this PSBT.
| 2
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
| Output Count
| PSBT_GLOBAL_OUTPUT_COUNT = 0x05
| None
| No key data
-|
+|
| Compact size unsigned integer representing the number of outputs in this PSBT.
| 2
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
| Transaction Modifiable Flags
| PSBT_GLOBAL_TX_MODIFIABLE = 0x06
| None
| No key data
-|
-| A single byte boolean (0 for False, 1 for True) representing whether inputs can be modified, followed by a single byte boolean representing whether outputs can be modified.
+| <8-bit uint flags>
+| An 8 bit little endian unsigned integer as a bitfield for various transaction modification flags. Bit 0 is the Inputs Modifiable Flag and indicates whether inputs can be modified. Bit 1 is the Outputs Modifiable Flag and indicates whether outputs can be modified. Bit 2 is the Has SIGHASH_SINGLE flag and indicates whether the transaction has a SIGHASH_SINGLE signature who's input and output pairing must be preserved. Bit 2 essentially indicates that the Constructor must iterate the inputs to determine whether and how to add an input.
|
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
-| SIGHASH_SINGLE Inputs
-| PSBT_GLOBAL_SIGHASH_SINGLE_INPUTS = 0x07
-| None
-| No key data
-|
-| A bit vector representing which input indexes use SIGHASH_SINGLE. If the bit for an index is set to 1, then the input and output pair at that index are tied together with SIGHASH_SINGLE and must be moved together.
+| Silent Payment Global ECDH Share
+| PSBT_GLOBAL_SP_ECDH_SHARE = 0x07
+| <33 byte scan key>
+| The scan key that this ECDH share is for.
+| <33 byte share>
+| An ECDH share for a scan key. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the sum of all private keys of all eligible inputs, and ''B_scan'' is the scan key of a recipient.
+|
+| 0
+| 2
+| [[bip-0375.mediawiki|375]]
+|-
+| Silent Payment Global DLEQ Proof
+| PSBT_GLOBAL_SP_DLEQ = 0x08
+| <33 byte scan key>
+| The scan key that this proof covers.
+| <64-byte proof>
+| A BIP374 DLEQ proof computed for the matching ECDH share.
|
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0375.mediawiki|375]]
|-
| PSBT Version Number
| PSBT_GLOBAL_VERSION = 0xFB
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint version>
| The 32-bit little endian unsigned integer representing the version number of this PSBT. If omitted, the version number is 0.
|
|
@@ -195,9 +206,9 @@ The currently defined global types are as follows:
|-
| Proprietary Use Type
| PSBT_GLOBAL_PROPRIETARY = 0xFC
-|
-| Compact size unsigned integer , followed by identifier prefix of that length , followed by a subtype , followed by the key data itself .
-|
+|
+| Compact size unsigned integer of the length of the identifier, followed by identifier prefix, followed by a compact size unsigned integer subtype, followed by the key data itself.
+|
| Any value data as defined by the proprietary type user.
|
|
@@ -223,7 +234,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_NON_WITNESS_UTXO = 0x00
| None
| No key data
-|
+|
| The transaction in network serialization format the current input spends from. This should be present for inputs that spend non-segwit outputs and can be present for inputs that spend segwit outputs. An input can have both PSBT_IN_NON_WITNESS_UTXO and PSBT_IN_WITNESS_UTXO. '''Why can both UTXO types be provided?''' Many wallets began requiring the full previous transaction (i.e. PSBT_IN_NON_WITNESS_UTXO) for segwit inputs when PSBT was already in use. In order to be compatible with software which were expecting PSBT_IN_WITNESS_UTXO, both UTXO types must be allowed.
|
|
@@ -234,7 +245,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_WITNESS_UTXO = 0x01
| None
| No key data
-| <64-bit int>
+| <64-bit little endian int amount>
| The entire transaction output in network serialization which the current input spends from. This should only be present for inputs which spend segwit outputs, including P2SH embedded ones. An input can have both PSBT_IN_NON_WITNESS_UTXO and PSBT_IN_WITNESS_UTXO
|
|
@@ -243,10 +254,10 @@ The currently defined per-input types are defined as follows:
|-
| Partial Signature
| PSBT_IN_PARTIAL_SIG = 0x02
-|
+|
| The public key which corresponds to this signature.
-|
-| The signature as would be pushed to the stack from a scriptSig or witness.
+|
+| The signature as would be pushed to the stack from a scriptSig or witness. The signature should be a valid ECDSA signature corresponding to the pubkey that would return true when verified and not a value that would return false or be invalid otherwise (such as a NULLDUMMY).
|
|
| 0, 2
@@ -256,7 +267,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_SIGHASH_TYPE = 0x03
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint sighash type>
| The 32-bit unsigned integer specifying the sighash type to be used for this input. Signatures for this input must use the sighash type, finalizers must fail to finalize inputs which have signatures that do not match the specified sighash type. Signers who cannot produce signatures with the sighash type must not provide a signature.
|
|
@@ -267,7 +278,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_REDEEM_SCRIPT = 0x04
| None
| No key data
-|
+|
| The redeemScript for this input if it has one.
|
|
@@ -278,7 +289,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_WITNESS_SCRIPT = 0x05
| None
| No key data
-|
+|
| The witnessScript for this input if it has one.
|
|
@@ -287,9 +298,9 @@ The currently defined per-input types are defined as follows:
|-
| BIP 32 Derivation Path
| PSBT_IN_BIP32_DERIVATION = 0x06
-|
+|
| The public key
-| <32-bit uint> <32-bit uint>*
+| <4 byte fingerprint> <32-bit little endian uint path element>*
| The master key fingerprint as defined by BIP 32 concatenated with the derivation path of the public key. The derivation path is represented as 32 bit unsigned integer indexes concatenated with each other. Public keys are those that will be needed to sign this input.
|
|
@@ -300,7 +311,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_FINAL_SCRIPTSIG = 0x07
| None
| No key data
-|
+|
| The Finalized scriptSig contains a fully constructed scriptSig with signatures and any other scripts necessary for the input to pass validation.
|
|
@@ -311,7 +322,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_FINAL_SCRIPTWITNESS = 0x08
| None
| No key data
-|
+|
| The Finalized scriptWitness contains a fully constructed scriptWitness with signatures and any other scripts necessary for the input to pass validation.
|
|
@@ -322,7 +333,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_POR_COMMITMENT = 0x09
| None
| No key data
-|
+|
| The UTF-8 encoded commitment message string for the proof-of-reserves. See [[bip-0127.mediawiki|BIP 127]] for more information.
|
|
@@ -333,7 +344,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_RIPEMD160 = 0x0a
| <20-byte hash>
| The resulting hash of the preimage
-|
+|
| The hash preimage, encoded as a byte vector, which must equal the key when run through the RIPEMD160 algorithm
|
|
@@ -344,7 +355,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_SHA256 = 0x0b
| <32-byte hash>
| The resulting hash of the preimage
-|
+|
| The hash preimage, encoded as a byte vector, which must equal the key when run through the SHA256 algorithm
|
|
@@ -355,7 +366,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_HASH160 = 0x0c
| <20-byte hash>
| The resulting hash of the preimage
-|
+|
| The hash preimage, encoded as a byte vector, which must equal the key when run through the SHA256 algorithm followed by the RIPEMD160 algorithm
|
|
@@ -366,7 +377,7 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_HASH256 = 0x0d
| <32-byte hash>
| The resulting hash of the preimage
-|
+|
| The hash preimage, encoded as a byte vector, which must equal the key when run through the SHA256 algorithm twice
|
|
@@ -377,62 +388,196 @@ The currently defined per-input types are defined as follows:
| PSBT_IN_PREVIOUS_TXID = 0x0e
| None
| No key data
-|
+| <32 byte txid>
| 32 byte txid of the previous transaction whose output at PSBT_IN_OUTPUT_INDEX is being spent.
| 2
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
| Spent Output Index
| PSBT_IN_OUTPUT_INDEX = 0x0f
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint index>
| 32 bit little endian integer representing the index of the output being spent in the transaction with the txid of PSBT_IN_PREVIOUS_TXID.
| 2
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
| Sequence Number
| PSBT_IN_SEQUENCE = 0x10
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint sequence>
| The 32 bit unsigned little endian integer for the sequence number of this input. If omitted, the sequence number is assumed to be the final sequence number (0xffffffff).
|
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
| Required Time-based Locktime
| PSBT_IN_REQUIRED_TIME_LOCKTIME = 0x11
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint locktime>
| 32 bit unsigned little endian integer greater than or equal to 500000000 representing the minimum Unix timestamp that this input requires to be set as the transaction's lock time.
|
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
| Required Height-based Locktime
| PSBT_IN_REQUIRED_HEIGHT_LOCKTIME = 0x12
| None
| No key data
-| <32-bit uiht>
+| <32-bit uint locktime>
| 32 bit unsigned little endian integer less than 500000000 representing the minimum block height that this input requires to be set as the transaction's lock time.
|
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
+|-
+| Taproot Key Spend Signature
+| PSBT_IN_TAP_KEY_SIG = 0x13
+| None
+| No key data
+| <64 or 65 byte signature>
+| The 64 or 65 byte Schnorr signature for key path spending a Taproot output. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+| [[bip-0371.mediawiki|371]]
+|-
+| Taproot Script Spend Signature
+| PSBT_IN_TAP_SCRIPT_SIG = 0x14
+| <32 byte xonlypubkey>
+| A 32 byte X-only public key involved in a leaf script concatenated with the 32 byte hash of the leaf it is part of.
+| <64 or 65 byte signature>
+| The 64 or 65 byte Schnorr signature for this pubkey and leaf combination. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+| [[bip-0371.mediawiki|371]]
+|-
+| Taproot Leaf Script
+| PSBT_IN_TAP_LEAF_SCRIPT = 0x15
+|
+| The control block for this leaf as specified in BIP 341. The control block contains the merkle tree path to this leaf.
+| <8-bit uint leaf version>
+| The script for this leaf as would be provided in the witness stack followed by the single byte leaf version. Note that the leaves included in this field should be those that the signers of this input are expected to be able to sign for. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+| [[bip-0371.mediawiki|371]]
+|-
+| Taproot Key BIP 32 Derivation Path
+| PSBT_IN_TAP_BIP32_DERIVATION = 0x16
+| <32 byte xonlypubkey>
+| A 32 byte X-only public key involved in this input. It may be the output key, the internal key, or a key present in a leaf script.
+| <32 byte leaf hash>* <4 byte fingerprint> <32-bit little endian uint path element>*
+| A compact size unsigned integer representing the number of leaf hashes, followed by a list of leaf hashes, followed by the 4 byte master key fingerprint concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. Public keys are those needed to spend this output. The leaf hashes are of the leaves which involve this public key. The internal key does not have leaf hashes, so can be indicated with a hashes len of 0. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+| [[bip-0371.mediawiki|371]]
+|-
+| Taproot Internal Key
+| PSBT_IN_TAP_INTERNAL_KEY = 0x17
+| None
+| No key data
+| <32 byte xonlypubkey>
+| The X-only pubkey used as the internal key in this output. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+| [[bip-0371.mediawiki|371]]
+|-
+| Taproot Merkle Root
+| PSBT_IN_TAP_MERKLE_ROOT = 0x18
+| None
+| No key data
+| <32-byte hash>
+| The 32 byte Merkle root hash. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+| [[bip-0371.mediawiki|371]]
+|-
+| MuSig2 Participant Public Keys
+| PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1a
+| <33 byte plain aggregate pubkey>
+| The MuSig2 aggregate plain public key from the KeyAgg algorithm. This key may or may not
+be in the script directly (as x-only). It may instead be a parent public key from which the public keys in the
+script were derived.
+| <33 byte compressed pubkey>*
+| A list of the compressed public keys of the participants in the MuSig2 aggregate key in the order
+required for aggregation. If sorting was done, then the keys must be in the sorted order.
+|
+|
+| 0, 2
+| [[bip-0373.mediawiki|373]]
+|-
+| MuSig2 Public Nonce
+| PSBT_IN_MUSIG2_PUB_NONCE = 0x1b
+| <33 byte compressed pubkey> <33 byte plain pubkey> <32 byte hash or omitted>
+| The compressed public key of the participant providing this nonce, followed by the plain public
+key the participant is providing the nonce for, followed by the BIP 341 tapleaf hash of
+the Taproot leaf script that will be signed. If the aggregate key is the taproot internal key or the
+taproot output key, then the tapleaf hash must be omitted. The plain public key must be
+the key found in the script and not the aggregate public key that it was derived from, if it was
+derived from an aggregate key.
+| <66 byte public nonce>
+| The public nonce produced by the NonceGen algorithm.
+|
+|
+| 0, 2
+| [[bip-0373.mediawiki|373]]
+|-
+| MuSig2 Participant Partial Signature
+| PSBT_IN_MUSIG2_PARTIAL_SIG = 0x1c
+| <33 byte compressed pubkey> <33 byte plain pubkey> <32 byte hash or omitted>
+| The compressed public key of the participant providing this partial signature, followed by the
+plain public key the participant is providing the signature for, followed by the BIP 341 tapleaf hash
+of the Taproot leaf script that will be signed. If the aggregate key is the taproot internal key or
+the taproot output key, then the tapleaf hash must be omitted. Note that the plain public key must
+be the key found in the script and not the aggregate public key that it was derived from, if it was
+derived from an aggregate key.
+| <32 byte partial signature>
+| The partial signature produced by the Sign algorithm.
+|
+|
+| 0, 2
+| [[bip-0373.mediawiki|373]]
+|-
+| Silent Payment Input ECDH Share
+| PSBT_IN_SP_ECDH_SHARE = 0x1d
+| <33 byte scan key>
+| The scan key that this ECDH share is for.
+| <33 byte share>
+| An ECDH share for a scan key. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the private key of the corresponding prevout public key, and ''B_scan'' is the scan key of a recipient.
+|
+| 0
+| 2
+| [[bip-0375.mediawiki|375]]
+|-
+| Silent Payment Input DLEQ Proof
+| PSBT_IN_SP_DLEQ = 0x1e
+| <33 byte scan key>
+| The scan key that this proof covers.
+| <64-byte proof>
+| A BIP374 DLEQ proof computed for the matching ECDH share.
+|
+| 0
+| 2
+| [[bip-0375.mediawiki|375]]
|-
| Proprietary Use Type
| PSBT_IN_PROPRIETARY = 0xFC
-|
-| Compact size unsigned integer , followed by identifier prefix of that length , followed by a subtype , followed by the key data itself .
-|
+|
+| Compact size unsigned integer of the length of the identifier, followed by identifier prefix, followed by a compact size unsigned integer subtype, followed by the key data itself.
+|
| Any value data as defined by the proprietary type user.
|
|
@@ -460,7 +605,7 @@ determine which outputs are change outputs and verify that the change is returni
| PSBT_OUT_REDEEM_SCRIPT = 0x00
| None
| No key data
-|
+|
| The redeemScript for this output if it has one.
|
|
@@ -471,7 +616,7 @@ determine which outputs are change outputs and verify that the change is returni
| PSBT_OUT_WITNESS_SCRIPT = 0x01
| None
| No key data
-|
+|
| The witnessScript for this output if it has one.
|
|
@@ -480,9 +625,9 @@ determine which outputs are change outputs and verify that the change is returni
|-
| BIP 32 Derivation Path
| PSBT_OUT_BIP32_DERIVATION = 0x02
-|
+|
| The public key
-| <{32-bit uint> <32-bit uint>*
+| <4 byte fingerprint> <32-bit little endian uint path element>*
| The master key fingerprint concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. Public keys are those needed to spend this output.
|
|
@@ -493,29 +638,110 @@ determine which outputs are change outputs and verify that the change is returni
| PSBT_OUT_AMOUNT = 0x03
| None
| No key data
-| <64-bit int>
+| <64-bit int amount>
| 64 bit signed little endian integer representing the output's amount in satoshis.
| 2
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0370.mediawiki|370]]
|-
| Output Script
| PSBT_OUT_SCRIPT = 0x04
| None
| No key data
-|
-| The script for this output, also known as the scriptPubKey. Must be omitted in PSBTv0. Must be provided in PSBTv2.
+|
+| The script for this output, also known as the scriptPubKey. Must be omitted in PSBTv0. Must be provided in PSBTv2 if not sending to a BIP352 silent payment address, otherwise may be omitted.
+|
+| 0
+| 2
+| [[bip-0370.mediawiki|370]], [[bip-0375.mediawiki|375]]
+|-
+| Taproot Internal Key
+| PSBT_OUT_TAP_INTERNAL_KEY = 0x05
+| None
+| No key data
+| <32 byte xonlypubkey>
+| The X-only pubkey used as the internal key in this output.
+|
+|
+| 0, 2
+| [[bip-0371.mediawiki|371]]
+|-
+| Taproot Tree
+| PSBT_OUT_TAP_TREE = 0x06
+| None
+| No key data
+| {<8-bit uint depth> <8-bit uint leaf version> }*
+| One or more tuples representing the depth, leaf version, and script for a leaf in the Taproot tree, allowing the entire tree to be reconstructed. The tuples must be in depth first search order so that the tree is correctly reconstructed. Each tuple is an 8-bit unsigned integer representing the depth in the Taproot tree for this script, an 8-bit unsigned integer representing the leaf version, the length of the script as a compact size unsigned integer, and the script itself.
+|
+|
+| 0, 2
+| [[bip-0371.mediawiki|371]]
+|-
+| Taproot Key BIP 32 Derivation Path
+| PSBT_OUT_TAP_BIP32_DERIVATION = 0x07
+| <32 byte xonlypubkey>
+| A 32 byte X-only public key involved in this output. It may be the output key, the internal key, or a key present in a leaf script.
+| <32 byte leaf hash>* <4 byte fingerprint> <32-bit little endian uint path element>*
+| A compact size unsigned integer representing the number of leaf hashes, followed by a list of leaf hashes, followed by the 4 byte master key fingerprint concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. Public keys are those needed to spend this output. The leaf hashes are of the leaves which involve this public key. The internal key does not have leaf hashes, so can be indicated with a hashes len of 0. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+| [[bip-0371.mediawiki|371]]
+|-
+| MuSig2 Participant Public Keys
+| PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS = 0x08
+| <33 byte plain aggregate pubkey>
+| The MuSig2 aggregate plain public key from the KeyAgg algorithm. This key may or may not
+be in the script directly. It may instead be a parent public key from which the public keys in the
+script were derived.
+| <33 byte compressed pubkey>*
+| A list of the compressed public keys of the participants in the MuSig2 aggregate key in the order
+required for aggregation. If sorting was done, then the keys must be in the sorted order.
+|
+|
+| 0, 2
+| [[bip-0373.mediawiki|373]]
+|-
+| Silent Payment Data
+| PSBT_OUT_SP_V0_INFO = 0x09
+| None
+| No key data
+| <33 byte scan key> <33 byte spend key>
+| The scan and spend public keys from the silent payments address.
+|
+| 0
| 2
+| [[bip-0375.mediawiki|375]]
+|-
+| Silent Payment Label
+| PSBT_OUT_SP_V0_LABEL = 0x0a
+| None
+| No key data
+| <32-bit little endian uint label>
+| The label to use to compute the spend key of the silent payments address to verify change.
+|
| 0
| 2
-| [[bip-psb2.mediawiki|psbt2]]
+| [[bip-0375.mediawiki|375]]
+|-
+| BIP 353 DNSSEC proof
+| PSBT_OUT_DNSSEC_PROOF = 0x35
+| None
+| No key data
+| <1-byte-length-prefixed BIP 353 human-readable name>
+| A BIP 353 human-readable name (without the ₿ prefix), prefixed by a 1-byte length.
+Followed by an [[https://www.rfc-editor.org/rfc/rfc9102.html#name-dnssec-authentication-chain|RFC 9102 DNSSEC AuthenticationChain]] (i.e. a series of DNS Resource Records in no particular order) providing a DNSSEC proof to a BIP 353 DNS TXT record.
+|
+|
+| 0, 2
+| [[bip-0353.mediawiki|353]]
|-
| Proprietary Use Type
| PSBT_OUT_PROPRIETARY = 0xFC
-|
-| Compact size unsigned integer , followed by identifier prefix of that length , followed by a subtype , followed by the key data itself .
-|
+|
+| Compact size unsigned integer of the length of the identifier, followed by identifier prefix, followed by a compact size unsigned integer subtype, followed by the key data itself.
+|
| Any value data as defined by the proprietary type user.
|
|
@@ -536,7 +762,7 @@ the key.
===Handling Duplicated Keys===
-Keys within each scope should never be duplicated; all keys in the format are unique. PSBTs containing duplicate keys are invalid. However implementors
+Keys within each scope should never be duplicated; all keys in the format are unique. PSBTs containing duplicate keys are invalid. However implementers
will still need to handle events where keys are duplicated when combining transactions with duplicated fields. In this event, the software may choose
whichever value it wishes.'''Why can the values be arbitrarily chosen?''' When there are duplicated keys, the values that can be chosen will either be
valid or invalid. If the values are invalid, a signer would simply produce an invalid signature and the final transaction itself would be invalid. If the
@@ -545,7 +771,7 @@ values are valid, then it does not matter which is chosen as either way the tran
===Proprietary Use Type===
For all global, per-input, and per-output maps, the type 0xFC is reserved for proprietary use.
-The proprietary use type requires keys that follow the type with a compact size unsigned integer representing the length of the string identifer, followed by the string identifier, then a subtype, and finally any key data.
+The proprietary use type requires keys that follow the type with a compact size unsigned integer representing the length of the string identifier, followed by the string identifier, then a subtype, and finally any key data.
The identifier can be any variable length string that software can use to identify whether the particular data in the proprietary type can be used by it.
It can also be the empty string although this is not recommended.
@@ -588,7 +814,7 @@ The Signer must only accept a PSBT.
The Signer must only use the UTXOs provided in the PSBT to produce signatures for inputs.
Before signing a non-witness input, the Signer must verify that the TXID of the non-witness UTXO matches the TXID specified in the unsigned transaction.
Before signing a witness input, the Signer must verify that the witnessScript (if provided) matches the hash specified in the UTXO or the redeemScript, and the redeemScript (if provided) matches the hash in the UTXO.
-The Signer may choose to fail to sign a segwit input if a non-witness UTXO is not provided. '''Why would non-witness UTXOs be provided for segwit inputs?''' The sighash algorithm for Segwit specified in BIP 173 is known to have an issue where an attacker could trick a user to sending Bitcoin to fees if they are able to convince the user to sign a malicious transaction multiple times. This is possible because the amounts in PSBT_IN_WITNESS_UTXO of other segwit inputs can be modified without effecting the signature for a particular input. In order to prevent this kind of attack, many wallets are requiring that the full previous transaction (i.e. PSBT_IN_NON_WITNESS_UTXO) be provided to ensure that the amounts of other inputs are not being tampered with.
+The Signer may choose to fail to sign a segwit input if a non-witness UTXO is not provided. '''Why would non-witness UTXOs be provided for segwit inputs?''' The sighash algorithm for Segwit specified in BIP 143 is known to have an issue where an attacker could trick a user to sending Bitcoin to fees if they are able to convince the user to sign a malicious transaction multiple times. This is possible because the amounts in PSBT_IN_WITNESS_UTXO of other segwit inputs can be modified without effecting the signature for a particular input. In order to prevent this kind of attack, many wallets are requiring that the full previous transaction (i.e. PSBT_IN_NON_WITNESS_UTXO) be provided to ensure that the amounts of other inputs are not being tampered with.
The Signer should not need any additional data sources, as all necessary information is provided in the PSBT format.
The Signer must only add data to a PSBT.
Any signatures created by the Signer must be added as a "Partial Signature" key-value pair for the respective input it relates to.
@@ -630,15 +856,8 @@ sign_non_witness(script_code, i):
if IsMine(key) and IsAcceptable(sighash_type):
sign(non_witness_sighash(script_code, i, input))
-for input,i in enumerate(psbt.inputs):
- if non_witness_utxo.exists:
- assert(sha256d(non_witness_utxo) == psbt.tx.input[i].prevout.hash)
- if redeemScript.exists:
- assert(non_witness_utxo.vout[psbt.tx.input[i].prevout.n].scriptPubKey == P2SH(redeemScript))
- sign_non_witness(redeemScript, i)
- else:
- sign_non_witness(non_witness_utxo.vout[psbt.tx.input[i].prevout.n].scriptPubKey, i)
- else if witness_utxo.exists:
+for input, i in enumerate(psbt.inputs):
+ if witness_utxo.exists:
if redeemScript.exists:
assert(witness_utxo.scriptPubKey == P2SH(redeemScript))
script = redeemScript
@@ -649,6 +868,13 @@ for input,i in enumerate(psbt.inputs):
else if IsP2WSH(script):
assert(script == P2WSH(witnessScript))
sign_witness(witnessScript, i)
+ else if non_witness_utxo.exists:
+ assert(sha256d(non_witness_utxo) == psbt.tx.input[i].prevout.hash)
+ if redeemScript.exists:
+ assert(non_witness_utxo.vout[psbt.tx.input[i].prevout.n].scriptPubKey == P2SH(redeemScript))
+ sign_non_witness(redeemScript, i)
+ else:
+ sign_non_witness(non_witness_utxo.vout[psbt.tx.input[i].prevout.n].scriptPubKey, i)
else:
assert False
@@ -688,6 +914,8 @@ Or, for participants performing fA(psbt) and fB(psbt): Combine(fA(psbt), fB(psbt
The Input Finalizer must only accept a PSBT.
For each input, the Input Finalizer determines if the input has enough data to pass validation. If it does, it must construct the 0x07 Finalized scriptSig and 0x08 Finalized scriptWitness and place them into the input key-value map.
+If scriptSig is empty for an input, 0x07 should remain unset rather than assigned an empty array.
+Likewise, if no scriptWitness exists for an input, 0x08 should remain unset rather than assigned an empty array.
All other data except the UTXO and unknown fields in the input key-value map should be cleared from the PSBT. The UTXO should be kept to allow Transaction Extractors to verify the final network serialized transaction.
===Transaction Extractor===
@@ -710,7 +938,7 @@ A MIME type name will be added to this document once one has been registered.
==Extensibility==
The Partially Signed Transaction format can be extended in the future by adding
-new types for key-value pairs. Backwards compatibilty will still be maintained as those new
+new types for key-value pairs. Backwards compatibility will still be maintained as those new
types will be ignored and passed-through by signers which do not know about them.
===Version Numbers===
@@ -729,6 +957,9 @@ If an updater is updating a PSBT and needs to add a field that is only available
New fields should first be proposed on the bitcoin-dev mailing list.
If a field requires significant description as to its usage, it should be accompanied by a separate BIP.
The field must be added to the field listing tables in the Specification section.
+Although some PSBT version 0 implementations encode types as uint8_t rather than compact size,
+it is still safe to add >0xFD fields to PSBT 0, because these old parsers ignore
+unknown fields, and is prefixed by its length.
===Procedure For New Versions===
diff --git a/bip-0174/build.sh b/bip-0174/build.sh
new file mode 100755
index 0000000000..2de1e56275
--- /dev/null
+++ b/bip-0174/build.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+pdflatex -output-format=pdf coinjoin-workflow.tex && \
+inkscape --with-gui --export-text-to-path \
+ --export-plain-svg=coinjoin-workflow.svg coinjoin-workflow.pdf && \
+pdflatex -output-format=pdf multisig-workflow.tex && \
+inkscape --with-gui --export-text-to-path \
+ --export-plain-svg=multisig-workflow.svg multisig-workflow.pdf && \
+echo '"success"'
diff --git a/bip-0174/coinjoin-workflow.svg b/bip-0174/coinjoin-workflow.svg
index 67a0aadd0d..3b6b952e8f 100644
--- a/bip-0174/coinjoin-workflow.svg
+++ b/bip-0174/coinjoin-workflow.svg
@@ -1,7 +1,54 @@
-
-
diff --git a/bip-0174/coinjoin-workflow.tex b/bip-0174/coinjoin-workflow.tex
index e0516ffeea..a325321ae4 100644
--- a/bip-0174/coinjoin-workflow.tex
+++ b/bip-0174/coinjoin-workflow.tex
@@ -7,7 +7,7 @@
\usepackage{lmodern}
\renewcommand*\familydefault{\sfdefault}
\usepackage{tikz}
-\usetikzlibrary{shapes,arrows}
+\usetikzlibrary{shapes,arrows.meta}
\tikzset{>=latex}
\begin{document}
% \sffamily{}
@@ -22,7 +22,7 @@
rounded corners]
\begin{tikzpicture}[auto]
% outlining the flowchart on a grid
- \matrix[column sep=3ex,row sep=2ex]{
+ \matrix[column sep=3ex,row sep=3ex]{
\node [block_center] (0alice1)
{Alice creates a PSBT with only her inputs
with UTXOs filled in.\\Sends it to Bob.};
@@ -49,7 +49,13 @@
\\
};% end matrix
% connecting nodes with paths
- \draw[line width = 1pt, ->]
+ \draw [ultra thick, draw=black, -{Stealth[length=8pt]}]
+ (0alice1) edge (1bob1)
+ (1bob1) edge (2carol1)
+ (2carol1) edge (3bob2)
+ (3bob2) edge (4alice1)
+ (4alice1) edge (5alice2);
+ \draw [thin, white, -{Stealth[color=black, fill=white, length=8pt]}]
(0alice1) edge (1bob1)
(1bob1) edge (2carol1)
(2carol1) edge (3bob2)
diff --git a/bip-0174/multisig-workflow.svg b/bip-0174/multisig-workflow.svg
index 951b49e80c..2d873b052b 100644
--- a/bip-0174/multisig-workflow.svg
+++ b/bip-0174/multisig-workflow.svg
@@ -1,5 +1,47 @@
-
-
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
@@ -191,277 +233,931 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
@@ -470,397 +1166,1381 @@
-
-
-
-
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -872,23 +2552,173 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bip-0174/multisig-workflow.tex b/bip-0174/multisig-workflow.tex
index 2b8744d32a..d2250cfa6b 100644
--- a/bip-0174/multisig-workflow.tex
+++ b/bip-0174/multisig-workflow.tex
@@ -7,7 +7,7 @@
\usepackage{lmodern}
\renewcommand*\familydefault{\sfdefault}
\usepackage{tikz}
-\usetikzlibrary{shapes,arrows}
+\usetikzlibrary{shapes,arrows.meta}
\tikzset{>=latex}
%\pgfdeclarelayer{bg} % declare background layer
%\pgfsetlayers{bg,main} % set order of layers
@@ -83,7 +83,15 @@
};% end matrix
% connecting nodes with paths
% \begin{pgfonlayer}{bg}
- \draw[line width = 1pt, ->]
+ \draw [ultra thick, draw=black, -{Stealth[length=8pt]}]
+ (R1) edge (R2)
+ (R2) edge (R3)
+ (R3) -| (R4C1)
+ (R3) edge (R4C2)
+ (R5) edge (R6)
+ (R6) edge (R7)
+ (R7) edge (stop);
+ \draw [thin, white, -{Stealth[color=black, fill=white, length=8pt]}]
(R1) edge (R2)
(R2) edge (R3)
(R3) -| (R4C1)
@@ -92,7 +100,12 @@
(R6) edge (R7)
(R7) edge (stop);
% circumvent missing arrow
- \draw[line width = 1pt, ->]
+ \draw [ultra thick, draw=black, -{Stealth[length=8pt]}]
+ (R4C1) |-+(0,-2.2em)-| (R5)
+ (R4C2) edge (R5)
+ (R4C3) |-+(0,-2.2em)-| (R5)
+ (R3) -| (R4C3);
+ \draw [thin, white, -{Stealth[color=black, fill=white, length=8pt]}]
(R4C1) |-+(0,-2.2em)-| (R5)
(R4C2) edge (R5)
(R4C3) |-+(0,-2.2em)-| (R5)
diff --git a/bip-0176.mediawiki b/bip-0176.mediawiki
index 8a49bfa717..bfce9a22cb 100644
--- a/bip-0176.mediawiki
+++ b/bip-0176.mediawiki
@@ -16,7 +16,7 @@ Bits is presented here as the standard term for 100 (one hundred) satoshis or 1/
== Motivation ==
The bitcoin price has grown over the years and once the price is past $10,000 USD or so, bitcoin amounts under $10 USD start having enough decimal places that it's difficult to tell whether the user is off by a factor of 10 or not. Switching the denomination to "bits" makes comprehension easier. For example, when BTC is $15,000 USD, $10.05 is a somewhat confusing 0.00067 BTC, versus 670 bits, which is a lot clearer.
-Additonally, reverse comparisons are easier as 59 bits being $1 is easier to comprehend for most people than 0.000059 BTC being $1. Similar comparisons can be made to other currencies: 1 yen being 0.8 bits, 1 won being 0.07 bits and so on.
+Additionally, reverse comparisons are easier as 59 bits being $1 is easier to comprehend for most people than 0.000059 BTC being $1. Similar comparisons can be made to other currencies: 1 yen being 0.8 bits, 1 won being 0.07 bits and so on.
Potential benefits of utilizing "bits" include:
@@ -28,7 +28,7 @@ Potential benefits of utilizing "bits" include:
== Specification ==
Definition: 1 bit = 100 satoshis.
-Plural of "bit" is "bits". The terms "bit" and "bits" are not proper nouns and thus should not be capitalized unless used at the start of a sentence, etc.
+Plural of "bit" is "bits." The terms "bit" and "bits" are not proper nouns and thus should not be capitalized unless used at the start of a sentence, etc.
All bitcoin-denominated items are encouraged to also show the denomination in bits, either as the default or as an option.
@@ -37,21 +37,21 @@ As bitcoin grows in price versus fiat currencies, it's important to give users t
Existing terms used in bitcoin such as satoshi, milli-bitcoin (mBTC) and bitcoin (BTC) do not conflict as they operate at different orders of magnitude.
-The term micro-bitcoin (µBTC) can continue to exist in tandem with the term "bits".
+The term micro-bitcoin (µBTC) can continue to exist in tandem with the term "bits."
== Backwards Compatibility ==
-Software such as the Bitcoin Core GUI currently use the µBTC denomination and can continue to do so. There is no obligation to switch to "bits".
+Software such as the Bitcoin Core GUI currently use the µBTC denomination and can continue to do so. There is no obligation to switch to "bits."
The term "bit" has many different definitions, but the ones of particular note are these:
-* 1 bit = 1/8 dollar (e.g. That candy cost me 2 bits)
-* bit meaning some amount of data (e.g. The first bit of the version field is 0)
-* bit meaning strength of a cryptographic algorithm (e.g. 256-bit ECDSA is used in Bitcoin)
+* 1 bit = 1/8 dollar (e.g., that candy cost me 2 bits {or 1/4 dollar})
+* bit meaning some amount of data (e.g., the first bit of the version field is 0)
+* bit meaning strength of a cryptographic algorithm (e.g., 256-bit ECDSA is used in Bitcoin)
-The first is a bit dated and isn't likely to confuse people dealing with Bitcoin. The second and third are computer science terms and context should be sufficient to figure out what the user of the word means.
+The first is a bit dated and isn't likely to confuse people dealing with Bitcoin. The second and third are computer science terms and context should be sufficient to figure out what the user of the word means.
== Copyright ==
This BIP is licensed under the BSD 2-clause license.
== Credit ==
-It's hard to ascertain exactly who invented the term "bits", but the term has been around for a while and the author of this BIP does not take any credit for inventing the term.
\ No newline at end of file
+It's hard to ascertain exactly who invented the term "bits," but the term has been around for a while and the author of this BIP does not take any credit for inventing the term.
diff --git a/bip-0177.mediawiki b/bip-0177.mediawiki
new file mode 100644
index 0000000000..43325c4a61
--- /dev/null
+++ b/bip-0177.mediawiki
@@ -0,0 +1,158 @@
+
+ BIP: 177
+ Title: Redefine Bitcoin's Base Unit
+ Author: John Carvalho
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0177
+ Status: Draft
+ Type: Informational
+ Created: 2025-04-23
+ License: CC0-1.0
+
+
+
+==Introduction==
+
+===Abstract===
+
+This BIP proposes redefining the commonly recognized "bitcoin" unit so that the base unit becomes the primary reference unit. Under this proposal, one bitcoin is defined as that indivisible base unit, eliminating the convention of synthetic decimal places. By making the base unit the standard measure, this BIP aims to simplify user comprehension, reduce confusion, and align on-chain values directly with their displayed representation.
+
+===Motivation===
+
+The current convention defines one bitcoin as 100,000,000 base units. This representation requires dealing with eight simulated decimal places, which can be confusing and foster the misconception that bitcoin is inherently decimal-based. In reality, Bitcoin’s ledger represents values as integral base units. The decimal point is merely a human-imposed abstraction.
+
+By redefining the base unit as "one bitcoin," this BIP aligns user perception with the protocol’s true nature. It reduces cognitive overhead, ensures users understand Bitcoin as counting discrete units, and ultimately improves educational clarity and user experience.
+
+===Specification===
+
+'''Redefinition of the Unit:'''
+
+* Internally, the base units remain unchanged.
+* Historically, 1 bitcoin = 100,000,000 base units. Under this proposal, "1 bitcoin" equals one base unit.
+* What was previously referred to as "1 bitcoin" now corresponds to 100 million bitcoins under the new definition.
+
+'''Terminology:'''
+
+* The informal terms "satoshi" or "sat" are deprecated.
+* All references, interfaces, and documentation SHOULD refer to the base unit simply as "bitcoin."
+* The currency code "BTC" is unaffected by these changes, and continues to mean 100,000,000 base units.
+
+'''Display and Formatting:'''
+
+* Applications SHOULD allow users to toggle between the legacy BTC format (1 BTC = 100,000,000 base units) and the new integral format (1 bitcoin = 1 base unit).
+* Use of the ₿ symbol MAY be used to represent base-unit bitcoins but is OPTIONAL.
+
+Example 1:
+
+* Old display: 0.00010000 bitcoin
+* New display: ₿10,000 or 10,000 bitcoins or 0.00010000 BTC
+
+Example 2:
+
+* Old display: 10.23486 bitcoin
+* New display: ₿1,023,486,000 or 1,023,486,000 bitcoins or 10.23486 BTC
+
+Example 3:
+
+* Old display: 0.345 BTC
+* New display: No changes required or ₿34,500,000 or 34,500,000 bitcoins
+
+NOTE: Traditional number display abbreviations, like 2.5M for millions, are also optional.
+
+'''Conversion:'''
+
+* Ledger and consensus rules remain unchanged.
+* BTC as a currency code remains unchanged (1 BTC = 100,000,000 base units)
+* Implementations adopting this standard MUST multiply previously displayed bitcoin amounts by 100,000,000 to determine the new integer representation.
+
+===Rationale===
+
+'''Usability:'''
+Integer-only displays simplify mental arithmetic and reduce potential confusion or user error.
+
+'''Protocol Alignment:'''
+The Bitcoin protocol inherently counts discrete units. Removing the artificial decimal format aligns user perception with Bitcoin’s actual integral design.
+
+'''Educational Clarity:'''
+Presenting integers ensures newcomers do not mistakenly assume that Bitcoin’s nature is decimal-based. It conveys Bitcoin’s true design from the start.
+
+'''Future-Proofing:'''
+Adopting the base unit as the primary measure ensures a consistent standard that can scale smoothly as Bitcoin adoption grows.
+
+'''Perception of Supply:'''
+While the total count of base units is roughly 2.1 quadrillion, this proposal does not alter supply in any way. The change is purely representational. Comparisons can be drawn to other currencies like the Japanese yen or Indonesian rupiah, where high unit counts are standard and not perceived as inflationary.
+
+===Addressing Alternative Approaches===
+
+'''Refuting the "Bits" Proposal'''
+([https://github.com/bitcoin/bips/blob/master/bip-0176.mediawiki BIP 176])
+
+An alternative suggestion (BIP 176) proposes using "bits" to represent one-millionth of a bitcoin (100 satoshis). While this reduces the number of decimal places in certain contexts, it fails to fully address the core issues our BIP aims to solve:
+
+1. '''Persistent Decimal Mindset:'''
+Using "bits" still retains a layered decimal approach, requiring users to think in terms of multiple denominations (BTC and bits). This shifts complexity rather than eliminating it.
+
+2. '''Inconsistent User Experience:'''
+Users must learn to toggle between BTC for large amounts and bits for small amounts. Instead of providing a unified view of value, it fragments the user experience.
+
+3. '''Incomplete Alignment with the Protocol’s Nature:'''
+The "bits" proposal does not realign the displayed value with the integral nature of Bitcoin’s ledger. It continues to rely on fractional units, masking the fundamental integer-based accounting that Bitcoin employs.
+
+4. '''Not Permanently Future-Proof:'''
+Though "bits" may simplify certain price ranges, future circumstances could demand additional denominations or scaling adjustments. Our integral approach resolves this problem entirely by making the base unit the standard measure, avoiding future fragmentation.
+
+In essence, while BIP 176 attempts to simplify small amount representations, it only replaces one decimal representation with another. By redefining "bitcoin" as the base unit, this BIP eliminates reliance on decimal fractions and separate denominations entirely, offering a clearer, more intuitive, and ultimately more durable solution.
+
+===Handling the Terms “satoshi” and “sat”===
+
+'''Background'''
+
+“Satoshi” (or its shorthand “sat”) emerged organically some years ago, to honour Bitcoin’s creator and to give a friendly name to the 100-millionth "fraction" of a bitcoin.
+Over time “stacking sats” became a meme, and the term now appears in podcasts, apparel, and some wallet UIs.
+
+While culturally valuable, the term introduces an implicit second denomination layer that contradicts the goal of this BIP: a single base unit, called simply "bitcoin". Of course this BIP cannot stop anyone from using any colloquial term they prefer, but this document exists to specify how to display Bitcoin's only units as "bitcoin" correctly.
+
+===Backward Compatibility===
+
+No consensus rules are altered, and on-chain data remains unchanged. Differences arise solely in display formats:
+
+* '''For Developers:''' Update GUIs, APIs, and documentation to present values as integers. Remove references to fractional Bitcoin. BTC units remain unchanged.
+
+* '''For Users:''' The actual value of holdings does not change. Transitional measures, such as dual displays or explanatory tooltips, can ease the adjustment period.
+
+===Security Considerations===
+
+A short-term risk of confusion exists as users adapt to the new representation. Users accustomed to decimals may misinterpret initial displays. To mitigate this:
+
+* Offer dual displays and tooltips during the transition.
+* Provide clear educational materials and coordinated messaging.
+* Use alerts or confirmations in applications if input values appear unexpectedly large or small.
+* Highlight the unchanging 21M BTC supply cap and equivalence to avoid misinterpretation as inflationary.
+
+===Reference Implementation===
+
+Some wallets, such as Bitkit, have successfully adopted integer-only displays, demonstrating the feasibility of this approach, without incident. Transitional features — like showing both old and new formats side-by-side — can help smooth the transition.
+
+===Test Vectors===
+
+* Old: 1.00000000 Bitcoin → New: ₿100,000,000 (or 100,000,000 bitcoins)
+* Old: 0.00010000 Bitcoin → New: ₿10,000 (or 10,000 bitcoins)
+* Old: 0.00500000 Bitcoin → New: ₿500,000 (or 500,000 bitcoins)
+* Old: 0.005 BTC → New: 0.005 BTC (or ₿500,000 or 500,000 bitcoins)
+
+All formerly fractional representations now directly correspond to whole-number multiples of the base unit.
+
+===Implementation Timeline===
+
+'''Phase 1 (3-6 months):''' Introduce the concept, provide dual displays and educational materials. Begin pilot testing in willing wallet apps.
+
+'''Phase 2 (6-12 months):''' Prominent services adopt integer-only displays by default. Community coordination and media campaigns ensure consistency.
+
+'''Phase 3 (12+ months):''' Integer representation becomes standard. Documentation and user guides no longer reference decimal-based formats.
+
+===Conclusion===
+
+Redefining "bitcoin" as the smallest indivisible unit, and removing decimal-based representations, simplifies comprehension and aligns displayed values with the protocol’s integral accounting. While a transition period may be necessary, the long-term benefits include clearer communication, reduced confusion, and a more accurate understanding of Bitcoin’s fundamental design.
+
+===Copyright===
+
+This BIP is licensed under CC0-1.0.
diff --git a/bip-0179.mediawiki b/bip-0179.mediawiki
index 7894f2d060..b34e2f6c2d 100644
--- a/bip-0179.mediawiki
+++ b/bip-0179.mediawiki
@@ -2,7 +2,6 @@
BIP: 179
Title: Name for payment recipient identifiers
Author: Emil Engler
- MarcoFalke
Luke Dashjr
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0179
diff --git a/bip-0197.mediawiki b/bip-0197.mediawiki
index 427ff22000..7e5e8e3dc5 100644
--- a/bip-0197.mediawiki
+++ b/bip-0197.mediawiki
@@ -79,7 +79,7 @@ The Seizable Collateral script takes the following form:
==Compatibility==
-BIP 197 is compatible with [ERC 1850](https://github.com/ethereum/EIPs/pull/1850) for [atomic loans](https://arxiv.org/pdf/1901.05117.pdf) with Ethereum. Can be extended in the future to be compatible with other HTLC and smart contract compatible chains.
+BIP 197 is compatible with [https://github.com/ethereum/EIPs/pull/1850 ERC 1850] for [https://arxiv.org/pdf/1901.05117.pdf atomic loans] with Ethereum. Can be extended in the future to be compatible with other HTLC and smart contract compatible chains.
==Motivation==
@@ -148,7 +148,7 @@ As this is a new standard for collateralized debt, there is no need for backward
==Implementation==
-https://github.com/AtomicLoans/chainabstractionlayer/blob/bitcoin-collateral-provider/src/providers/bitcoin/BitcoinCollateralProvider.js
+https://github.com/AtomicLoans/chainabstractionlayer/blob/dev/packages/bitcoin-collateral-provider/lib/BitcoinCollateralProvider.js
==Copyright==
diff --git a/bip-0199.mediawiki b/bip-0199.mediawiki
index e463c7f7bd..9ec541d0f1 100644
--- a/bip-0199.mediawiki
+++ b/bip-0199.mediawiki
@@ -6,7 +6,7 @@
Daira Hopwood
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0199
- Status: Draft
+ Status: Rejected
Type: Standards Track
Created: 2017-03-27
License: BSD-3-Clause
@@ -19,13 +19,13 @@ This BIP describes a script for generalized off-chain contract negotiation.
==Summary==
-A Hashed Time-Locked Contract (HTLC) is a script that permits a designated party (the "seller") to spend funds by disclosing the preimage of a hash. It also permits
+A Hashed Time-Locked Contract (HTLC) is a script that permits a designated party (the "seller") to spend funds by disclosing the preimage of a hash. It also permits
a second party (the "buyer") to spend the funds after a timeout is reached, in a refund situation.
The script takes the following form:
OP_IF
- [HASHOP] OP_EQUALVERIFY OP_DUP OP_HASH160
+ [HASHOP] OP_EQUALVERIFY OP_DUP OP_HASH160
OP_ELSE
[TIMEOUTOP] OP_DROP OP_DUP OP_HASH160
OP_ENDIF
@@ -44,28 +44,28 @@ The script takes the following form:
** Peggy spends the funds, and in doing so, reveals the preimage to Victor in the transaction; OR
** Victor recovers the funds after the timeout threshold.
-Victor is interested in a lower timeout to reduce the amount of time that his funds are encumbered in the event that Peggy does not reveal the preimage. Peggy is
-interested in a higher timeout to reduce the risk that she is unable to spend the funds before the threshold, or worse, that her transaction spending the funds does
+Victor is interested in a lower timeout to reduce the amount of time that his funds are encumbered in the event that Peggy does not reveal the preimage. Peggy is
+interested in a higher timeout to reduce the risk that she is unable to spend the funds before the threshold, or worse, that her transaction spending the funds does
not enter the blockchain before Victor's but does reveal the preimage to Victor anyway.
==Motivation==
-In many off-chain protocols, secret disclosure is used as part of a settlement mechanism. In some others, the secrets themselves are valuable. HTLC transactions are
-a safe and cheap method of exchanging secrets for money over the blockchain, due to the ability to recover funds from an uncooperative counterparty, and the
+In many off-chain protocols, secret disclosure is used as part of a settlement mechanism. In some others, the secrets themselves are valuable. HTLC transactions are
+a safe and cheap method of exchanging secrets for money over the blockchain, due to the ability to recover funds from an uncooperative counterparty, and the
opportunity that the possessor of a secret has to receive the funds before such a refund can occur.
===Lightning network===
In the lightning network, HTLC scripts are used to perform atomic swaps between payment channels.
-Alice constructs K and hashes it to produce L. She sends an HTLC payment to Bob for the preimage of L. Bob sends an HTLC payment to Carol for the same preimage and
-amount. Only when Alice releases the preimage K does any exchange of value occur, and because the secret is divulged for each hop, all parties are compensated. If
+Alice constructs K and hashes it to produce L. She sends an HTLC payment to Bob for the preimage of L. Bob sends an HTLC payment to Carol for the same preimage and
+amount. Only when Alice releases the preimage K does any exchange of value occur, and because the secret is divulged for each hop, all parties are compensated. If
at any point some parties become uncooperative, the process can be aborted via the refund conditions.
===Zero-knowledge contingent payments===
-Various practical zero-knowledge proving systems exist which can be used to guarantee that a hash preimage derives valuable information. As an example, a
-zero-knowledge proof can be used to prove that a hash preimage acts as a decryption key for an encrypted sudoku puzzle solution. (See
+Various practical zero-knowledge proving systems exist which can be used to guarantee that a hash preimage derives valuable information. As an example, a
+zero-knowledge proof can be used to prove that a hash preimage acts as a decryption key for an encrypted sudoku puzzle solution. (See
[https://github.com/zcash/pay-to-sudoku pay-to-sudoku] for a concrete example of such a protocol.)
HTLC transactions can be used to exchange such decryption keys for money without risk, and they do not require large or expensive-to-validate transactions.
diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki
index 08f8994a3f..e09e141237 100644
--- a/bip-0300.mediawiki
+++ b/bip-0300.mediawiki
@@ -15,144 +15,120 @@
==Abstract==
-A "Hashrate Escrow" is a clearer term for the concept of "locked to an SPV Proof", which is itself a restatement of the phrase "within a sidechain" as described in [https://blockstream.com/sidechains.pdf the 2014 Blockstream whitepaper].
+BIP-300 enables a new type of L2, where "withdrawals" (the L2-to-L1 txns) are governed by proof-of-work -- instead of a federation or fixed set of pubkeys.
-A Hashrate Escrow resembles a 2-of-3 multisig escrow, where the 3rd party (who will arbitrate any disputes) is a decentralized group of people: the dynamic-membership set of Bitcoin Miners. However, the 3rd party does not sign escrow-withdrawal transactions with a private key. Instead, these are "signed" by the accumulation of hashpower over time.
+BIP-300 emphasizes slow, transparent, and auditable withdrawals that are easy for honest users to get right and hard for dishonest miners to abuse. The main design goal for BIP-300 is ''partitioning'' -- users can ignore BIP-300 txns if they wish; it makes no difference to L1 if the user validates all, some, or none of them. The second design goal is ''security'' -- users of the L2 should feel confident that, [https://www.drivechain.info/blog/fees/ if the L2 network is paying a lot of fees], then miners will want to keep it around, and the withdrawals will therefore be processed accurately.
-This project has [http://www.drivechain.info/ a website] which includes [http://www.drivechain.info/faq/index.html an FAQ].
+Once BIP-300 has established a "bridge" between L1 and these L2s, users can swap coins in and out instantly, only using BIP-300 for final settlement. This setup allows Bitcoin to process all the transactions in the world, of any shape or size, regardless of blocksize, node software, tech stack, or decentralization level -- all without altering L1 at all.
==Motivation==
-In practice these escrows are likely to be "asymmetric sidechains" of Bitcoin (such as [http://www.rsk.co/ Rootstock]) or "virtual chains" within Bitcoin (such as [https://github.com/blockstack/virtualchain proposed by Blockstack] in mid-2016).
+BIP-300 allows us to achieve [https://www.truthcoin.info/blog/zside-meltcast/ strong privacy], [https://www.truthcoin.info/blog/thunder/ planetary scale], and [https://www.truthcoin.info/blog/all-world-txns/ hundreds of billions of dollars in annual mining revenues], all with a [https://www.drivechain.info/blog/fees/ security model] that is [https://x.com/Truthcoin/status/1701959339508965405 much stronger than] that of the [https://www.truthcoin.info/blog/ln-blackpill/ Lightning Network].
-Sidechains have many potential benefits, including:
+The original motivation stretches back to Reid Hoffman, who [https://blockstream.com/2015/01/13/en-reid-hoffman-on-the-future-of-the-bitcoin-ecosystem/ wrote in 2014]: "Sidechains allow developers to add features and functionality to the Bitcoin universe without actually modifying the Bitcoin Core code...Consequently, innovation can occur faster, in more flexible and distributed ways, without losing the synergies of a common platform with a single currency."
-# Protect Bitcoin from competition from altcoins and spinoffs.
-# Protect Bitcoin from hard fork campaigns. (Such campaigns represent an existential threat to Bitcoin, as well as an avenue for developer corruption.)
-# Help with review, by making it much easier for reviewers to ignore bad ideas.
-# Provide an avenue for good-but-confusing ideas to prove their value safely.
+See [http://www.drivechain.info/ drivechain.info] for more information.
==Specification==
-==== Components ====
+===Overview===
-Hashrate Escrows are built of two types of component: [1] new databases, and [2] new message-interpretations.
+BIP-300 consists of six new blockchain messages:
-===== 1. New Databases =====
+* M1. "Propose New Sidechain"
+* M2. "ACK Proposal"
+* M3. "Propose Bundle"
+* M4. "ACK Bundle"
+* M5. Deposit -- a transfer of BTC from-main-to-side
+* M6. Withdrawal -- a transfer of BTC from-side-to-main
-* D1. "Escrow_DB" -- a database of "accounts" and their attributes.
-* D2. "Withdrawal_DB" -- a database of pending withdrawals from these accounts, and their statuses.
-Please note that these structures (D1 and D2) will not literally exist anywhere in the blockchain. Instead they are constructed from messages...these messages, in contrast, *will* exist in the blockchain (with the exception of M4).
+Nodes organize this data into [https://github.com/LayerTwo-Labs/bip300301_enforcer/blob/13a4353c39a26d9d40180ea361b7580fd682e5b5/src/bip300.rs#L79-L96 a few caches], mainly these two:
-===== 2. New Messages =====
-
-* M1. "Propose New Escrow"
-* M2. "ACK Escrow Proposal"
-* M3. "Propose Withdrawal"
-* M4. (implied) "ACK Withdrawal"
-* M5. "Execute Deposit" -- a transfer of BTC from-main-to-side
-* M6. "Execute Withdrawal" -- a transfer of BTC from-side-to-main
-
-
-
-
-=== Adding Sidechains (D1, M1, M2) ===
-
-==== D1 -- "Escrow_DB" ====
-
-The table below enumerates the new database fields, their size in bytes, and their purpose. In general, an escrow designer (for example, a sidechain-designer), is free to choose any value for these.
+* D1. "The Sidechain List"
+* D2. "The Withdrawal List"
+==== D1 (The Sidechain List) ====
+D1 is a list of active sidechains. D1 is populated via M1 and M2. Fields #9 and #10 are updated via M5 and M6.
{| class="wikitable"
+|- style="font-weight:bold; text-align:center; vertical-align:middle;"
! Field No.
! Label
! Type
! Description / Purpose
-|-
+|- style="vertical-align:middle;"
| 1
| Escrow Number
| uint8_t
-| A number assigned to the entire escrow. Used to make it easy to refer to each escrow.
+| The escrow's ID number. Used to uniquely refer to each sidechain.
|-
| 2
-| Sidechain Deposit Script Hex
-| string
-| The script that will be deposited to, and update the CTIP of the sidechain.
+| Version
+| int32_t
+| Version number.
|-
| 3
-| Sidechain Private Key
+| Sidechain Name
| string
-| The private key of the sidechain deposit script.
-|-
+| A human-readable name of the sidechain.
+|- style="vertical-align:middle;"
| 4
-| Escrow Name
+| Sidechain Description
| string
-| A human-readable name of the sidechain.
-|-
+| A human-readable name description of the sidechain.
+|- style="vertical-align:middle;"
| 5
-| Escrow Description
-| string
-| A human-readable name description of the sidechain. More than enough space to hold a 32 byte hash.
-|-
-| 6
-| Hash ID 1
+| Hash1 - tarball hash
| uint256
-| A field of 32 bytes, which could be any bytes such as a sha256 hash.
+| Intended as the sha256 hash of the tar.gz of the canonical sidechain software. (This is not enforced by BIP-300, and is for human purposes only.)
+|- style="vertical-align:middle;"
+| 6
+| Hash2 - git commit hash
+| uint160
+| Intended as the git commit hash of the canonical sidechain node software. (This is not enforced by BIP-300, and is for human purposes only.)
|-
| 7
-| Hash ID 2
-| uint256
-| A field of 32 bytes, which could be any bytes such as a sha256 hash.
-|-
+| Active
+| bool
+| Does this sidechain slot contain an active sidechain?
+|- style="vertical-align:middle;"
| 8
-| "CTIP" -- Part 1 "TxID"
-| uint256
-| The CTIP, or "Critical (TxID, Index) Pair" is a variable for keeping track of where the escrow's money is (ie, which member of the UTXO set).
-|-
+| Activation Status
+| int , int
+| The age of the proposal (in blocks); and the number of "fails" (a block that does NOT ack the sidechain). This is discarded after the sidechain activates.
+|- style="vertical-align:middle;"
| 9
-| "CTIP" -- Part 2 "Index"
+| "CTIP" -- "TxID"
+| uint256
+| A UTXO that holds the sidechain's money. (Part 1 of 2).
+|- style="vertical-align:middle;"
+| 10
+| "CTIP" -- "vout"
| int32_t
-| Of the CTIP, this is second element of the pair: the Index. See #9 above.
-|-
+| A UTXO that holds the sidechain's money. (Part 2 of 2).
|}
-D1 is updated via M1 and M2.
-
-( The following messages were modeled on SegWit -- see [https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#commitment-structure here] and [https://github.com/DriveNetTESTDRIVE/DriveNet/blob/564516653c1d876429382971a011f5f6119f7eb4/src/validation.cpp#L3348-L3375 here]. )
+==== D2 (The Withdrawal List) ====
-==== M1 -- "Propose New Sidechain" ====
-
- 1-byte - OP_RETURN (0x6a)
- 4-byte - Commitment header (0xD5E0C4AF)
- N-byte - The serialization of the sidechain.
-
-
-==== M2 -- "ACK Sidechain Proposal" ====
-
- 1-byte - OP_RETURN (0x6a)
- 4-byte - Commitment header (0xD6E1C5BF)
- 32-byte - Commitment hash: sha256D hash of sidechain's serialization
-
-==== New Block Validation Rules ====
+Withdrawals are transactions that remove coins "from" L2 (i.e., from the BIP-300 locked UTXO), and place them back on L1. Each BIP-300 withdrawal can pay out up to 6,000 withdrawals, and only one withdrawal can succeed at a time (per L2). Therefore, since all L2 users share the same large withdrawal-event, on L1 we call these withdrawals "bundles".
+D2 is driven by M3, M4, M5, and M6. Those messages enforce the following principles:
-# Escrows are added in a procedure that resembles BIP 9 soft fork activation: the network must see a properly-formatted M1, followed by "acknowledgment" of the sidechain in 95% of the following 2016 blocks.
-# It is possible to "overwrite" an escrow. This requires 6 months (26298 blocks) of M2s, instead of 2 weeks (XXXX). This possibility does not change the security assumptions (because we already assume that users perform extra-protocolic validation at a rate of 1 bit per 26298 blocks).
+# The database has a canonical order (first come first serve).
+# From one block to the next, every "Blocks Remaining" field decreases by 1.
+# When "Blocks Remaining" reaches zero, the bundle is removed.
+# From one block to the next, the value in "ACKs" may either increase or decrease, by a maximum of 1 (see M4).
+# If a bundle's "ACKs" reach 13150 or greater, it "succeeds" and its corresponding M6 message can be included in a block.
+# If the M6 of a bundle is paid out, it is also removed.
+# If a bundle cannot possibly succeed ( 13150 - "ACKs" > "Blocks Remaining" ), it is removed immediately.
-
-=== Withdrawing from Escrows (D2, M3, M4) ===
-
-==== D2 -- "Withdrawal_DB" ====
-
-D2 changes deterministically with respect to M3, M4, M5, and M6.
-
{| class="wikitable"
! Field No.
! Label
@@ -160,147 +136,344 @@ D2 changes deterministically with respect to M3, M4, M5, and M6.
! Description / Purpose
|-
| 1
-| Escrow Number
+| Sidechain Number
| uint8_t
-| Links the withdrawal-request to a specific escrow.
+| Links the withdrawal-request to a specific hashrate escrow.
|-
| 2
-| WT^ Hash
+| Bundle Hash
| uint256
-| This is a "blinded transaction id" (ie, the double-Sha256 of a txn that has had two fields zeroed out, see M6) of a withdrawal-attempt.
+| A withdrawal attempt. Specifically, it is a "blinded transaction id" (i.e., the double-Sha256 of a txn that has had two fields zeroed out, see M6) of a txn which could withdraw funds from a sidechain.
|-
| 3
-| ACKs (Work Score)
+| Work Score (ACKs)
| uint16_t
-| The current total number of ACKs (PoW)
+| How many miner upvotes a withdrawal has. Starts at 0. Fastest possible rate of increase is 1 per block.
|-
| 4
-| Blocks Remaining (Age)
+| Blocks Remaining
| uint16_t
-| The number of blocks which this WT^ has remaining to accumulate ACKs
+| How long this bundle has left to live (measured in blocks). Starts at 26,300 and counts down.
|}
-==== New Block Validation Rules for D2 ====
-# A hash commitment to D2 exists in each block (even if D2 is blank).
-# Withdrawals in D2 are sorted first by field #1 (Escrow Number) and second by field #4 (Age). This imposes a unique sort.
-# From one block to the next, "Age" fields must increase by exactly 1.
-# Withdrawals are stored in D2 until they fail ("Age" = "MaxAge"), or they succeed (the blockchain contains a txn whose blinded txID matches "WT^").
-In addition, there are special rules for the "ACKs" field (see M4 below).
+=== M1 -- Propose Sidechain ===
+
+New sidechains are proposed with M1, and ACKed with M2.
+
+M1 is a coinbase OP Return output containing the following:
+
+ 1-byte - OP_RETURN (0x6a)
+ 4-byte - Message header (0xD5E0C4AF)
+ N-byte - The serialization of the sidechain.
+ 1-byte nSidechain
+ 4-byte nVersion
+ x-byte title
+ x-byte description
+ 32-byte hashID1
+ 20-byte hashID2
+
+
+M1 is invalid if:
+
+* It would add a duplicate entry to D1.
+* There is already an M1 in this block.
+* The sidechain serialization does not parse.
+
+Otherwise:
+
+* A new entry is added to D1, whose initial Activation Status is (age=0, fails=0).
+
+
+=== M2 -- ACK Sidechain Proposal ===
+
+M2 is a coinbase OP Return output containing the following:
+
+ 1-byte - OP_RETURN (0x6a)
+ 4-byte - Message header (0xD6E1C5BF)
+ 32-byte - the sha256D hash of sidechain's serialization
+
+
+M2 is ignored if it doesn't parse, or if it is for a sidechain that doesn't exist.
+
+M2 is invalid if:
+
+* An M2 is already in this block.
+* It tries to ACK two different M1s for the same slot.
+
+Otherwise:
+
+* The sidechain is "ACK"ed and does NOT get a "fail" for this block. (As it otherwise would.)
+
+A sidechain fails to activate if:
+
+* If the slot is unused: during the next 2016 blocks, it accumulates 1008 fails (i.e., 50% hashrate threshold).
+* If the slot is in use: during the next 26,300 blocks, it accumulates 13,150 fails (i.e., 50% hashrate threshold).
+
+( Thus we can overwrite a used sidechain slot. BIP-300 sidechains are already vulnerable to one catastrophe per 13150 blocks (the invalid withdrawal), so this slot-overwrite option does not change the security assumptions. )
+
+Otherwise, the sidechain activates (Active is set to TRUE).
+
+
+=== Withdrawing in Bundles ===
-==== M3 -- "Propose Withdrawal" ====
+Sidechain withdrawals take the form of "bundles" -- named because they "bundle up" many individual withdrawal-requests into a single rare L1 transaction.
+
+On the L2 side, individual withdrawal requests are periodically combined into a single CoinJoin-like withdrawal bundle. This bundle is hashed [https://github.com/LayerTwo-Labs/bip300301_messages/blob/398b224981c7c236c8354704e655996d33685149/src/lib.rs#L374C1-L419C2 in a particular way] (on both L2 and L1) -- this "blinded hash" commits to its own L1 fee, but (notably) it does not commit to its first tx-input (in that way, it is like [https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki BIP-118]).
+
+This hash is what L1 miners will slowly ACK over 3-6 months, not the M6 itself (nor any sidechain data, of course).
+
+A bundle will either pay all its withdrawals out (via M6), or fail (and pay nothing out for anyone).
+
+
+=== M3 -- Propose Bundle ===
+
+M3 is a coinbase OP Return output containing the following:
1-byte - OP_RETURN (0x6a)
- 1-byte - Push the following 36 bytes (0x24)
4-byte - Commitment header (0xD45AA943)
- 32-byte - The WT^ hash to populate a new D2 entry
+ 32-byte - The bundle hash, to populate a new D2 entry
+ 1-byte - nSidechain (the slot number)
+M3 is ignored if it does not parse, or if it is for a sidechain that doesn't exist.
-==== New Block Validation Rules for M3 ====
+M3 is invalid if:
-# If the network detects a properly-formatted M3, it must add an entry to D2 in the very next block. The starting values of fields #3 and #4 are zero, and #5 is pulled over by extracting the relevant value from D1.
-# Each block can only contain one M3 per sidechain.
+* This block already has an M3 for that nSidechain.
+* A bundle with this hash is already in D2.
+* A bundle with this hash already paid out.
+* A bundle with this hash was rejected in the past.
+Otherwise: M3 adds an entry to D2, with initial ACK score = 1 and initial Blocks Remaining = 26,299. (Merely being added to D2, does count as your first upvote.)
-==== M4 -- "ACK Withdrawal" ====
-M4 is a way of describing changes to the "ACKs" column of D2.
+=== M4 -- ACK Bundle(s) ===
-From one block to the next, "ACKs" can only change as follows:
+Once a bundle is in D2, how can we give it enough ACKs to make it valid?
-* The ACK-counter of any withdrawal can only change by (-1,0,+1).
-* Within a sidechain-group, upvoting one withdrawal ("+1") requires you to downvote all other withdrawals in that group. However, the minimum ACK-value is zero (and, therefore, downvotes cannot reduce it below zero).
-* While only one withdrawal can be upvoted at once, they can all be unchanged at once ("abstain") and they can all be downvoted at once ("alarm").
+M4 is a coinbase OP Return output containing the following:
-One option for explicit transmission of M4 is:
+ 1-byte - OP_RETURN (0x6a)
+ 4-byte - Commitment header (0xD77D1776)
+ 1-byte - Version
+ n-byte - The "upvote vector" -- describes which bundle-choice is "upvoted", for each sidechain.
- 4-byte - Message identifier (0x????????)
- 1-byte - Version of this message
- 1-byte - Length (in bytes) of this message; total number of withdrawal attempts; y = ceiling( sum_i(m_i +2)/8 ). Nodes should already know what length to expect, because they know the sequence of M3s and therefore the vector of WT^s.
- N-byte - stream of bits (not bytes), with a 1 indicating the position of the chosen action [downvote all, abstain, upvote1, upvote2, ...]
+The M4 message will be invalid (and invalidate the block), if:
-But sometimes M4 does not need to be transmitted at all! If there are n Escrows and m Withdrawals-per-escrow, then there are (m+2)^n total candidates for the next D2. So, when m and n are low, all of the possible D2s can be trivially computed in advance.
+* It tries to upvote a bundle that doesn't exist. (For example, trying to upvote the 7th bundle on sidechain #2, when sidechain #2 has only three bundles.)
+* There are no bundles at all, from any sidechain.
-Miners can impose a "soft limit" on m, blocking new withdrawal-attempts until previous ones expire. For a worst-case scenario of n=200 and m=1,000, honest nodes can communicate M4 with ~25 KB per block [4+1+1+(200\*(1000+1+1)/8)].
+If M4 is NOT present in a block, then it is treated as an "abstain" for all sidechains.
+If M4 is present and valid: each withdrawal-bundle that is ACKed, will gain one upvote.
-=== Depositing and Withdrawing (M5, M6) ===
+Each sidechain always has two "virtual bundles" -- an "abstain" bundle (0xFF), and an "alarm" bundle (0xFE). Abstain leaves the ACK count unchanged, and alarm reduces all ACK counts of all bundles by 1.
-Both M5 and M6 are regular Bitcoin txns. They are identified by meeting an important criteria: they select a one of the Critical TxID-index Pairs (a "CTIP") as one of their inputs.
+Any bundle which fails to receive a vote, is downvoted (and loses 1 ACK). If a sidechain has no pending bundles, then it is skipped over when M4 is created and parsed.
-Just as these txns must select a CTIP input, they must create a new CTIP output. D1 is then updated to match only the latest CTIP output. The purpose of this is to have all of the escrow's money (ie all of the sidechain's money) in one TxID, so that depositors immediately undo any UTXO bloat they may cause.
-Deposits ("M5") are distinguished from withdrawals ("M6") by simply checking to see if money is "going in", or "out".
+==== Examples ====
-https://github.com/DriveNetTESTDRIVE/DriveNet/blob/564516653c1d876429382971a011f5f6119f7eb4/src/validation.cpp#L647-L742
+To upvote the 7th bundle on sidechain #1, and upvote the 4th bundle on sidechain #2, the upvote vector would be { 07, 04 }. And M4 would be [0x6A,D77D1776,00,0006,0003].
+If block 900,000 has D2 of...
-==== M5. "Make a Deposit" -- a transfer of BTC from-main-to-side ====
+{| class="wikitable"
+|-
+! SC#
+! Bundle Hash
+! ACKs
+! Blocks Remaining
+|-
+| 1
+| h1
+| 45
+| 22,109
+|-
+| 1
+| h2
+| 12
+| 22,008
+|-
+| 2
+| h3
+| 13
+| 22,999
+|-
+| 2
+| h4
+| 8
+| 23,550
+|-
+| 2
+| h5
+| 2
+| 22,560
+|}
-As far as mainchain consensus is concerned, deposits to the escrow are always valid.
-However, in practice there will be additional requirements. The escrow account (ie the "sidechain") needs to know how to credit depositors. One well-known method, is for mainchain depositors to append a zero-value OP Return to a Deposit txn, so that the sidechain knows how to credit funds. Mainchain users must upgrade their wallet software, of course, (on an individual basis) in order to become aware of and take advantage of new deposit-methods.
+...and then D2 wants to become:
+{| class="wikitable"
+|-
+! SC#
+! Bundle Hash
+! ACKs
+! Blocks Remaining
+|-
+| 1
+| h1
+| 46
+| 22,108
+|-
+| 1
+| h2
+| 11
+| 22,007
+|-
+| 2
+| h3
+| 12
+| 22,998
+|-
+| 2
+| h4
+| 9
+| 23,549
+|-
+| 2
+| h5
+| 1
+| 22,559
+|}
-==== M6. "Execute Withdrawal" -- a transfer of BTC from-side-to-main ====
+... then M4 would have been [0x6A,D77D1776,00,0000,0001].
-We come, finally, to the critical matter: where users can take their money *out* of the escrow account, and return it to the "regular" UTXO set. As previously mentioned, this txn is one which (a) spends from a CTIP and (b) reduces the quantity of BTC in an account's CTIP. Most of the work has already been done by D1, M3, M4, and D2. Furthermore, existing Bitcoin tx-rules prevent the sidechain from ever withdrawing more money than has been placed into it.
+==== Saving Space ====
-In each block, a withdrawal in D2 is considered "approved" if its "ACKs" value meets the threshold (13,150).
+The version number allows us to shrink the upvote vector in many cases.
+Version 0x00 omits the upvote vector entirely (i.e., 6 bytes for the whole M4) and sets this block's M4 equal to the previous block's M4.
+Version 0x01 uses 1 byte per sidechain, and can be used while all ACKed withdrawals have an index <256 (i.e., 99.99%+ of the time).
+Version 0x02 uses 2 bytes per sidechain, but it always works, even in astronomically unlikely cases (such as when >1 sidechains have >256 bundle candidates).
+Version 0x03 omits the upvote vector, and instead upvotes only those withdrawals that are leading their rivals by at least 50 votes.
-Approved withdrawals give the green light to their respective "WT^". A "WT^" is 32-bytes which aspire to represent the withdrawing transaction (the txn that actually withdraws funds from the escrow). The two cannot match exactly, because "WT^" is defined at onset, and the withdrawing TxID depends on the its CTIP input (which is constantly changing).
+For example, an upvote vector of { 2 , N/A, 1 } would be represented as [0x6A,D77D1776,01,01,00]. It means: "upvote the second bundle in sidechain #1; and the first bundle in sidechain #3" (iff sidechains #2 has no bundles proposed).
-To solve this, we define a "blinded TxID" as a way of hashing a txn, in which some bytes are first overwritten with zeros. Specifically, these bytes are the first input and the first output.
+An upvote vector of { N/A, N/A, 4 } would be [0x6A,D77D1776,01,03].
-So, withdrawals must meet the following three criteria:
-# "Be ACKed" -- The "blinded TxID" of this txn must be member of the "approved candidate" set in the D2 of this block.
-# "Return Change to Account" -- TxOut0 must pay to the "critical account" (see D1) that corresponds to the CTIP that was selected as a TxIn.
-# "Return *all* Change to Account" -- Sum of inputs must equal the sum of outputs. No traditional tx fee is possible.
+=== M5 -- Deposit BTC (from L1 to L2) ===
+Finally, we describe Deposits (M5) and Withdrawals (M6). These are not coinbase outputs, they are txns on L1.
+We call a transaction "M5" if it spends from the escrow output and '''increases''' the quantity of coins. Conversely, we call a transaction "M6" if it spends from the escrow output and '''decreases''' the quantity of coins. See [https://github.com/LayerTwo-Labs/bip300301_enforcer/blob/13a4353c39a26d9d40180ea361b7580fd682e5b5/src/bip300.rs#L462C1-L462C47 here].
+Every time a deposit/withdrawal is made, the old UTXO is spent and a single new UTXO is created. (Deposits/Withdrawals never cause UTXO bloat.) At all times, the specific treasury UTXO ("CTIP") of each sidechain is cached in D1 (above).
-==Backward compatibility==
+Every M5 is valid, as long as:
+* It has exactly one OP_DRIVECHAIN output -- this becomes the new CTIP.
+* The new CTIP has '''more''' coins in it, than before.
-As a soft fork, older software will continue to operate without modification. Non-upgraded nodes will see a number of phenomena that they don't understand -- coinbase txns with non-txn data, value accumulating in anyone-can-spend UTXOs for months at a time, and then random amounts leaving the UTXO in single, infrequent bursts. However, these phenomena don't affect them, or the validity of the money that they receive.
-( As a nice bonus, note that the sidechains themselves inherit a resistance to hard forks. The only way to guarantee that the WT^s reported by different clients will continue to match identically, is to upgrade sidechains via soft forks of themselves. )
+=== M6 -- Withdraw BTC (from L2 to L1) ===
-==Deployment==
+M6 is invalid if:
+* The blinded hash of M6 does NOT match one of the approved bundle-hashes. (In other words: M6 must first be approved by 13,150 upvotes.)
+* The first output of M6 is NOT an OP_DRIVECHAIN. (This OP_DRIVECHAIN becomes the new CTIP. In other words: all non-withdrawn coins are paid back to the sidechain.)
+* The second output is NOT a zero-value OP_RETURN script of exactly 10 bytes, of which 8 bytes are a serialized Bitcoin amount.
+* The txn fee of M6 is NOT exactly equal to the amount of the previous bullet point.
+* There are additional OP_DRIVECHAIN outputs after the first one.
-This BIP will be deployed by "version bits" BIP9 with the name "hrescrow" and using bit 4.
+Else, M6 is valid -- and the funds are withdrawn.
-
-// Deployment of Drivechains (BIPX, BIPY)
-consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].bit = 4;
-consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].nStartTime = 1579072881; // January 15th, 2020.
-consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].nTimeout = 1610695281; // January 15th, 2021.
-
+(The point of the latter two bullet points, is to allow the bundle hash to cover the L1 transaction fee.)
-==Reference Implementation==
+===OP_DRIVECHAIN===
+
+This proposal adds a single new opcode, OP_DRIVECHAIN, which has strict semantics for usage.
+OP_NOP5 (0xb4) is redefined as OP_DRIVECHAIN if and only if the entire script is OP_DRIVECHAIN followed by a single-byte push and OP_TRUE (exactly 4 bytes).
+The single-byte push contains the sidechain number.
+Note that this is not a "script number", and cannot be OP_1..OP_16 or any other kind of push; it is also unsigned, and must not be padded even if over sidechain number 127.
+The final OP_TRUE is to ensure this change remains a softfork:
+without it, sidechain numbers 0 and 128 would cause the legacy script interpreter to fail.
+
+If an OP_DRIVECHAIN input is spent, the additional rules for M5 or M6 (see above) must be enforced.
+
+
-See: https://github.com/DriveNetTESTDRIVE/DriveNet
-Also, for interest, see an example sidechain here: https://github.com/drivechain-project/bitcoin/tree/sidechainBMM
-==References==
+==Backward compatibility==
+
+This soft fork can be deployed without modifying Bitcoin Core at all (i.e., via [https://bip300cusf.com/ CUSF]).
+
+
+==Deployment==
+
+This BIP deploys when/if >51% hashrate runs [https://github.com/LayerTwo-Labs/bip300301_enforcer/ the enforcer client].
-See http://www.drivechain.info/literature/index.html
+Ideally, a critical mass of users would also run the enforcer client -- this would strongly dissuade miners from ever de-activating it.
-==Credits==
+==Reference Implementation==
+
+The enforcer is [https://github.com/LayerTwo-Labs/bip300301_enforcer/ here].
-Thanks to everyone who contributed to the discussion, especially: ZmnSCPxj, Adam Back, Peter Todd, Dan Anderson, Sergio Demian Lerner, Chris Stewart, Matt Corallo, Sjors Provoost, Tier Nolan, Erik Aronesty, Jason Dreyzehner, Joe Miyamoto, Ben Goldhaber.
+Also, several example L2s are [https://releases.drivechain.info/ here].
==Copyright==
diff --git a/bip-0300/appendix-1.txt b/bip-0300/appendix-1.txt
deleted file mode 100644
index 736a6c48a9..0000000000
--- a/bip-0300/appendix-1.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-
-==== Two Withdrawals at Once ====
-
-Currently, the documentation and code describe a situation where only one withdrawal can proceed at a time. As a result, one "train" (carrying everyone's withdrawals) leaves the station every 3 months, and takes 3-6 months to reach its destination.
-
-Thus, if a withdrawing-user is very unlucky, and "just misses" the train, this user must wait double-long. First, (s)he must wait for the missed-train to reach its destination. Second, (s)he must board the new train, and wait for *it* to reach its destination. Each of these steps takes 3-6 months.
-
-So, even when withdrawals always go as quickly as possible (3 months each), the total time varies, from 3 months (0 months waiting + 3 months travel) to 6 months (3 months waiting + 3 months travel). The average is 4.5 months.
-
-To improve this, we allow for slightly different behavior if the highest-ACK-withdrawal [1st] has an ACK score >= 6575; and [2nd] is not tied with any other withdrawal.
-
-Basically: a second train can leave, if the furthest train is 50+% of the way to its destination.
-
-So, previously, for m trains, M4 could be any of the following:
-
- abstain
- alarm (move all trains backwards)
- move train #1 forward (and others backwards)
- move train #2 forward (and others backwards)
- ...
- move train #3 forward (and others backwards)
-
-If our new special conditions apply, we now double the (m-1) elements, to accommodate a second train:
-
- |abstain
- |alarm (move all trains backwards)
-
- |advance furthest train + advance train #1 (regress all others)
- |advance furthest train + advance train #2 (regress all others)
- |...
- |advance furthest train + advance train #(m-1) (regress all others)
-
- |regress furthest train + advance train #1 (regress all others)
- |regress furthest train + advance train #2 (regress all others)
- |...
- |regress furthest train + advance train #(m-1) (regress all others)
-
-
-It is theoretically possible (but in practice probably impossible) to troll this rule, by getting two (or even three) withdrawals to have >6575 ACK scores, and then getting these to *tie* for first place. Then they'd both be furthest. Hence the second condition prohibiting this new behavior, if the furthest trains have any ACK-score ties.
-
-This simple change, which has almost zero impact on the security assumptions, improves the monthly total wait times drastically:
-
- Worst-case: 6 --> 4.5
- Average: 4.5 --> 3.75
- Std Dev: ~.91 --> ~.45
diff --git a/bip-0300/m1-cli.png b/bip-0300/m1-cli.png
new file mode 100644
index 0000000000..3361b28ae0
Binary files /dev/null and b/bip-0300/m1-cli.png differ
diff --git a/bip-0300/m1-gui.jpg b/bip-0300/m1-gui.jpg
new file mode 100644
index 0000000000..2b05556cf1
Binary files /dev/null and b/bip-0300/m1-gui.jpg differ
diff --git a/bip-0300/two-groups.png b/bip-0300/two-groups.png
deleted file mode 100644
index c8a3ffabbd..0000000000
Binary files a/bip-0300/two-groups.png and /dev/null differ
diff --git a/bip-0301.mediawiki b/bip-0301.mediawiki
index d6056f212a..70f1dd018a 100644
--- a/bip-0301.mediawiki
+++ b/bip-0301.mediawiki
@@ -12,213 +12,145 @@
License: BSD-2-Clause
-==Abstract==
-
-Blind Merged Mining (BMM) is a way of mining optional extension blocks (ie, "asymmetric sidechains"). BMM produces weak guarantees that the block is valid, for *any* arbitrary set of rules; and yet it does so without requiring miners to actually do any validation on the block whatsoever.
+==Abstract==
-BMM actually is a process that spans two or more chains. Here we focus on the modifications to mainchain Bitcoin. For an explanation of the "whole picture", please see [http://www.truthcoin.info/blog/blind-merged-mining/ this post].
+Blind Merged Mining (BMM) allows SHA-256d miners to collect transaction fee revenue from other blockchains, without running any new software (i.e., without "looking" at those alt-chains, hence "blind").
-Our goal here, is to allow mainchain miners to trustlessly "sell" the act of finding a sidechain block.
+Instead, this block-assembly work is done by alt-chain users. They choose the alt-chain block, and what txns go in it, the fees etc. Simultaneously, these users "bid" on L1 to win the right to be the sole creator of the alt-chain block. BIP-301 ensures that L1 miners only accept one bid (per 10 minutes, per L2 category), instead of taking all of them (which is what they would ordinarily do).
==Motivation==
-Regular "Merged-Mining" (MM) allows miners to reuse their hashing work to secure other chains (for example, as in Namecoin). However, traditional MM has two drawbacks:
-
-# Miners must run a full node of the other chain. (This is because [while miners can effortlessly create the block] miners will not create a valid payment to themselves, unless the block that they MM is a valid one. Therefore, miners must assemble a *valid* block first, then MM it.)
-# Miners are paid on the other chain, not on the regular BTC mainchain. For example, miners who MM Namecoin will earn NMC (and they will need to sell the NMC for BTC, before selling the BTC in order to pay for electricity).
-
-BMM addresses both shortcomings.
-
-
-==Specification==
-
-Note: This document uses the notation side:\* and main:\* in front of otherwise-ambiguous words (such as "block", "node", or "chain"), to distinguish the mainchain version from its sidechain counterpart. We also use "Simon" to refer to a Sidechain Full Node, and "Mary" to refer to a mainchain miner.
-
-
-=== BMM Request ===
-
-To buy the right to find a sidechain block, users broadcast BMM Requests.
-
-Here, these can take two forms. The first does not require the Lightning Network, but it does have new requirements for Immediate Expiration (see below). The second inherits Immediate Expiration from the Lightning Network itself, but requires extra preparation and a different/larger message.
-
-Both forms require that certain Critical Data will be committed to within the coinbase of the block that the transaction is included in (see BMM Accept). For the OnChain (non-Lightning) version, we have created a new extended serialization transaction type (very similar to how SegWit handles witness data (the witness stack)).
-
-==== Immediate Expiration ("Fill-or-Kill") ====
-
-We would like to make special guarantees to the counterparties of this transaction. Specifically, instead of Simon making a "payment" to Mary, we prefer that Simon give Mary an "offer" (which she can either accept or decline).
-
-Crucially, we want Simon to safely make many offers to several different Mary's, in realtime (ie, quickly and off-chain). However, we ultimately want only one offer to be accepted, at most. In other words, we want Simon's offers to *immediately expire*. If only one offer can become a bona fide transaction, then Simon will feel comfortable making multiple offers all day long. Because all of the Simons are making many offers, the Marys collectively gain access to a large set of offers to choose from.
+"Merged-Mining" (MM) allows miners to reuse their hashing work to secure other chains (for example, as in Namecoin).
-==== OnChain BMM Request ====
+However, traditional MM has two drawbacks:
-OnChain BMMRs do not require the Lightning network, but they do have new requirements for validation.
+# Miners must run a full node of the other chain(s). (Thus, they must run "non-Bitcoin" software which may be buggy.)
+# Miners are paid on the other chain, in Alt-currency. (Miners who MM Namecoin, will earn NMC.)
-===== Structure =====
-The following data is required:
+==Notation and Example==
-
-
-sideHeaderHash comes from side:chain (side:nodes build side:blocks/headers). The identifying bytes are given here. nSidechain identifies which sidechain we are BMMing. By the time Blind Merged Mining can take place, it is known globally.
+We use notation side:\* and main:\* in front of otherwise ambiguous words (such as "block", "node", or "chain"), to distinguish the mainchain version from its sidechain/alt-chain counterpart. We name all sidechain users "Simon", and name all mainchain miners "Mary".
-prevBlockRef, is a little more complicated (next section).
+Furthermore, here is an example of BIP-301 in use. Imagine that a side:block contains 20,000 txns, each paying a $0.10 fee; therefore, the side:block is worth $2000 of fee revenue. In BIP-301, the sidechain's coinbase txn will pay this $2000 to "Simon". Simon does no hashing, but instead makes one L1 txn paying $1999 to the L1 miners ("Mary"). Thus, Mary ends up with all of the fee revenue, even though she didn't do anything on the sidechain.
-To qualify for inclusion in a block, BMM requests are subject to the following requirements:
-# Requests must match a corresponding "BMM Accept" (see last section of BIP).
-# At most, only one Request is allowed in a main:block, per sidechain. In other words, if 700 users broadcast BMM Requests for sidechain #4, then the main:miner must choose one single Request to include.
-# The 4-bytes of prevMainHeaderBytes must match the last four bytes of the previous main:blockheader. Thus, Simon's txns are only be valid for the current block, in the block history that he knows about (and therefore, the current sidechain history that he knows about).
+{| class="wikitable"
+|-
+! colspan="3" | Upon finding a sidechain block worth $2000...
+|- style="font-weight:bold; text-decoration:underline;"
+| Item
+| Layer1 Miner ("Mary")
+| Sidechain User ("Simon")
+|-
+| Runs a sidechain node?
+| No
+| Yes
+|-
+| How much hashing?
+| 100%
+| 0%
+|-
+| Coins collected, on Layer2
+| $0
+| $2000
+|-
+| Coins paid out, on Layer1
+| $0
+| $1999
+|-
+| Coins rec'd, on Layer1
+| $1999
+| $0
+|-
+| d(Net Worth)
+| +$1999
+| +$1
+|}
-===== prevBlockRef =====
-prevBlockRef is an integer that counts the number of "skips" one must take in the side:chain in order to find the current side:block's parent block. This value is zero unless the sidechain is reorganizing (or skipping over invalid sidechain blocks). If a side:node wants to orphan the most-recent N blocks, the value of the current block will be equal to N; in the block after that it will be back to zero.
+BIP-301 makes this specialization-of-labor trustless on L1. If Mary takes Simon's money, then she must let Simon control the side:block.
-
-Above: Three blockchains, with different max length (small number), reorganization histories, and prevBlockRef numbers (larger numbers beneath blocks). The ordering given via each side:block's "prevSideBlockRef" will be isomorphic to an ordering given by each side:block's "prevSideHeaderHash" ("prevSideHeaderHash is the sidechain's equivalent of the mainchain's "prevBlockHash"). One can freely convert from one to the other.
-===== Extended Serialization =====
-
-To impose new requirements at the transaction level, we borrow the dummy vin & "flag" trick from SegWit style transactions. Unless all of the requirements for sidechain critical data transactions are met by the block it is included in, the transaction is invalid. With SegWit, this extra data is the SegWit signature stack, and the extra requirements are the signatures' locations and validity. In the sidechain BMM critical data transactions, the extra data is the (nSidechain, h\*) pair, which must meet the first two requirements (above) as well as the main:blocknumber, which must meet the third requirement (above).
+==Specification==
-
+Each candidate for next side:block is defined by its unique side:blockhash "h*". (Even if the entire rest of the L2 block is identical, different Simons will have different side:coinbases and therefore different h*.)
-Above: A chart showing normal txns, SegWit txns, and CriticalData txns. The specific SegWit txn can be seen [http://srv1.yogh.io/#tx:id:D4A99AE93DF6EE3D4E42CE69338DFC1D06CCD9B198666E98FF0588057378D3D9 here].
+BIP-301 consists of two messages: "BMM Accept" and "BMM Request".
-These types of transactions have slightly different mempool behavior, and should probably be kept in a second mempool. These txns are received, checked immediately, and if valid they are evaluated for inclusion in a block. If they are not able to be included in the specific requested block (if the block height requested has been surpassed by the chain tip), they are discarded. In fact, after any main:block is found, everything in this "second mempool" can be discarded as new payments will be created immediately for the next block height. (This includes cases where the blockchain reorganizes.) There is no re-evaluation of the txns in this mempool ever -- they are evaluated once and then either included or discarded. They never need to be rescanned.
+# "BMM Accept" -- A coinbase output in L1, which contains h*. Mary can only choose one h* to endorse.
+# "BMM Request" -- A transaction where Simon offers to pay Mary, if (and only if) Mary's L1 block contains Simon's h*.
-Interestingly, these payments will *always* be directed to main:miners from non-main:miners. Therefore, non-mining full nodes do not need to keep them in any mempool at all. Non-miner nodes can just wait for a block to be found, and check the txn then. These transactions more resemble a stock market's pit trade-offers (in contrast, regular Bitcoin txns are more like paper checks).
+As a miner, Mary controls the main:coinbase, so she may select any h*. Her selection determines which side:block is "found" -- and which associated BMM Request she can collect.
-==== Lightning BMM Request ====
-Lightning BMMRs require Simons to have a LN-channel pathways open with Marys. This may not always be practical (or even possible), especially today.
+=== BMM Accept ===
-LN txns cannot make use of prevSideBlockRef, as no one knows for sure when (or if) they will be broadcast on-chain. Instead, they must use prevSideBlockHash. But they otherwise require the same data:
+To "Accept" a BMM proposal (endorsing Simon's side:block, and allowing Mary to accept Simon's money later in the block), Mary places an OP_RETURN output into the main:coinbase as follows:
-
-Notice that, in OnChain BMMRs, Simon could reuse the same h\* all he wanted, because only one OnChain BMMR could be included per main:block per sidechain. However, on the LN no such rule can be enforced, as the goal is to push everything off-chain and include *zero* txns. So, we will never know what the Requests were, or how many had an effect on anything.
-
-Therefore, Simon will need to ensure that he '''gives each Mary a different h\*'''. Simon can easily do this, as he controls the side:block's contents and can simply increment a side:nonce -- this changes the side:block, and changes its hash (ie, changes h\*).
-
-With a unique h\* per Mary (or, more precisely, per channel), and at most 1 h\* making it into a block (per sidechain), Simon can ensure that he is charged, at most, one time.
+[https://github.com/LayerTwo-Labs/bip300301_messages/blob/dd26518ff9505ea9088436797171799f359d0076/src/lib.rs#L256-L268 Code details here].
-That's probably confusing, so here is an example, in which: Simon starts with 13 BTC, Mary starts with 40 BTC, the side:block's tx-fees currently total 7.1 BTC, and Simon is keeping 0.1 BTC for himself and paying 7 BTC to Mary.
-
-We start with (I):
-
-
- Simon 13 in, Mary 40 in ; 53 in total
- Simon's version [signed by Mary]
- 13 ; to Simon if TimeLock=over; OR to Mary if SimonSig
- 40 ; to Mary
- Mary's version [signed by Simon]
- 40 ; to me if TimeLock=over; OR to Simon if MarySig
- 13 ; to Simon
-
+If these OP_RETURN outputs are not present, then no Requests were accepted. (And, Mary would get no money from Requests.)
+It is possible for Mary and Simon to be the same person. They would trust each other completely, so the BMM process would stop here. There would only be Accepts; Requests would be unnecessary.
-And both parties move, from there to (II):
+When Simon and Mary are different people, Simon will need to use BMM Requests.
-
- Simon 13 in, Mary 40 in ; 53 in total
- Simon's version [signed by Mary]
- 6 ; to Simon if TimeLock=over; OR to Mary if SimonSig
- 40 ; to Mary
- 7 ; to Mary if critical data requirements met; OR to Simon if LongTimeLock=over
- Mary's version [signed by Simon]
- 40 ; to Mary if TimeLock=over; OR to Simon if MarySig
- 6 ; to Simon
- 7 ; to Mary if critical data requirements met; OR to Simon if LongTimeLock=over
-
+=== BMM Request ===
+Simon will use BMM Requests to buy the "right" to find a sidechain block, from Mary.
-From here, if the h\* side:block in question is BMMed, they can proceed to (III):
+For each side:block that Simon wants to attempt, he broadcasts a txn containing the following as an OP_RETURN:
- Simon 13 in, Mary 40 in ; 53 in total
- Simon's version [signed by Mary]
- 6 ; to Simon if TimeLock=over; OR to Mary if SimonSig
- 47 ; to Mary
- Mary's version [signed by Simon]
- 47 ; to me if TimeLock=over; OR to Simon if MarySig
- 6 ; to Simon
+ 1-byte - OP_RETURN (0x6a)
+ 3-bytes - Message header (0x00bf00)
+ 1-byte - Sidechain number (0-255)
+ 32-bytes - h* (obtained from L2 node)
+ 32-bytes - prevMainBlock (the blockhash of the previous main:block)
-If Simon proceeds immediately, he removes Mary's incentive to care about blocks being built on this side:block. If Simon's side:block is orphaned, he loses his 7 BTC. Simon can either play it safe, and wait for (for example) 100 side:blocks before moving on (ie, before moving on to the third LN txn, above); or else Simon can take the risk if he feels comfortable with it.
-
-If the h\* side:block is not found, then (II) and (III) are basically equivalent to each other. Simon and Mary could jointly reconstruct (I) and go back there, or they could proceed to a new version of II (with a different h\*, trying again with new side:block in the next main:block).
+h* is chosen by Simon to correspond to the side:block he wants to mine on the alt-chain. nSidechain is the number assigned to the sidechain/alt-chain when it was created.
-Now that we have described Requests, we can describe how they are accepted.
+This txn is invalid if it fails any of the following checks:
-=== BMM Accept ===
+# Each "BMM Request", must match one corresponding "BMM Accept" (previous section).
+# Only one BMM Request is allowed in each main:block, per nSidechain. In other words, if 700 users broadcast BMM Requests for sidechain #4, then the main:miner must single out one BMM_Request_4 to include in this L1 block.
+# The 32-bytes of prevMainBlock must match the previous main:blockhash. Thus, Simon's txns are only valid for the current block, in the block history that he knows about.
-For each BMM Request that a main:miner "accepts", main:miners must place an OP Return output into their main:coinbase txn. (We've changed the tx-standardness policy to allow multiple OP_RETURNs.)
-The following data is required in the "accept" OP_RETURN output:
- 1-byte - OP_RETURN (0x6a)
- 1-byte - Push the following 36 bytes (0x24)
- 4-bytes - Message header (0xD3407053)
- 32-bytes - h*
- ~5-bytes - BMM identifier bytes
-
-
-[https://github.com/DriveNetTESTDRIVE/DriveNet/blob/564516653c1d876429382971a011f5f6119f7eb4/src/validation.cpp#L3377-L3470 Link to code].
+Most BMM Request txns will never make it into a block. Simon will make many BMM Requests, but only one will be accepted. Since only one BMM Request can enter the L1 block, Simon may feel comfortable making multiple offers all day long. This means Mary has many offers to choose from, and can choose the one that pays her the most.
-If these OP_RETURN outputs are not present, then no BMM Requests have been accepted. (And, if they are not accepted, then they cannot be included in a main:block.)
+This BIP allows BMM Requests to take place over Lightning. One method is [https://www.drivechain.info/media/bmm-note/bmm-lightning/ here]. (BMM Accepts cannot be over LN, since they reside in main:coinbase txns.)
==Backward compatibility==
-As a soft fork, older software will continue to operate without modification. As stated above, BMM asks nodes to track a set of ordered hashes, and to allow miners to "sell" the act of finding a sidechain block. Non-upgraded nodes will notice that this activity (specifically: data in coinbases, and new txns that have OP Returns and interesting message headers) is now taking place, but they will not understand any of it. Much like P2SH or a new OP Code, these old users will not be directly affected by the fork, as they will have no expectations of receiving payments of this kind.
-
-(As a matter of fact, the only people receiving money here all happen to be miners. So there is less reason than ever to expect compatibility problems.)
+This soft fork can be deployed without modifying Bitcoin Core at all (ie, via [https://bip300cusf.com/ CUSF]).
==Deployment==
-This BIP will be deployed by "version bits" BIP9 with the name "blindmm" and using bit 4.
+This BIP deploys when/if >51% hashrate runs [https://github.com/LayerTwo-Labs/bip300301_enforcer/ the enforcer client].
-
-// Deployment of Drivechains (BIPX, BIPY)
-consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].bit = 4;
-consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].nStartTime = 1579072881; // January 15th, 2020.
-consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].nTimeout = 1610695281; // January 15th, 2021.
-
+Ideally, a critical mass of users would also run the enforcer client -- this would strongly dissuade miners from ever de-activating it.
==Reference Implementation==
-See: https://github.com/DriveNetTESTDRIVE/DriveNet
-
-Also, for interest, see an example sidechain here: https://github.com/drivechain-project/bitcoin/tree/sidechainBMM
-
-
-==References==
-
-* http://www.drivechain.info/literature/index.html
-* http://www.truthcoin.info/blog/blind-merged-mining/
-* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-July/014789.html
-* http://www.truthcoin.info/images/bmm-outline.txt
-
-
-==Thanks==
+The enforcer is [https://github.com/LayerTwo-Labs/bip300301_enforcer/ here].
-Thanks to everyone who contributed to the discussion, especially: ZmnSCPxj, Adam Back, Peter Todd, Dan Anderson, Sergio Demian Lerner, Matt Corallo, Sjors Provoost, Tier Nolan, Erik Aronesty, Jason Dreyzehner, Joe Miyamoto, Chris Stewart, Ben Goldhaber.
+Also, several example L2s using BIP-301 are [https://releases.drivechain.info/ here].
==Copyright==
diff --git a/bip-0301/bmm-dots-examples.png b/bip-0301/bmm-dots-examples.png
deleted file mode 100644
index 70f11f6bbe..0000000000
Binary files a/bip-0301/bmm-dots-examples.png and /dev/null differ
diff --git a/bip-0301/images.txt b/bip-0301/images.txt
deleted file mode 100644
index 2fbbf63716..0000000000
--- a/bip-0301/images.txt
+++ /dev/null
@@ -1 +0,0 @@
-Images used as reference in the documentation.
diff --git a/bip-0301/witness-vs-critical.png b/bip-0301/witness-vs-critical.png
deleted file mode 100644
index 79c84b1fc5..0000000000
Binary files a/bip-0301/witness-vs-critical.png and /dev/null differ
diff --git a/bip-0310.mediawiki b/bip-0310.mediawiki
index 257e92ad1c..34522bea3f 100644
--- a/bip-0310.mediawiki
+++ b/bip-0310.mediawiki
@@ -190,7 +190,7 @@ send the mask, in this case a default full mask is used.
* '''"version-rolling.mask"''' (REQUIRED, ''TMask'')
::- Bits set to 1 are allowed to be changed by the miner. If a miner changes bits with mask value 0, the server will reject the submit.
-::- The server SHOULD return the largest mask possible (as many bits set to 1 as possible). This can be useful in a mining proxy setup when a proxy needs to negotiate the best mask for its future clients. There is a [Draft BIP](https://github.com/bitcoin/bips/pull/661/files) describing available nVersion bits. The server SHOULD pick a mask that preferably covers all bits specified in the BIP.
+::- The server SHOULD return the largest mask possible (as many bits set to 1 as possible). This can be useful in a mining proxy setup when a proxy needs to negotiate the best mask for its future clients. There is a [https://github.com/bitcoin/bips/pull/661/files Draft BIP] describing available nVersion bits. The server SHOULD pick a mask that preferably covers all bits specified in the BIP.
* '''"version-rolling.min-bit-count"''' (REQUIRED, ''TMask'')
::- The miner also provides a minimum number of bits that it needs for efficient version rolling in hardware. Note that this parameter provides important diagnostic information to the pool server. If the requested bit count exceeds the limit of the pool server, the miner always has the chance to operate in a degraded mode without using full hashing power. The pool server SHOULD NOT terminate miner connection if this rare mismatch case occurs.
@@ -276,7 +276,7 @@ Miner provides additional text-based information.
Currently, there is a similar protocol feature '''mining.capabilities''' that
was intended for various protocol extensions. However, '''mining.configure'''
is incompatible with this feature as it requires a server response confirming
-all accepted/negotatied extensions. The reason why we made it incompatible is
+all accepted/negotiated extensions. The reason why we made it incompatible is
that '''mining.capabilities''' request has no associated response.
diff --git a/bip-0321.mediawiki b/bip-0321.mediawiki
new file mode 100644
index 0000000000..ff5e8e4ed7
--- /dev/null
+++ b/bip-0321.mediawiki
@@ -0,0 +1,236 @@
+
+
+== Copyright ==
+
+This BIP is licensed under the BSD 2-clause license.
+
+== Abstract ==
+
+This BIP proposes a URI scheme for describing Bitcoin payment instructions.
+
+== Motivation ==
+
+The purpose of this URI scheme is to enable users to easily make payments by simply clicking links on webpages or scanning QR Codes.
+
+This BIP is a modification of [[bip-0021.mediawiki|BIP 0021]] to add information about the modern usage of bitcoin: URIs (including standard query parameters and modern address types) as well as provide forward-looking guidance on how to incorporate new payment instructions. It further adds an optional extension to provide the payment initiator with proof of payment. BIP 21 was based on BIP 20, which was, in turn based on an earlier document by Nils Schneider.
+
+== Specification ==
+
+=== General rules for handling (important!) ===
+
+Bitcoin clients MUST NOT act on URIs without getting the user's authorization.
+They SHOULD require the user to manually approve each payment individually, though in some cases they MAY allow the user to automatically make this decision.
+
+=== Operating system integration ===
+
+Graphical bitcoin clients SHOULD register themselves as the handler for the "bitcoin:" URI scheme by default, if no other handler is already registered. If there is already a registered handler, they MAY prompt the user to change it once when they first run the client.
+
+=== General Format ===
+
+Bitcoin URIs follow the general format for URIs as set forth in RFC 3986. The path component consists of a bitcoin address, and the query component provides additional payment options.
+
+Elements of the query component may contain characters outside the valid range. These must first be encoded according to UTF-8, and then each octet of the corresponding UTF-8 sequence must be percent-encoded as described in RFC 3986.
+
+=== ABNF grammar ===
+
+ bitcoinurn = "bitcoin:" [ bitcoinaddress ] [ "?" bitcoinparams ]
+ bitcoinaddress = *base58 / *bech32 / *bech32m
+ bitcoinparams = bitcoinparam [ "&" bitcoinparams ]
+ bitcoinparam = [ amountparam / labelparam / messageparam / responseparam / otherparam / reqparam ]
+ amountparam = "amount=" *digit [ "." *digit ]
+ labelparam = "label=" *qchar
+ messageparam = "message=" *qchar
+ responseparam = [ "req-" ] "pop=" *qchar
+ otherparam = qchar *qchar [ "=" *qchar ]
+ reqparam = "req-" qchar *qchar [ "=" *qchar ]
+
+Here, "qchar" corresponds to valid characters of an RFC 3986 URI query component, excluding the "=" and "&" characters, which this BIP takes as separators.
+
+The scheme component ("bitcoin:") is case-insensitive, and implementations must accept any combination of uppercase and lowercase letters. The query parameter keys are also case-insensitive. Query parameter values and bitcoin address fields may be case-sensitive depending on their content.
+
+Multiple query parameters with the same key MAY be included for query parameters representing payment instructions. Multiple query parameters with the same key MUST NOT be included for keys "label", "message", or "pop". Multiple query parameters with the same key for other keys MUST be allowed for unknown query parameters. Future query parameter keys may or may not allow for duplicate parameters.
+
+=== Bitcoin Address ===
+
+The bitcoinaddress body MUST be either a base58 P2SH or P2PKH address, bech32 Segwit version 0 address, bech32m Segwit address, or empty. Future address formats SHOULD instead be placed in query keys as optional payment instructions to provide backwards compatibility during upgrade cycles. The bitcoinaddress part of the URI MAY be left empty if there is at least one payment instruction provided in a query parameter, allowing for recipients wishing to avoid a standard on-chain fallback.
+
+=== Query Keys ===
+
+The following keys are defined generally and apply to any URI regardless of payment instructions:
+
+*label: Label for the recipient (e.g. name of receiver)
+*message: message that describes the transaction to the user ([[#Examples|see examples below]])
+*pop: a URI which the Bitcoin Wallet may return to in order to provide the application which initiated the payment with proof that a payment was completed.
+
+The following keys are currently defined for payment instructions of various forms:
+
+*lightning: Lightning BOLT 11 invoices
+*lno: Lightning BOLT12 offers
+*pay: [[bip-0351.mediawiki|BIP 351 Private Payment addresses]]
+*sp: [[bip-0352.mediawiki|BIP 352 Silent Payment addresses]]
+
+New payment instructions using bech32 or bech32m encodings SHOULD reuse their address format's Human Readable Part as the parameter key.
+
+==== Transfer amount ====
+
+If an amount is provided, it MUST be specified in decimal BTC.
+All amounts MUST contain no commas and use a period (.) as the separating character to separate whole numbers and decimal fractions.
+I.e. amount=50.00 or amount=50 is treated as 50 BTC, and amount=50,000.00 is invalid.
+
+=== Proof of Payment ===
+
+The URI MAY include a "pop" (or "req-pop") parameter whose value can be used to build a URI which the wallet application can, after payment completes, "open" to provide proof the payment was completed or other information about the payment.
+
+The value of a "pop" (or "req-pop") parameter shall be a percent-encoded (per RFC 3986 section 2.1) URI prefix. The wallet application, if it supports providing payment information SHOULD percent-decode the provided URI once, append the query parameter key from which the payment instructions used were read, append a single =, and finally append the Payment Information to the resulting URI and open it with the default system handler for the URI. For payment instructions read from the body of the URI, "onchain" SHALL be used in place of the key.
+
+A wallet MUST validate that the provided URI's scheme is not (case-insensitive) "http", "https", "file", "javascript", "mailto" or any other scheme which will open in a web browser prior to opening it.
+
+If a wallet will not open the pop scheme (either because it does not support returning payment information for the selected payment method or because it uses a URI scheme which should not be opened) and the parameter was passed as a "req-pop" parameter, the wallet MUST NOT initiate payment.
+
+For payments made using an on-chain transaction, the Payment Information shall be the full (including witness data) Bitcoin transaction as it was broadcasted to the Bitcoin network, encoded in hex.
+
+For payments made using a BOLT 11 invoice (communicated via the `lightning` parameter), the Payment Information shall be the hex-encoded payment preimage.
+
+Other payment schemes will define their own Payment Information format. This BIP may be updated from time to time with Payment Information formats for other payment schemes.
+
+== Rationale ==
+
+=== Payment identifiers, not person identifiers ===
+
+Best practices are that a unique address should be used for every transaction on-chain.
+Therefore, a URI which contains an on-chain payment address MUST NOT represent an exchange of personal information, but a one-time payment instruction. URIs which represent only reusable non-address-reusing payment instructions (like Lightning BOLT12 offers or Silent Payments) MAY be reused as a wallet sees fit.
+
+=== Proof of Payment ===
+
+On many mobile operating systems (especially, or any operating system more generally), applications may "open" a bitcoin: URI in order to initiate a payment with the user's default wallet application. These payment-initiating applications may wish to learn about the completed payment.
+
+For payments completed on-chain, this is largely addressed by having the payment-initiating application monitor the blockchain for payment completion, however for other payment schemes (e.g. lightning), no such global ledger of transactions exists. In that case, proof of payment must be provided via some other mechanism.
+
+In order to avoid inadvertently revealing the sender's IP address or other information to the recipient, proof URIs must only be opened when they will simply switch to another locally-installed application (i.e. the application which initiated the payment). When clicking a URI from a website, the website should already have plenty of logic on its backend to process payment completion and a proof-of-payment callback is unnecessary.
+
+== Forward compatibility ==
+
+Query parameter keys which are prefixed with a req- are considered required. If a client does not implement handling a query parameter which has a key prefixed with req-, it MUST consider the entire URI invalid. Any other query parameters which are not implemented, but which are not prefixed with a req-, can be safely ignored.
+
+As future new address types should be added using query parameters rather than the `bitcoinaddress` field, URIs seamlessly support various payment instructions while senders only need to support legacy instructions. This allows old senders to pay newer recipients which offer more modern payment instruction formats.
+
+== Backward compatibility ==
+
+Compared to BIP 21, this document describes standard query parameters containing payment instructions, makes query parameters case-insensitive, allows bech32 and bech32m addresses in the `bitcoinaddress` field, and allows for URIs with an empty `bitcoinaddress` field. Use of bech32 and bech32m `bitcoinaddress` fields were long-since common practice in 2024, and the `lightning` query parameter storing BOLT 11 payment instructions became common practice in the year or three leading up to 2024. Inclusion of standard query parameters was added to provide guidance on query parameter usage going forward.
+
+Additionally, this BIP describes the "pop" query parameter, which was unused and will be ignored by BIP 21 implementations.
+
+Any existing BIP 21 implementation should automatically be fully compliant with this BIP, as the changes only describe existing practice or impact future address format inclusion, with the one possible exception of query parameters being made case-insensitive. Note, however, that treating query parameters as case-insensitive is already common practice due to the use of mostly-uppercase URIs in QR codes.
+
+== Appendix ==
+
+=== Examples ===
+
+==== URIs ====
+
+Just the address:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W
+
+Address with recipient's name as label:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Luke-Jr
+
+Request 20.30 BTC to "Luke-Jr":
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=20.3&label=Luke-Jr
+
+Address with recipient's name as label:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Luke-Jr
+
+Request 50 BTC with message:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=50&label=Luke-Jr&message=Donation%20for%20project%20xyz
+
+Request funds to be paid over lightning to a BOLT 11 invoice with a fallback to on-chain payments:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?lightning=lnbc420bogusinvoice
+
+Request funds to be paid over lightning to a BOLT 11 invoice with no fallback:
+ bitcoin:?lightning=lnbc420bogusinvoice
+
+Request funds to be paid over lightning to a BOLT 12 offer with no fallback:
+ bitcoin:?lno=lno1bogusoffer
+
+Request funds to be paid over lightning to a BOLT 12 offer or silent payments address with no fallback:
+ bitcoin:?lno=lno1bogusoffer&sp=sp1qsilentpayment
+
+Request funds to be paid to a silent payments address with no fallback:
+ bitcoin:?sp=sp1qsilentpayment
+
+Request funds to be paid to a silent payments address with a fallback:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?sp=sp1qsilentpayment
+
+Some future version that has variables which are (currently) not understood and required and thus invalid:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-somethingyoudontunderstand=50&req-somethingelseyoudontget=999
+
+Some future version that has variables which are (currently) not understood but not required and thus valid:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?somethingyoudontunderstand=50&somethingelseyoudontget=999
+
+Multiple segwit addresses may be included for various versions of segwit, note that the human-readable part for all of them is `bc`
+ bitcoin:?bc=bc1qufgy354j3kmvuch987xe4s40836x3h0lg8f5n2&bc=bc1p5swkugezn97763tl0yty6556856uug0q6jflljvep9m4p7339x5qzyrh4g
+
+Many QR codes utilize all-uppercase URIs, which should be handled fine
+ BITCOIN:BC1QUFGY354J3KMVUCH987XE4S40836X3H0LG8F5N2?BC=BC1P5SWKUGEZN97763TL0YTY6556856UUG0Q6JFLLJVEP9M4P7339X5QZYRH4G
+ BITCOIN:?BC=BC1QUFGY354J3KMVUCH987XE4S40836X3H0LG8F5N2&BC=BC1P5SWKUGEZN97763TL0YTY6556856UUG0Q6JFLLJVEP9M4P7339X5QZYRH4G
+
+A testnet segwit addresses must be included in the `tb` parameter
+ bitcoin:?tb=tb1qghfhmd4zh7ncpmxl3qzhmq566jk8ckq4gafnmg
+
+Characters must be URI encoded properly.
+
+==== Invalid URIs ====
+
+Labels must not appear twice:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Luke-Jr&label=Matt
+
+Amounts must not appear twice:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=42&amount=10
+
+Amounts must not appear twice even if they are the same:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=42&amount=42
+
+Multiple proof of payment URIs must not appear, even if they are sometimes prefixed with req-:
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?pop=callback%3a&req-pop=callback%3a
+
+A testnet segwit addresses must be included in the `tb` parameter, not the `bc` parameter.
+ bitcoin:?bc=tb1qghfhmd4zh7ncpmxl3qzhmq566jk8ckq4gafnmg
+
+==== Proof of Payment ====
+
+If the original URI is
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?pop=initiatingapp%3a
+the wallet should perform the payment information callback by opening
+ initiatingapp:onchain=$HEX_ENCODED_TRANSACTION
+
+If the original URI is
+ bitcoin:?lightning=lnbc420bogusinvoice&pop=callbackuri%3abody%3fpop=
+the wallet should perform the proof-of-payment callback by opening
+ callbackuri:body?pop=lightning=$HEX_ENCODED_PAYMENT_PREIMAGE
+
+If the original URI is
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?lightning=lnbc420bogusinvoice&pop=app%3a%3f
+and the wallet pays on-chain, it should perform the payment information callback by opening
+ app:?onchain=$HEX_ENCODED_TRANSACTION
+but if the app pays using lightning, it should perform the proof-of-payment callback by opening
+ app:?lightning=$HEX_ENCODED_PAYMENT_PREIMAGE
+
+If the original URI is
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?pop=https%3aiwantyouripaddress.com
+the wallet should make a payment as it normally would but MUST NOT interact with iwantyouripaddress.com
+
+If the original URI is
+ bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-pop=https%3aevilwebsite.com
+the wallet MUST NOT make a payment
diff --git a/bip-0322.mediawiki b/bip-0322.mediawiki
index 5f4704d099..81ef896d3b 100644
--- a/bip-0322.mediawiki
+++ b/bip-0322.mediawiki
@@ -61,27 +61,25 @@ The to_spend transaction is:
vout[0].nValue = 0
vout[0].scriptPubKey = message_challenge
-where message_hash is a BIP340-tagged hash of the message, i.e. sha256_tag(m), where tag = BIP0322-signed-message, and message_challenge is the to be proven (public) key script.
+where message_hash is a BIP340-tagged hash of the message, i.e. sha256_tag(m), where tag = BIP0322-signed-message and m is the message as is without length prefix or null terminator, and message_challenge is the to be proven (public) key script.
The to_sign transaction is:
- nVersion = 0 or as appropriate (e.g. 2, for time locks)
- nLockTime = 0 or as appropriate (for time locks)
+ nVersion = 0 or (FULL format only) as appropriate (e.g. 2, for time locks)
+ nLockTime = 0 or (FULL format only) as appropriate (for time locks)
vin[0].prevout.hash = to_spend.txid
vin[0].prevout.n = 0
- vin[0].nSequence = 0 or as appropriate (for time locks)
+ vin[0].nSequence = 0 or (FULL format only) as appropriate (for time locks)
vin[0].scriptWitness = message_signature
vout[0].nValue = 0
vout[0].scriptPubKey = OP_RETURN
-A full signature consists of the base64-encoding of the to_sign transaction in standard network serialisation.
+A full signature consists of the base64-encoding of the to_sign transaction in standard network serialisation once it has been signed.
=== Full (Proof of Funds) ===
A signer may construct a proof of funds, demonstrating control of a set of UTXOs, by constructing a full signature as above, with the following modifications.
-* message_challenge is unused and shall be set to OP_TRUE
-* Similarly, message_signature is then empty.
* All outputs that the signer wishes to demonstrate control of are included as additional inputs of to_sign, and their witness and scriptSig data should be set as though these outputs were actually being spent.
Unlike an ordinary signature, validators of a proof of funds need access to the current UTXO set, to learn that the claimed inputs exist on the blockchain, and to learn their scriptPubKeys.
@@ -120,7 +118,7 @@ Validation consists of the following steps:
# Check the **upgradeable rules**
## The version of to_sign must be 0 or 2.
## The use of NOPs reserved for upgrades is forbidden.
-## The use of segwit versions greater than 0 are forbidden.
+## The use of segwit versions greater than 1 are forbidden.
## If any of the above steps failed, the validator should stop and output the ''inconclusive'' state.
# Let ''T'' by the nLockTime of to_sign and ''S'' be the nSequence of the first input of to_sign. Output the state ''valid at time T and age S''.
@@ -144,7 +142,7 @@ This specification is backwards compatible with the legacy signmessage/verifymes
== Reference implementation ==
-TODO
+* Bitcoin Core pull request (basic support) at: https://github.com/bitcoin/bitcoin/pull/24058
== Acknowledgements ==
@@ -160,4 +158,33 @@ This document is licensed under the Creative Commons CC0 1.0 Universal license.
== Test vectors ==
-TODO
+=== Message hashing ===
+
+Message hashes are BIP340-tagged hashes of a message, i.e. sha256_tag(m), where tag = BIP0322-signed-message, and m is the message as is without length prefix or null terminator:
+
+* Message = "" (empty string): c90c269c4f8fcbe6880f72a721ddfbf1914268a794cbb21cfafee13770ae19f1
+* Message = "Hello World": f0eb03b1a75ac6d9847f55c624a99169b5dccba2a31f5b23bea77ba270de0a7a
+
+=== Message signing ===
+
+Given below parameters:
+
+* private key L3VFeEujGtevx9w18HD1fhRbCH67Az2dpCymeRE1SoPK6XQtaN2k
+* corresponding address bc1q9vza2e8x573nczrlzms0wvx3gsqjx7vavgkx0l
+
+Produce signatures:
+
+* Message = "" (empty string): AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI= or AkgwRQIhAPkJ1Q4oYS0htvyuSFHLxRQpFAY56b70UvE7Dxazen0ZAiAtZfFz1S6T6I23MWI2lK/pcNTWncuyL8UL+oMdydVgzAEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy
+* Message = "Hello World": AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI= or AkgwRQIhAOzyynlqt93lOKJr+wmmxIens//zPzl9tqIOua93wO6MAiBi5n5EyAcPScOjf1lAqIUIQtr3zKNeavYabHyR8eGhowEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy
+
+=== Transaction Hashes ===
+
+to_spend:
+
+* Message = "" (empty string): c5680aa69bb8d860bf82d4e9cd3504b55dde018de765a91bb566283c545a99a7
+* Message = "Hello World": b79d196740ad5217771c1098fc4a4b51e0535c32236c71f1ea4d61a2d603352b
+
+to_sign:
+
+* Message = "" (empty string): 1e9654e951a5ba44c8604c4de6c67fd78a27e81dcadcfe1edf638ba3aaebaed6
+* Message = "Hello World": 88737ae86f2077145f93cc4b153ae9a1cb8d56afa511988c149c5c8c9d93bddf
diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki
new file mode 100644
index 0000000000..941d96e006
--- /dev/null
+++ b/bip-0324.mediawiki
@@ -0,0 +1,596 @@
+
+ BIP: 324
+ Layer: Peer Services
+ Title: Version 2 P2P Encrypted Transport Protocol
+ Author: Dhruv Mehta
+ Tim Ruffing
+ Jonas Schnelli
+ Pieter Wuille
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0324
+ Status: Final
+ Type: Standards Track
+ Created: 2019-03-08
+ License: BSD-3-Clause
+ Replaces: 151
+
+
+== Introduction ==
+
+=== Abstract ===
+This document proposes a new Bitcoin P2P transport protocol, which features opportunistic encryption, a mild bandwidth reduction, and the ability to negotiate upgrades before exchanging application messages.
+
+=== Copyright ===
+This document is licensed under the 3-clause BSD license.
+
+=== Motivation ===
+Bitcoin is a permissionless network whose purpose is to reach consensus over public data. Since all data relayed in the Bitcoin P2P network is inherently public, and the protocol lacks a notion of cryptographic identities, peers talk to each other over unencrypted and unauthenticated connections. Nevertheless, this plaintext nature of the current P2P protocol (referred to as v1 in this document) has severe drawbacks in the presence of attackers:
+
+* While the relayed data itself is public in nature, the associated metadata may reveal private information and hamper privacy of users. For example, a global passive attacker eavesdropping on all Bitcoin P2P connections can trivially identify the source and timing of a transaction.
+* Since connections are unauthenticated, they can be tampered with at a low cost and often even with a low risk of detection. For example, an attacker can alter specific bytes of a connection (such as node flags) on-the-fly without the need to keep any state.
+* The protocol is self-revealing. For example, deep packet inspection can identify a P2P connection trivially because connections start with a fixed sequence of magic bytes. The ability to detect connections enables censorship and facilitates the aforementioned attacks as well as other attacks which require the attacker to control the connections of victims, e.g., eclipse attacks targeted at miners.
+
+This proposal for a new P2P protocol version (v2) aims to improve upon this by raising the costs for performing these attacks substantially, primarily through the use of unauthenticated, opportunistic transport encryption. In addition, the bytestream on the wire is made pseudorandom (i.e., indistinguishable from uniformly random bytes) to a passive eavesdropper.
+
+* Encryption, even when it is unauthenticated and only used when both endpoints support v2, impedes eavesdropping by forcing the attacker to become active: either by performing a persistent man-in-the-middle (MitM) attack, by downgrading connections to v1, or by spinning up their own nodes and getting honest nodes to make connections to them. Active attacks at scale are more resource intensive in general, but in the case of manual, deliberate connections (as opposed to automatic, random ones), they are also in principle detectable: even very basic checks, e.g., operators manually comparing protocol versions and session IDs (as supported by the proposed protocol), will expose the attacker.
+* Tampering, while already an inherently active attack, is costlier if the attacker is forced to maintain the state necessary for a full MitM interception.
+* A pseudorandom bytestream excludes identification techniques based on pattern matching, and makes it easier to shape the bytestream in order to mimic other protocols used on the Internet. This raises the cost of a connection censoring firewall, forcing them to either resort to a full MitM attack, or operate on a more obvious allowlist basis, rather than a blocklist basis.
+
+''' Why encrypt without authentication?'''
+
+As we have argued above, unauthenticated encryption'''What does ''authentication'' mean in this context?''' Unfortunately, the term authentication in the context of secure channel protocols is ambiguous. It can refer to:
+* The encryption scheme guaranteeing that a message obtained via successful decryption was encrypted by someone having access to the (symmetric) encryption key, and not modified after encryption by a third party. The proposal in this document achieves that property through the use of an AEAD.
+* The communication protocol establishing that the communication partner's identity matches who we expect them to be, through some public key mechanism. The proposal in this document does '''not''' include such a mechanism. provides strictly better security than no encryption. Thus, all connections should use encryption, even if they are unauthenticated.
+
+When it comes to authentication, the situation is not as clear as for encryption. Due to Bitcoin's permissionless nature, authentication will always be restricted to specific scenarios (e.g., connections between peers belonging to the same operator), and whether some form of (possibly partially anonymous) authentication is desired depends on the specific requirements of the involved peers. As a consequence, we believe that authentication should be addressed separately (if desired), and this proposal aims to provide a solid technical basis for future protocol upgrades, including the addition of optional authentication (see [https://github.com/sipa/writeups/tree/main/private-authentication-protocols Private authentication protocols]).
+
+''' Why have a pseudorandom bytestream when traffic analysis is still possible? '''
+
+Traffic analysis, e.g., observing packet lengths and timing, as well as active attacks can still reveal that the Bitcoin v2 P2P protocol is in use. Nevertheless, a pseudorandom bytestream raises the cost of fingerprinting the protocol substantially, and may force some intermediaries to attack any protocol they cannot identify, causing collateral cost.
+
+A pseudorandom bytestream is not self-identifying. Moreover, it is unopinionated and thus a canonical choice for similar protocols. As a result, Bitcoin P2P traffic will be indistinguishable from traffic of other protocols which make the same choice (e.g., [https://gitlab.com/yawning/obfs4 obfs4] and a recently proposed [https://datatracker.ietf.org/doc/draft-cpbs-pseudorandom-ctls/ cTLS extension]). Moreover, traffic shapers and protocol wrappers (for example, making the traffic look like HTTPS or SSH) can further mitigate traffic analysis and active attacks but are out of scope for this proposal.
+
+''' Why not use a secure tunnel protocol? '''
+
+Our goal includes making opportunistic encryption ubiquitously available, as that provides the best defense against large-scale attacks. That implies protecting both the manual, deliberate connections node operators instruct their software to make, and the automatic connections Bitcoin nodes make with each other based on IP addresses obtained via gossip. While encryption per se is already possible with proxy networks or VPN protocols, these are not desirable or applicable for automatic connections at scale:
+* Proxy networks like Tor or I2P introduce a separate address space, independent of network topology, with a very low cost per address making eclipse attacks cheaper. In comparison, clearnet IPv4 and IPv6 networks make obtaining multiple network identities in distinct, well-known network partitions carry a non-trivial cost. Thus, it is not desirable to have a substantial portion of nodes be exclusively connected this way, as this would significantly reduce Eclipse attack costs.'''Why is it a bad idea to have nodes exclusively connected over Tor?''' See the [https://arxiv.org/abs/1410.6079 Bitcoin over Tor isn't a Good Idea] paper Additionally, Tor connections come with significant bandwidth and latency costs that may not be desirable for all network users.
+* VPN protocols like WireGuard or OpenVPN inherently define a private network, which requires manual configuration and therefore is not a realistic avenue for automatic connections.
+
+Thus, to achieve our goal, we need a solution that has minimal costs, works without configuration, and is always enabled – on top of any network layer rather than be part of the network layer.
+
+''' Why not use a general-purpose transport encryption protocol? '''
+
+While it would be possible to rely on an off-the-shelf transport encryption protocol such as TLS or Noise, the specific requirements of the Bitcoin P2P network laid out above make these protocols an unsuitable choice.
+
+The primary requirement which existing protocols fail to meet is a sufficiently modular treatment of encryption and authentication. As we argue above, whether and which form of authentication is desired in the Bitcoin P2P network will depend on the specific requirements of the involved peers (resulting in a mix of authenticated and unauthenticated connections), and thus the question of authentication should be decoupled from encryption. However, native support for a handful of standard authentication scenarios (e.g., using digital signatures and certificates) is at the core of the design of existing general-purpose transport encryption protocols. This focus on authentication would not provide clear benefits for the Bitcoin P2P network but would come with a large amount of additional complexity.
+
+In contrast, our proposal instead aims for a simple modular design that makes it possible to address authentication separately. Our proposal provides a foundation for authentication by exporting a ''session ID'' that uniquely identifies the encrypted channel. After an encrypted channel has been established, the two endpoints are able to use any authentication protocol to confirm that they have the same session ID. (This is sometimes called ''channel binding'' because the session ID binds the encrypted channel to the authentication protocol.) Since in our proposal, any authentication needs to run after an encrypted connection has been established, the price we pay for this modularity is a possibly higher number of roundtrips as opposed to other protocols that perform authentication alongside the Diffie-Hellman key exchange.'''Do other protocols not support exporting a session ID?''' While [https://noiseprotocol.org/noise.html#channel-binding Noise] and [https://datatracker.ietf.org/doc/draft-ietf-kitten-tls-channel-bindings-for-tls13/ TLS (as a draft)] offer similar protocol extensions for exporting session IDs, using channel binding for authentication is not at the focus of their design and would not avoid the bulk of additional complexity due to the native support of authentication methods. However, the resulting increase in connection establishment latency is a not a concern for Bitcoin's long-lived connections, [https://www.dsn.kastel.kit.edu/bitcoin/ which typically live for hours or even weeks].
+
+Besides this fundamentally different treatment of authentication, further technical issues arise when applying TLS or Noise to our desired use case:
+
+* Neither offers a pseudorandom bytestream.
+* Neither offers native support for elliptic curve cryptography on the curve secp256k1 as otherwise used in Bitcoin. While using secp256k1 is not strictly necessary, it is the obvious choice is for any new asymmetric cryptography in Bitcoin because it minimizes the cryptographic hardness assumptions as well as the dependencies that Bitcoin software will need.
+* Neither offers shapability of the bytestream.
+* Both provide a stream-based interface to the application layer, whereas Bitcoin requires a packet-based interface, resulting in the need for an additional thin layer to perform packet serialization and deserialization.
+
+While existing protocols could be amended to address all of the aforementioned issues, this would negate the benefits of using them as off-the-shelf solution, e.g., the possibility to re-use existing implementations and security analyses.
+
+== Goals ==
+
+This proposal aims to achieve the following properties:
+
+* Confidentiality against passive attacks: A passive attacker having recorded a v2 P2P bytestream (without timing and fragmentation information) must not be able to determine the plaintext being exchanged by the nodes.
+* Observability of active attacks: A session ID identifying the encrypted channel uniquely is derived deterministically from a Diffie-Hellman negotiation. An active man-in-the-middle attacker is forced to incur a risk of being detected as peer operators can compare session IDs manually, or using optional authentication methods possibly introduced in future protocol versions.
+* Pseudorandom bytestream: A passive attacker having recorded a v2 P2P bytestream (without timing information and fragmentation information) must not be able to distinguish it from a uniformly random bytestream.
+* Shapable bytestream: It should be possible to shape the bytestream to increase resistance to traffic analysis (for example, to conceal block propagation), or censorship avoidance.'''How can shapability help circumvent fragmentation-pattern based censoring?''' See [https://gitlab.torproject.org/legacy/trac/-/issues/20348#note_2229522 this Tor issue] as an example.
+* Forward secrecy: An eavesdropping attacker who compromises a peer's sessions secrets should not be able to decrypt past session traffic, except for the latest few packets.
+* Upgradability: The proposal provides an upgrade path using transport versioning which can be used to add features like authentication, PQC handshake upgrade, etc. in the future.
+* Compatibility: v2 clients will allow inbound v1 connections to minimize risk of network partitions.
+* Low overhead: the introduction of a new P2P transport protocol should not substantially increase computational cost or bandwidth for nodes that implement it, compared to the current protocol.
+
+== Specification ==
+
+The specification consists of three parts:
+
+* The '''Transport layer''' concerns how to set up an encrypted connection between two nodes, capable of transporting application-level messages between them.
+* The '''Application layer''' concerns how to encode Bitcoin P2P messages and commands for transport by the Transport Layer.
+* The '''Signaling''' concerns how v2 nodes advertise their support for the v2 protocol to potential peers.
+
+=== Transport layer specification ===
+
+In this section, we define the encryption protocol for messages between peers.
+
+==== Overview and design ====
+
+We first give an informal overview of the entire protocol flow and packet encryption.
+
+'''Protocol flow overview'''
+
+Given a newly established connection (typically TCP/IP) between two v2 P2P nodes, there are 3 phases the connection goes through. The first starts immediately, i.e. there are no v1 messages or any other bytes exchanged on the link beforehand. The two parties are called the '''initiator''' (who established the connection) and the '''responder''' (who accepted the connection).
+
+# The '''Key exchange phase''', where nodes exchange data to establish shared secrets.
+#* The initiator:
+#** Generates a random ephemeral secp256k1 private key and sends a corresponding 64-byte ElligatorSwift'''What is ElligatorSwift and why use it?''' The [https://eprint.iacr.org/2022/759.pdf SwiftEC paper] describes a method called ElligatorSwift which allows encoding elliptic curve points in a way that is indistinguishable from a uniformly distributed bitstream. While a random 256-bit string has about 50% chance of being a valid X coordinate on the secp256k1 curve, every 512-bit string is a valid ElligatorSwift encoding of a curve point, making the encoded point indistinguishable from random when using an encoder that can sample uniformly.'''How fast is ElligatorSwift?''' Our benchmarks show that ElligatorSwift encoded ECDH is about 50% more expensive than unencoded ECDH. Given the fast performance of ECDH and the low frequency of new connections, we found the performance trade-off acceptable for the pseudorandom bytestream and future censorship resistance it can enable.-encoded public key to the responder.
+#** May send up to 4095'''How was the limit of 4095 bytes garbage chosen?''' It is a balance between having sufficient freedom to hide information, and allowing it to be large enough so that the necessary 64 bytes of public key is small compared to it on the one hand, and bandwidth waste on the other hand. bytes of arbitrary data after their public key, called '''garbage''', providing a form of shapability and avoiding a recognizable pattern of exactly 64 bytes.'''Why does the affordance for garbage exist in the protocol?''' The garbage strings after the public keys are needed for shapability of the handshake. Neither peer can send decoy packets before having received at least the other peer's public key, i.e., neither peer can send more than 64 bytes before having received 64 bytes.
+#* The responder:
+#** Waits until one byte is received which does not match the 16 bytes consisting of the network magic followed by "version\x00\x00\x00\x00\x00". If the first 16 bytes do match, the connection is treated as using the v1 protocol instead.'''What if a v2 initiator's public key starts accidentally with these 16 bytes?''' This is so unlikely (probability of ''2-128'') to happen randomly in the v2 protocol that the initiator does not need to specifically avoid it. The optional detection of wrong-network v1 peers has a probability of ''2-96'', which is still negligible compared to random network failures.Bitcoin Core versions <=0.4.0 and >=22.0 ignore valid P2P messages that are received prior to a VERSION message. Bitcoin Core versions between 0.4.0 and 22.0 assign a misbehavior score to the peer upon receiving such messages. v2 clients implementing this proposal will interpret any message other than VERSION received as the first message to be the initiation of a v2 connection, and will result in disconnection for v1 initiators that send any message type other than VERSION as the first message. We are not aware of any implementations where this could pose a problem.
+#** If the first 4 received bytes do not match the network magic, but the 12 bytes after that do match the version message encoding above, implementations may interpret this as a v1 peer of a different network, and disconnect them.
+#** Similarly generates a random ephemeral private key and sends a corresponding 64-byte ElligatorSwift-encoded public key to the initiator.
+#** Similarly may send up to 4095 bytes of garbage data after their public key.
+#* Both parties:
+#** Receive (the remainder of) the full 64-byte public key from the other side.
+#** Use X-only'''Why use X-only ECDH?''' Using only the X coordinate provides the same security as using a full encoding of the secret curve point but allows for more efficient implementation by avoiding the need for square roots to compute Y coordinates. ECDH to compute a shared secret from their private key and the exchanged public keys'''Why is the shared secret computation a function of the exact 64-byte public encodings sent?''' This makes sure that an attacker cannot modify the public key encoding used without modifying the rest of the stream. If a third party wants the ability to modify stream bytes, they need to perform a full MitM attack on the connection., and deterministically derive from the secret 4 '''encryption keys''' (two in each direction: one for packet lengths, one for content encryption), a '''session id''', and two 16-byte '''garbage terminators''''''What length is sufficient for garbage terminators?''' The length of the garbage terminators determines the probability of accidental termination of a legitimate v2 connection due to garbage bytes (sent prior to ECDH) inadvertently including the terminator. 16 byte terminators with 4095 bytes of garbage yield a negligible probability of such collision which is likely orders of magnitude lower than random connection failure on the Internet.'''What does a garbage terminator in the wild look like?'''
[[File:bip-0324/garbage_terminator.png|none|256px|A garbage terminator model TX-v2 in the wild... sent by the responder]]
+ (one in each direction) using HKDF-SHA256.
+#** Send their 16-byte garbage terminator.'''Why does the protocol need a garbage terminator?''' While it is in principle possible to use the first packet after the garbage directly as a terminator (scan until a valid packet follows), this would be significantly slower than just scanning for a fixed byte sequence, as it would require recomputing a Poly1305 tag after every received byte.
+#** Receive up to 4111 bytes, stopping when encountering the garbage terminator.
+#* At this point, both parties have the same keys, and all further communication proceeds in the form of '''encrypted packets'''.
+#** Encrypted packets have an '''ignore bit''', which makes them '''decoy packets''' if set. Decoy packets are to be ignored by the receiver apart from verifying they decrypt correctly. Either peer may send such decoy packets at any point from here on. These form the primary shapability mechanism in the protocol. How and when to use them is out of scope for this document.
+#** For each of the two directions, the first encrypted packet that will be sent in that direction (regardless of it being a decoy packet or not) will make use of the associated authenticated data (AAD) feature of the AEAD to authenticate the garbage that has been sent in that direction.'''Why does the protocol authenticate the garbage?''' Without garbage authentication, the garbage would be modifiable by a third party without consequences. We want to force any active attacker to have to maintain a full protocol state. In addition, such malleability without the consequence of connection termination could enable protocol fingerprinting.
+# The '''Version negotiation phase''', where parties negotiate what transport version they will use, as well as data defined by that version.'''What features could be added in future protocol versions?''' Examples of features that could be added in future versions include post-quantum cryptography upgrades to the handshake, and optional authentication.
+#* The responder:
+#** Sends a '''version packet''' with empty content, to indicate support for the v2 P2P protocol proposed by this document. Any other value for content is reserved for future versions.
+#* The initiator:
+#** Receives a packet, ignores its contents. The idea is that features added by future versions get negotiated based on what is supported by both parties. Since there is just one version so far, the contents here can simply be ignored. But in the future, receiving a non-empty contents here may trigger other behavior; we defer specifying the encoding for such version content until there is a need for it.'''How will future versions encode version numbers in the version packet?''' Future versions could, for example, specify that the contents of the version packet is to be interpreted as an integer version number (with empty representing 0), and if the minimum of both numbers is N, that being interpreted as choosing a "v2.N" protocol version. Alternatively, certain bytes of the version packet contents could be interpreted as a bitvector of optional features.
+#** Sends a '''version packet''' with empty content as well, to indicate support for the v2 P2P protocol.
+#* The responder:
+#** Receives a packet, ignores its contents.
+# The '''Application phase''', where the packets exchanged have contents to be interpreted as application data.
+#* Whenever either peer has a message to send, it sends a packet with that application message as '''contents'''.
+
+To avoid the recognizable pattern of first messages being at least 64 bytes, a future backwards-compatible upgrade to this protocol may allow both peers to send their public key + garbage + garbage terminator in multiple rounds, slicing those bytes up into messages arbitrarily, as long as progress is guaranteed.'''How can progress be guaranteed in a backwards-compatible way?''' In order to guarantee progress, it must be ensured that no deadlock occurs, i.e., no state is reached in which each party waits for the other party indefinitely. For example, any upgrade that adheres to the following conditions will guarantee progress:
+
+* The initiator must start by sending at least as many bytes as necessary to mismatch the magic/version 16 bytes prefix.
+* The responder must start sending after having received at least one byte that mismatches that 16-byte prefix.
+* As soon as either party has received the other peer's garbage terminator, or has received 4095 bytes of garbage, they must send their own garbage terminator. (When either of these conditions is met, the other party has nothing to respond with anymore that would be needed to guarantee progress otherwise.)
+* Whenever either party receives any nonzero number of bytes, while not having sent their garbage terminator completely yet, they must send at least one byte in response without waiting for more bytes.
+* After either party has sent their garbage terminator, they must transition to the version negotiation phase without waiting for more bytes.
+
+Since the protocol as specified here adheres to these conditions, any upgrade which also adheres to these conditions will be backwards-compatible.
+
+Note that the version negotiation phase does not need to wait for the key exchange phase to complete; version packets can be sent immediately after sending the garbage terminator. So the first two phases together, jointly called '''the handshake''', comprise just 1.5 roundtrips:
+
+* the initiator sends public key + garbage
+* the responder sends public key + garbage + garbage terminator + decoy packets (optional) + version packet
+* the initiator sends garbage terminator + decoy packets (optional) + version packet
+
+'''Packet encryption overview'''
+
+All data on the wire after the garbage terminators takes the form of encrypted packets. Every packet encodes an encrypted variable-length byte array, called the '''contents''', as well as an '''ignore bit''' as mentioned before. The total size of a packet is 20 bytes plus the length of its contents.
+
+Each packet consists of:
+* A 3-byte encrypted '''length''' field, encoding the length of the '''contents''' (between ''0'' and ''224-1'''''Is ''224-1'' bytes sufficient as maximum content size?''' The current Bitcoin P2P protocol has no messages which support more than 4000000 bytes of application payload. By supporting up to ''224-1'' we can accommodate future evolutions needing more than 4 times that value. Hypothetical protocol changes that have even more data to exchange than that should probably use multiple separate messages anyway, because of the per-peer receive buffer sizes involved, and the inability to start processing a message before it is fully received. Of course, future versions of the transport protocol could change the size of the length field, if this were really needed., inclusive).
+* An authenticated encryption of the '''plaintext''', which consists of:
+** A 1-byte '''header''' which consists of transport layer protocol flags. Currently, only the highest bit is defined as the '''ignore bit'''. The other bits are ignored, but this may change in future versions'''Why is the header a part of the plaintext and not included alongside the length field?''' The packet length field is the minimum information that must be available before we can leverage the standard RFC8439 AEAD. Any other data, including metadata like the header being in the content encryption makes it easier to reason about the protocol security w.r.t. data being used before it is authenticated. If the ignore bit was not part of the content, another mechanism would be needed to authenticate it; for example, it could be fed as AAD to the AEAD cipher. We feel the complexity of such an approach outweighs the benefit of saving one byte per message..
+** The variable-length '''contents'''.
+
+The encryption of the plaintext uses '''[https://en.wikipedia.org/wiki/ChaCha20-Poly1305 ChaCha20Poly1305]''''''Why is ChaCha20Poly1305 chosen as the basis for packet encryption?''' It is a very widely used authenticated encryption cipher (used among others in SSH, TLS 1.2, TLS 1.3, [https://en.wikipedia.org/wiki/QUIC QUIC], Noise, and [https://www.wireguard.com/protocol/ WireGuard]; in the latter it is currently even the only supported cipher), with very good performance in general purpose software implementations. While AES-based ciphers (including the winners in the [https://competitions.cr.yp.to/caesar.html CAESAR] competition in non-lightweight categories) perform significantly better on systems with AES hardware acceleration, they are also significantly slower in pure software implementations. We choose to optimize for the weakest hardware., an [https://en.wikipedia.org/wiki/Authenticated_encryption authenticated encryption with associated data] (AEAD) cipher specified in [https://datatracker.ietf.org/doc/html/rfc8439 RFC 8439]. Every packet's plaintext is treated as a separate AEAD message, with a different nonce for each.
+
+The length must be dealt with specially, as it is needed to determine packet boundaries before the whole packet is received and authenticated. As we want a stream that is pseudorandom to a passive attacker, it still needs encryption. We use unauthenticated'''Why is the length encryption not separately authenticated?''' Informally, the relevant security goal we aim for is to hide the number of packets and their lengths (i.e., the packet boundaries) against a passive attacker that receives the bytestream without timing or fragmentation information. (A formal definition can be found for example in [https://himsen.github.io/pdf/thesis.pdf Hansen 2016 (Definition 22)] under the name "boundary hiding against chosen-plaintext attacks (BH-CPA)".) However, we do not aim to hide packet boundaries against active attackers because active attackers can always exploit the fact that the Bitcoin P2P protocol is largely query-response based: they can trickle the bytes on the stream one-by-one unmodified and observe when a response comes (see [https://himsen.github.io/pdf/thesis.pdf Hansen 2016 (Section 3.9)] for a in-depth discussion). With that in mind, we accept that an active (non-MitM) attacker is able to figure out some information about packet boundaries by flipping certain bits in the unauthenticated length field, and observing the other side disconnecting immediately or later. Thus, we choose to use unauthenticated encryption for the length data, which is sufficient to achieve boundary hiding against passive attackers, and saves 16 bytes of bandwidth per packet. '''ChaCha20''' encryption for this, with an independent key. Note that the plaintext length is still implicitly authenticated by the encryption of the plaintext, but this can only be verified after receiving the whole packet. This design is inspired by that of the ChaCha20Poly1305 cipher suite in [http://bxr.su/OpenBSD/usr.bin/ssh/PROTOCOL.chacha20poly1305 OpenSSH].'''How does packet encryption differ from the OpenSSH design?''' The differences are:
+* The length field is only 3 bytes instead of 4, as that is sufficient for our purposes.
+* Length encryption keeps drawing pseudorandom bytes from the same ChaCha20 cipher for multiple packets, rather than incrementing the nonce for every packet.
+* The Poly1305 authentication tag only covers the encrypted plaintext, and not the encrypted length field. This means that plaintext encryption uses the standard ChaCha20Poly1305 construction without any modifications, maximizing applicability of analysis and review of that cipher. The length encryption can be seen as a separate layer, using a separate key, and thus cannot affect any of the confidentiality or integrity guarantees of the plaintext encryption. On the other hand, this change w.r.t. OpenSSH also does not worsen any properties, as incorrect lengths will still trigger authentication failure for the overall packet (the plaintext length is implicitly authenticated by ChaCha20Poly1305).
+* A hash step is performed every 224'''How was the rekeying interval 224 chosen?''' Assuming a node sends only ping messages every 20 minutes (the timeout interval for post-[https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki BIP31] connections) on a connection, the node will transmit 224 packets in about 3.11 days. This means ''soft rekeying'' after a fixed number of packets automatically translates to an upper-bound of time interval for rekeying, while being much simpler to coordinate than an actual time-based rekeying regime. At the same time, doing it once every 224 messages is sufficiently infrequent that it has only negligible impact on performance. Furthermore, 224 times 3 bytes (the number of bytes consumed by each length encryption) is 672, which is a multiple of 64 minus 32. This means that at the end of 224 length encryptions, exactly 32 bytes of keystream data remain that can be used as next key. messages to rekey the encryption ciphers, in order to provide forward security.
+ Because only fixed-length chunks (3-byte length fields) are encrypted, we do not need to treat all length chunks as separate messages. Instead, a single cipher (with the same nonce) is used for multiple consecutive length fields. This avoids wasting 61 pseudorandom bytes per packet, and makes the cost of having a separate cipher for length encryption negligible.'''Is it acceptable to use a less standard construction for length encryption?''' The fact that multiple (non-overlapping) bytes generated by a single ChaCha20 cipher are used for the encryption of multiple consecutive length fields is uncommon. We feel the performance cost gained by this deviation is worth it (especially for small packets, which are very common in Bitcoin's P2P protocol), given the low guarantees that are feasible for length encryption in the first place, and the result is still sufficient to provide pseudorandomness from the view of passive attackers. For plaintext encryption, we independently use a very standard construction, as the stakes for confidentiality and integrity there are much higher.
+
+In order to provide forward security'''What value does forward security provide?''' Re-keying ensures [https://eprint.iacr.org/2001/035.pdf forward secrecy within a session], i.e., an attacker compromising the current session secrets cannot derive past encryption keys in the same session.'''Why have a cipher with forward secrecy but no periodical refresh of the ECDH key exchange?''' Our cipher ratchets encryption keys forward in order to protect messages encrypted under ''past'' encryption keys. In contrast, re-performing ECDH key exchange would protect messages encrypted under ''future'' encryption keys, i.e., it would re-establish security after the attacker had compromised one of the peers ''temporarily'' (e.g., the attacker obtains a memory dump). We do not believe protecting against that is a priority: an attacker that, for whatever reason, is capable of an attack that reveals encryption keys (or other session secrets) of a peer once is likely capable of performing the same attack again after peers have re-performed the ECDH key exchange. Thus, we do not believe the benefits of re-performing key exchange outweigh the additional complexity that comes with the necessary coordination between the peers. We note that the initiator could choose to close and re-open the entire connection to force a refresh of the ECDH key exchange, but that introduces other issues: a connection slot needs to be kept open at the responder side, it is not cryptographically guaranteed that really the same initiator will use it, and the observable TCP reset and handshake may create a detectable pattern., the encryption keys for both plaintext and length encryption are cycled every 224 messages, by switching to a new key that is generated by the key stream using the old key.
+
+==== Handshake: key exchange and version negotiation ====
+
+Next we specify the handshake of a connection in detail.
+
+As explained before, these messages are sent to set up the connection:
+
+
+
+===== Shared secret computation =====
+
+The peers derive their shared secret through X-only ECDH, hashed together with the exactly 64-byte public keys' encodings sent over the wire.
+
+
+def v2_ecdh(priv, ellswift_theirs, ellswift_ours, initiating):
+ ecdh_point_x32 = ellswift_ecdh_xonly(ellswift_theirs, priv)
+ if initiating:
+ # Initiating, place our public key encoding first.
+ return sha256_tagged("bip324_ellswift_xonly_ecdh", ellswift_ours + ellswift_theirs + ecdh_point_x32)
+ else:
+ # Responding, place their public key encoding first.
+ return sha256_tagged("bip324_ellswift_xonly_ecdh", ellswift_theirs + ellswift_ours + ecdh_point_x32)
+
+
+Here, sha256_tagged(tag, x) returns a tagged hash value SHA256(SHA256(tag) || SHA256(tag) || x) as in [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#specification BIP340].
+
+===== ElligatorSwift encoding of curve X coordinates =====
+
+The functions ellswift_create and ellswift_ecdh_xonly encapsulate the construction of ElligatorSwift-encoded public keys, and the computation of X-only ECDH with
+ElligatorSwift-encoded public keys.
+
+First we define a constant:
+* Let ''c = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852''.'''What is the ''c'' constant used in ''XSwiftEC''?''' The algorithm requires a constant ''√-3 (mod p)''; in other words, a number ''c'' such that ''-c2 mod p = 3''. There are two solutions to this equation, one which is itself a square modulo ''p'', and its negation. We choose the square one.
+
+To define the needed functions, we first introduce a helper function, matching the XSwiftEC function from the [https://eprint.iacr.org/2022/759.pdf SwiftEC] paper, instantiated for the secp256k1 curve, with minor modifications. It maps pairs of integers ''(u, t)'' (both in range ''0..p-1'') to valid X coordinates on the curve. Note that the specification here does not attempt to be constant time, as it does not operate on secret data. In what follows, we use the notation from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#specification BIP340].
+
+* ''XSwiftEC(u, t)'':
+** Alter the inputs to guarantee an X coordinate on the curve:'''Why do the inputs to the XSwiftEC algorithm need to be altered?''' This step deviates from the paper, which maps a negligibly small subset of inputs (around ''3/2256'') to the point at infinity. To avoid the need to deal with the case where a peer could craft encodings that intentionally trigger this edge case, we remap them to inputs that yield a valid X coordinate.
+*** If ''u mod p = 0'', let ''u = 1'' instead.
+*** If ''t mod p = 0'', let ''t = 1'' instead.
+*** If ''(u3 + t2 + 7) mod p = 0'', let ''t = 2t (mod p)'' instead.
+** Let ''X = (u3 + 7 - t2)/(2t) (mod p).'''''What does the division (/) sign in modular arithmetic refer to?''' Note that the division in these expressions corresponds to multiplication with the modular inverse modulo ''p'', i.e. ''a / b (mod p)'' with nonzero ''b'' is the unique solution ''x'' for which ''bx = a (mod p)''. It can be computed as ''abp-2 (mod p)'', but more efficient algorithms exist.
+** Let ''Y = (X + t)/(cu) (mod p)''.
+** For every ''x'' in ''{u + 4Y2, (-X/Y - u)/2, (X/Y - u)/2}'' (all ''mod p''; the order matters):
+*** If ''lift_x(x)'' succeeds, return ''x''. There is at least one such ''x''.
+
+To find encodings of a given X coordinate ''x'', we first need the inverse of ''XSwiftEC''. The function ''XSwiftECInv(x, u, case)'' either returns ''t'' such that ''XSwiftEC(u, t) = x'', or ''None''. The ''case'' variable is an integer in range ''0..7'', which selects which of the up to 8 valid such ''t'' values to return:
+
+* ''XSwiftECInv(x, u, case)'':
+** If ''case & 2 = 0'':
+*** If ''lift_x(-x - u)'' succeeds, return ''None''.
+*** Let ''v = x''.
+*** Let ''s = -(u3 + 7)/(u2 + uv + v2) (mod p)''.
+** Else (''case & 2 = 2''):
+*** Let ''s = x - u (mod p)''.
+*** If ''s = 0'', return ''None''.
+*** Let ''r'' be the square root of ''-s(4(u3 + 7) + 3u2s) (mod p).'''''How to compute a square root mod ''p''?''' Due to the structure of ''p'', a candidate for the square root of ''a'' mod ''p'' can be computed as ''x = a(p+1)/4 mod p''. If ''a'' is not a square mod ''p'', this formula returns the square root of ''-a mod p'' instead, so it is necessary to verify that ''x2 mod p = a''. If that is the case ''-x mod p'' is a solution too, but we define "the" square root to be equal to that expression (the square root will therefore always be a square itself, as ''(p+1)/4'' is even). This algorithm is a specialization of the [https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm Tonelli-Shanks algorithm]. Return ''None'' if it does not exist.
+*** If ''case & 1 = 1'' and ''r = 0'', return ''None''.
+*** Let ''v = (r/s - u)/2''.
+** Let ''w'' be the square root of ''s (mod p)''. Return ''None'' if it does not exist.
+** If ''case & 5 = 0'', return ''-w(u(1 - c)/2 + v)''.
+** If ''case & 5 = 1'', return ''w(u(1 + c)/2 + v)''.
+** If ''case & 5 = 4'', return ''w(u(1 - c)/2 + v)''.
+** If ''case & 5 = 5'', return ''-w(u(1 + c)/2 + v)''.
+
+The overall ''XElligatorSwift'' algorithm, matching the name used in the paper, then uses this inverse to randomly'''''Can the ElligatorSwift encoding be used to construct public key encodings that satisfy a certain structure (and not pseudorandom)?''' The algorithm chooses the first 32 bytes (i.e., the value ''u'') and then computes a corresponding ''t'' such that the mapping to the curve point holds. In general, picking ''u'' from a uniformly random distribution provides pseudorandomness. But we can also fix any of the 32 bytes in ''u'', and the algorithm will still find a corresponding ''t''. The fact that it is possible to fix the first 32 bytes, combined with the garbage bytes in the handshake, provides a limited but very simple method of parroting other protocols such as [https://tls13.xargs.org/ TLS 1.3], which can be deployed by one of the peers without explicit support from the other peer. More general methods of parroting, e.g., introduced by defining new protocol or a protocol upgrade, are not precluded. sample encodings of ''x'':
+
+* ''XElligatorSwift(x)'':
+** Loop:
+*** Let ''u'' be a random non-zero integer in range ''1..p-1'' inclusive.
+*** Let ''case'' be a random integer in range ''0..7'' inclusive.
+*** Compute ''t = XSwiftECInv(x, u, case)''.
+*** If ''t'' is not ''None'', return ''(u, t)''. Otherwise, restart loop.
+
+This is used to define the ellswift_create algorithm used in the previous section; it generates a random private key, along with a uniformly sampled 64-byte ElligatorSwift-encoded public key corresponding to it:
+
+* ''ellswift_create()'':
+** Generate a random private key ''priv'' in range ''1..p-1''.
+** Let ''P = priv⋅G'', the corresponding public key point to ''priv''.
+** Let ''(u, t) = XElligatorSwift(x(P))'', an encoding of ''x(P)''.
+** ''ellswift_pub = bytes(u) || bytes(t)'', its encoding as 64 bytes.
+** Return ''(priv, ellswift_pub)''.
+
+Finally the ellswift_ecdh_xonly algorithm is:
+
+* ''ellswift_ecdh_xonly(ellswift_theirs, priv)'':
+** Let ''u = int(ellswift_theirs[:32]) mod p''.
+** Let ''t = int(ellswift_theirs[32:]) mod p''.
+** Return ''bytes(x(priv⋅lift_x(XSwiftEC(u, t))))''.'''Does it matter which point ''lift_x'' maps to?''' Either point is valid, as they are negations of each other, and negations do not affect the output X coordinate.
+
+===== Keys and session ID derivation =====
+
+The authenticated encryption construction proposed here requires two 32-byte keys per communication direction. These (in addition to a session ID) are computed using HKDF'''Why use HKDF for deriving key material?''' The shared secret already involves a hash function to make sure the public key encodings contribute to it, which negates some of the need for HKDF already. We still use it as it is the standard mechanism for deriving many keys from a single secret, and its computational cost is low enough to be negligible compared to the rest of a connection setup. as specified in [https://tools.ietf.org/html/rfc5869 RFC 5869] with SHA256 as the hash function:
+
+
+def initialize_v2_transport(peer, ecdh_secret, initiating):
+ # Include NETWORK_MAGIC to ensure a connection between nodes on different networks will immediately fail
+ prk = HKDF_Extract(Hash=sha256, salt=b'bitcoin_v2_shared_secret' + NETWORK_MAGIC, ikm=ecdh_secret)
+
+ peer.session_id = HKDF_Expand(Hash=sha256, PRK=prk, info=b'session_id', L=32)
+
+ # Initialize the packet encryption ciphers.
+ initiator_L = HKDF_Expand(Hash=sha256, PRK=prk, info=b'initiator_L', L=32)
+ initiator_P = HKDF_Expand(Hash=sha256, PRK=prk, info=b'initiator_P', L=32)
+ responder_L = HKDF_Expand(Hash=sha256, PRK=prk, info=b'responder_L', L=32)
+ responder_P = HKDF_Expand(Hash=sha256, PRK=prk, info=b'responder_P', L=32)
+ garbage_terminators = HKDF_Expand(Hash=sha256, PRK=prk, info=b'garbage_terminators', L=32)
+ initiator_garbage_terminator = garbage_terminators[:16]
+ responder_garbage_terminator = garbage_terminators[16:]
+
+ if initiating:
+ peer.send_L = FSChaCha20(initiator_L)
+ peer.send_P = FSChaCha20Poly1305(initiator_P)
+ peer.send_garbage_terminator = initiator_garbage_terminator
+ peer.recv_L = FSChaCha20(responder_L)
+ peer.recv_P = FSChaCha20Poly1305(responder_P)
+ peer.recv_garbage_terminator = responder_garbage_terminator
+ else:
+ peer.send_L = FSChaCha20(responder_L)
+ peer.send_P = FSChaCha20Poly1305(responder_P)
+ peer.send_garbage_terminator = responder_garbage_terminator
+ peer.recv_L = FSChaCha20(initiator_L)
+ peer.recv_P = FSChaCha20Poly1305(initiator_P)
+ peer.recv_garbage_terminator = initiator_garbage_terminator
+
+ # To achieve forward secrecy we must wipe the key material used to initialize the ciphers:
+ memory_cleanse(ecdh_secret, prk, initiator_L, initiator_P, responder_L, responder_K)
+
+
+The session ID uniquely identifies the encrypted channel. v2 clients supporting this proposal may present the entire session ID (encoded as a hex string) to the node operator to allow for manual, out of band comparison with the peer node operator. Future transport versions may introduce optional authentication methods that compare the session ID as seen by the two endpoints in order to bind the encrypted channel to the authentication.
+
+===== Overall handshake pseudocode =====
+
+To establish a v2 encrypted connection, the initiator generates an ephemeral secp256k1 keypair and sends an unencrypted ElligatorSwift encoding of the public key to the responding peer followed by unencrypted pseudorandom bytes initiator_garbage of length garbage_len < 4096.
+
+
+
+The responder generates an ephemeral keypair for itself and derives the shared ECDH secret (using the first 64 received bytes) which enables it to instantiate the encrypted transport. It then sends 64 bytes of the unencrypted ElligatorSwift encoding of its own public key and its own responder_garbage also of length garbage_len < 4096. If the first 16 bytes received match the v1 prefix, the v1 protocol is used instead.
+
+
+
+Upon receiving the encoded responder public key, the initiator derives the shared ECDH secret and instantiates the encrypted transport. It then sends the derived 16-byte initiator_garbage_terminator, optionally followed by an arbitrary number of decoy packets. Afterwards, it receives the responder's garbage (delimited by the garbage terminator). The responder performs very similar steps but includes the earlier received prefix bytes in the public key. Both the initiator and the responder set the AAD of the first encrypted packet they send after the garbage terminator (i.e., either an optional decoy packet or the version packet) to the garbage they have just sent, not including the garbage terminator.
+
+
+def complete_handshake(peer, initiating, decoy_content_lengths=[]):
+ received_prefix = b'' if initiating else peer.received_prefix
+ ellswift_theirs = receive(peer, 64 - len(received_prefix))
+ if not initiating and ellswift_theirs[4:16] == V1_PREFIX[4:16]:
+ # Looks like a v1 peer from the wrong network.
+ disconnect(peer)
+ ecdh_secret = v2_ecdh(peer.privkey_ours, ellswift_theirs, peer.ellswift_ours,
+ initiating=initiating)
+ initialize_v2_transport(peer, ecdh_secret, initiating=True)
+ # Send garbage terminator
+ send(peer, peer.send_garbage_terminator)
+ # Optionally send decoy packets after garbage terminator.
+ aad = peer.sent_garbage
+ for decoy_content_len in decoy_content_lengths:
+ send(v2_enc_packet(peer, decoy_content_len * b'\x00', aad=aad))
+ aad = b''
+ # Send version packet.
+ send(v2_enc_packet(peer, TRANSPORT_VERSION, aad=aad))
+ # Skip garbage, until encountering garbage terminator.
+ received_garbage = recv(peer, 16)
+ for i in range(4096):
+ if received_garbage[-16:] == peer.recv_garbage_terminator:
+ # Receive, decode, and ignore version packet.
+ # This includes skipping decoys and authenticating the received garbage.
+ v2_receive_packet(peer, aad=received_garbage[:-16])
+ return
+ else:
+ received_garbage += recv(peer, 1)
+ # Garbage terminator was not seen after 4 KiB of garbage.
+ disconnect(peer)
+
+
+==== Packet encryption ====
+
+Lastly, we specify the packet encryption cipher in detail.
+
+===== Existing cryptographic primitives =====
+
+Packet encryption is built on two existing primitives:
+
+* '''ChaCha20Poly1305''' is specified as AEAD_CHACHA20_POLY1305 in [https://datatracker.ietf.org/doc/html/rfc8439#section-2.8 RFC 8439 section 2.8]. It is an authenticated encryption protocol with associated data (AEAD), taking a 256-bit key, 96-bit nonce, and an arbitrary-length byte array of associated authenticated data (AAD). Due to the built-in authentication tag, ciphertexts are 16 bytes longer than the corresponding plaintext. In what follows:
+** aead_chacha20_poly1305_encrypt(key, nonce, aad, plaintext) refers to a function that takes as input a 32-byte array ''key'', a 12-byte array ''nonce'', an arbitrary-length byte array ''aad'', and an arbitrary-length byte array ''plaintext'', and returns a byte array ''ciphertext'', 16 bytes longer than the plaintext.
+** aead_chacha20_poly1305_decrypt(key, nonce, aad, ciphertext) refers to a function that takes as input a 32-byte array ''key'', a 12-byte array ''nonce'', an arbitrary-length byte array ''aad'', and an arbitrary-length byte array ''ciphertext'', and returns either a byte array ''plaintext'' (16 bytes shorter than the ciphertext), or ''None'' in case the ciphertext was not a valid ChaCha20Poly1305 encryption of any plaintext with the specified ''key'', ''nonce'', and ''aad''.
+* The '''ChaCha20 Block Function''' is specified in [https://datatracker.ietf.org/doc/html/rfc8439#section-2.3 RFC 8439 section 2.3]. It is a pseudorandom function (PRF) taking a 256-bit key, 96-bit nonce, and 32-bit counter, and outputs 64 pseudorandom bytes. It is the underlying building block on which ChaCha20 (and ultimately, ChaCha20Poly1305) is built. In what follows:
+** chacha20_block(key, nonce, count) refers to a function that takes as input a 32-byte array ''key'', a 12-byte array ''nonce'', and an integer ''count'' in range ''0..232-1'', and returns a byte array of length 64.
+
+These will be used for plaintext encryption and length encryption, respectively.
+
+===== Rekeying wrappers: FSChaCha20Poly1305 and FSChaCha20 =====
+
+To provide re-keying every 224 packets, we specify two wrappers.
+
+The first is '''FSChaCha20Poly1305''', which represents a ChaCha20Poly1305 AEAD, which automatically changes the nonce after every message, and rekeys every 224 messages by encrypting 32 zero bytes'''Why is rekeying implemented in terms of an invocation of the AEAD?''' This means the FSChaCha20Poly1305 wrapper can be thought of as a pure layer around the ChaCha20Poly1305 AEAD. Actual implementations can take advantage of the fact that this formulation is equivalent to using byte 64 through 95 of the keystream output of the underlying ChaCha20 cipher as new key, avoiding the need for Poly1305 in the process., and using the first 32 bytes of the result. Each message will be used for one packet. Note that in our protocol, any FSChaCha20Poly1305 instance is always either exclusively encryption or exclusively decryption, as separate instances are used for each direction of the protocol. The nonce used for a message is composed of the 32-bit little-endian encoding of the number of messages with the current key, followed by the 64-bit little-endian encoding of the number of rekeyings performed. For rekeying, the first 32-bit integer is set to ''0xffffffff''.
+
+
+
+The second is '''FSChaCha20''', a (single) stream cipher which is used for the lengths of all packets. Encryption and decryption are identical here, so a single function crypt is exposed. It XORs the input with bytes generated using the ChaCha20 block function, rekeying every 224 chunks using the next 32 bytes of the block function output as new key. A ''chunk'' refers here to a single invocation of crypt. As explained before, the same cipher is used for 224 consecutive chunks, to avoid wasting cipher output. The nonce used for these batches of 224 chunks is composed of 4 zero bytes followed by the 64-bit little-endian encoding of the number of rekeyings performed. The block counter is reset to 0 after every rekeying.
+
+
+
+===== Overall packet encryption and decryption pseudocode =====
+
+Encryption and decryption of packets then follow by composing the ciphers from the previous section as building blocks.
+
+
+CHACHA20POLY1305_EXPANSION = 16
+
+def v2_receive_packet(peer, aad=b''):
+ while True:
+ enc_contents_len = receive(peer, LENGTH_FIELD_LEN)
+ contents_len = int.from_bytes(peer.recv_L.crypt(enc_contents_len), 'little')
+ aead_ciphertext = receive(peer, HEADER_LEN + contents_len + CHACHA20POLY1305_EXPANSION)
+ plaintext = peer.recv_P.decrypt(aad, aead_ciphertext)
+ if plaintext is None:
+ disconnect(peer)
+ break
+ # Only the first packet is expected to have non-empty AAD.
+ aad = b''
+ header = plaintext[:HEADER_LEN]
+ if not (header[0] & (1 << IGNORE_BIT_POS)):
+ return plaintext[HEADER_LEN:]
+
+
+==== Performance ====
+
+Each v1 P2P message uses a double-SHA256 checksum truncated to 4 bytes. Roughly the same amount of computation power is required for encrypting and authenticating a v2 P2P message as proposed.
+
+=== Application layer specification ===
+==== v2 Bitcoin P2P message structure ====
+v2 Bitcoin P2P transport layer packets use the encrypted message structure shown above. An unencrypted application layer '''contents''' is composed of:
+
+{|class="wikitable"
+! Field !! Size in bytes !! Comments
+|-
+| message_type || 1 or 13 || either a one byte ID in range ''1..255'' or b'\x00' followed by a 12-byte ASCII message type (as in the v1 P2P protocol)
+|-
+| message_payload || message_length || message payload
+|}
+
+If the first byte of message_type is b'\x00', the following 12 bytes are interpreted as an ASCII message type (as in the v1 P2P protocol), trailing padded with b'\x00' as necessary. If the first byte of message_type is in the range ''1..255'', it is interpreted as a message type ID. This structure results in smaller messages than the v1 protocol, as most messages sent/received will have a message type ID. We recommend reserving 1-byte type IDs for message types that are sent more than once per direction per connection.'''How do the lengths between v1 and v2 compare?''' For messages that use the 1-byte short message type ID, v2 packets use 3 bytes less per message than v1.'''Why not allow variable length long message type IDs?''' Allowing for variable length long IDs reduces the available 1-byte ID space by 12 (to encode the length itself) and incentivizes less descriptive message types. In addition, limiting message types to fixed lengths of 1 or 13 hampers traffic analysis.
+
+The following table lists currently defined message type IDs:
+
+{| class="wikitable"
+|-
+!
+!0
+!1
+!2
+!3
+|-
+!+0
+|(12 bytes follow)||ADDR||BLOCK||BLOCKTXN
+|-
+!+4
+|CMPCTBLOCK||FEEFILTER||FILTERADD||FILTERCLEAR
+|-
+!+8
+|FILTERLOAD||GETBLOCKS||GETBLOCKTXN||GETDATA
+|-
+!+12
+|GETHEADERS||HEADERS||INV||MEMPOOL
+|-
+!+16
+|MERKLEBLOCK||NOTFOUND||PING||PONG
+|-
+!+20
+|SENDCMPCT||TX||GETCFILTERS||CFILTER
+|-
+!+24
+|GETCFHEADERS||CFHEADERS||GETCFCHECKPT||CFCHECKPT
+|-
+!+28
+|ADDRV2
+|-
+!≥29
+|| colspan="4" | (undefined)
+|}
+
+
+Additional message types may be added separately after BIP finalization.
+
+=== Signaling specification ===
+==== Signaling v2 support ====
+Peers supporting the v2 transport protocol signal support by advertising the NODE_P2P_V2 = (1 << 11) service flag in addr relay. If met with immediate disconnection when establishing a v2 connection, clients implementing this proposal are encouraged to retry connecting using the v1 protocol.'''Why are v2 clients met with immediate disconnection encouraged to retry with a v1 connection?''' Service flags propagated through untrusted intermediaries using ADDR and ADDRV2 P2P messages and are OR'ed when received from multiple sources. An untrusted intermediary could falsely advertise a potential peer as supportive of v2 connections. Connection downgrades to v1 mitigate the risk of a network participant being blackholed via false advertising.
+
+
+== Test Vectors ==
+
+For development and testing purposes, we provide a collection of test vectors in CSV format, and a naive, highly inefficient, [[bip-0324/reference.py|reference implementation]] of the relevant algorithms. This code is for demonstration purposes only:
+* [[bip-0324/ellswift_decode_test_vectors.csv|XElligatorSwift decoding vectors]] provide examples of ElligatorSwift-encoded public keys, and the X coordinate they map to.
+* [[bip-0324/xswiftec_inv_test_vectors.csv|XSwiftECInv vectors]] provide examples of ''(u, x)'' pairs, and the various ''t'' values that ''xswiftec_inv'' maps them to.
+* [[bip-0324/packet_encoding_test_vectors.csv|Packet encoding vectors]] illustrate the lifecycle of the authenticated encryption scheme proposed in this document.
+
+== Rationale and References ==
+
+
+== Acknowledgements ==
+Thanks to everyone (last name order) that helped invent and develop the ideas in this proposal:
+
+* Matt Corallo
+* Lloyd Fournier
+* Gregory Maxwell
+* Anthony Towns
diff --git a/bip-0324/ellswift_decode_test_vectors.csv b/bip-0324/ellswift_decode_test_vectors.csv
new file mode 100644
index 0000000000..1bab96b721
--- /dev/null
+++ b/bip-0324/ellswift_decode_test_vectors.csv
@@ -0,0 +1,77 @@
+ellswift,x,comment
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,edd1fd3e327ce90cc7a3542614289aee9682003e9cf7dcc9cf2ca9743be5aa0c,u%p=0;t%p=0;valid_x(x2)
+000000000000000000000000000000000000000000000000000000000000000001d3475bf7655b0fb2d852921035b2ef607f49069b97454e6795251062741771,b5da00b73cd6560520e7c364086e7cd23a34bf60d0e707be9fc34d4cd5fdfa2c,u%p=0;valid_x(x1)
+000000000000000000000000000000000000000000000000000000000000000082277c4a71f9d22e66ece523f8fa08741a7c0912c66a69ce68514bfd3515b49f,f482f2e241753ad0fb89150d8491dc1e34ff0b8acfbb442cfe999e2e5e6fd1d2,u%p=0;valid_x(x3);valid_x(x2);valid_x(x1)
+00000000000000000000000000000000000000000000000000000000000000008421cc930e77c9f514b6915c3dbe2a94c6d8f690b5b739864ba6789fb8a55dd0,9f59c40275f5085a006f05dae77eb98c6fd0db1ab4a72ac47eae90a4fc9e57e0,u%p=0;valid_x(x2)
+0000000000000000000000000000000000000000000000000000000000000000bde70df51939b94c9c24979fa7dd04ebd9b3572da7802290438af2a681895441,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9fffffd6b,u%p=0;(u'^3-t'^2+7)%p=0;valid_x(x3)
+0000000000000000000000000000000000000000000000000000000000000000d19c182d2759cd99824228d94799f8c6557c38a1c0d6779b9d4b729c6f1ccc42,70720db7e238d04121f5b1afd8cc5ad9d18944c6bdc94881f502b7a3af3aecff,u%p=0;valid_x(x3)
+0000000000000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,edd1fd3e327ce90cc7a3542614289aee9682003e9cf7dcc9cf2ca9743be5aa0c,u%p=0;t%p=0;valid_x(x2);t>=p
+0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff2664bbd5,50873db31badcc71890e4f67753a65757f97aaa7dd5f1e82b753ace32219064b,u%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p
+0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7028de7d,1eea9cc59cfcf2fa151ac6c274eea4110feb4f7b68c5965732e9992e976ef68e,u%p=0;valid_x(x2);t>=p
+0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffcbcfb7e7,12303941aedc208880735b1f1795c8e55be520ea93e103357b5d2adb7ed59b8e,u%p=0;valid_x(x1);t>=p
+0000000000000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff3113ad9,7eed6b70e7b0767c7d7feac04e57aa2a12fef5e0f48f878fcbb88b3b6b5e0783,u%p=0;valid_x(x3);t>=p
+0a2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f8530000000000000000000000000000000000000000000000000000000000000000,532167c11200b08c0e84a354e74dcc40f8b25f4fe686e30869526366278a0688,t%p=0;(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1)
+0a2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f853fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,532167c11200b08c0e84a354e74dcc40f8b25f4fe686e30869526366278a0688,t%p=0;(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p
+0ffde9ca81d751e9cdaffc1a50779245320b28996dbaf32f822f20117c22fbd6c74d99efceaa550f1ad1c0f43f46e7ff1ee3bd0162b7bf55f2965da9c3450646,74e880b3ffd18fe3cddf7902522551ddf97fa4a35a3cfda8197f947081a57b8f,valid_x(x3)
+0ffde9ca81d751e9cdaffc1a50779245320b28996dbaf32f822f20117c22fbd6ffffffffffffffffffffffffffffffffffffffffffffffffffffffff156ca896,377b643fce2271f64e5c8101566107c1be4980745091783804f654781ac9217c,valid_x(x2);t>=p
+123658444f32be8f02ea2034afa7ef4bbe8adc918ceb49b12773b625f490b368ffffffffffffffffffffffffffffffffffffffffffffffffffffffff8dc5fe11,ed16d65cf3a9538fcb2c139f1ecbc143ee14827120cbc2659e667256800b8142,(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p
+146f92464d15d36e35382bd3ca5b0f976c95cb08acdcf2d5b3570617990839d7ffffffffffffffffffffffffffffffffffffffffffffffffffffffff3145e93b,0d5cd840427f941f65193079ab8e2e83024ef2ee7ca558d88879ffd879fb6657,(u'^3+t'^2+7)%p=0;valid_x(x3);t>=p
+15fdf5cf09c90759add2272d574d2bb5fe1429f9f3c14c65e3194bf61b82aa73ffffffffffffffffffffffffffffffffffffffffffffffffffffffff04cfd906,16d0e43946aec93f62d57eb8cde68951af136cf4b307938dd1447411e07bffe1,(u'^3+t'^2+7)%p=0;valid_x(x2);t>=p
+1f67edf779a8a649d6def60035f2fa22d022dd359079a1a144073d84f19b92d50000000000000000000000000000000000000000000000000000000000000000,025661f9aba9d15c3118456bbe980e3e1b8ba2e047c737a4eb48a040bb566f6c,t%p=0;valid_x(x2)
+1f67edf779a8a649d6def60035f2fa22d022dd359079a1a144073d84f19b92d5fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,025661f9aba9d15c3118456bbe980e3e1b8ba2e047c737a4eb48a040bb566f6c,t%p=0;valid_x(x2);t>=p
+1fe1e5ef3fceb5c135ab7741333ce5a6e80d68167653f6b2b24bcbcfaaaff507fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,98bec3b2a351fa96cfd191c1778351931b9e9ba9ad1149f6d9eadca80981b801,t%p=0;(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p
+4056a34a210eec7892e8820675c860099f857b26aad85470ee6d3cf1304a9dcf375e70374271f20b13c9986ed7d3c17799698cfc435dbed3a9f34b38c823c2b4,868aac2003b29dbcad1a3e803855e078a89d16543ac64392d122417298cec76e,(u'^3-t'^2+7)%p=0;valid_x(x3)
+4197ec3723c654cfdd32ab075506648b2ff5070362d01a4fff14b336b78f963fffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3ab1e95,ba5a6314502a8952b8f456e085928105f665377a8ce27726a5b0eb7ec1ac0286,(u'^3+t'^2+7)%p=0;valid_x(x1);t>=p
+47eb3e208fedcdf8234c9421e9cd9a7ae873bfbdbc393723d1ba1e1e6a8e6b24ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7cd12cb1,d192d52007e541c9807006ed0468df77fd214af0a795fe119359666fdcf08f7c,(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p
+5eb9696a2336fe2c3c666b02c755db4c0cfd62825c7b589a7b7bb442e141c1d693413f0052d49e64abec6d5831d66c43612830a17df1fe4383db896468100221,ef6e1da6d6c7627e80f7a7234cb08a022c1ee1cf29e4d0f9642ae924cef9eb38,(u'^3+t'^2+7)%p=0;valid_x(x1)
+7bf96b7b6da15d3476a2b195934b690a3a3de3e8ab8474856863b0de3af90b0e0000000000000000000000000000000000000000000000000000000000000000,50851dfc9f418c314a437295b24feeea27af3d0cd2308348fda6e21c463e46ff,t%p=0;valid_x(x1)
+7bf96b7b6da15d3476a2b195934b690a3a3de3e8ab8474856863b0de3af90b0efffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,50851dfc9f418c314a437295b24feeea27af3d0cd2308348fda6e21c463e46ff,t%p=0;valid_x(x1);t>=p
+851b1ca94549371c4f1f7187321d39bf51c6b7fb61f7cbf027c9da62021b7a65fc54c96837fb22b362eda63ec52ec83d81bedd160c11b22d965d9f4a6d64d251,3e731051e12d33237eb324f2aa5b16bb868eb49a1aa1fadc19b6e8761b5a5f7b,(u'^3+t'^2+7)%p=0;valid_x(x2)
+943c2f775108b737fe65a9531e19f2fc2a197f5603e3a2881d1d83e4008f91250000000000000000000000000000000000000000000000000000000000000000,311c61f0ab2f32b7b1f0223fa72f0a78752b8146e46107f8876dd9c4f92b2942,t%p=0;valid_x(x3);valid_x(x2);valid_x(x1)
+943c2f775108b737fe65a9531e19f2fc2a197f5603e3a2881d1d83e4008f9125fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,311c61f0ab2f32b7b1f0223fa72f0a78752b8146e46107f8876dd9c4f92b2942,t%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p
+a0f18492183e61e8063e573606591421b06bc3513631578a73a39c1c3306239f2f32904f0d2a33ecca8a5451705bb537d3bf44e071226025cdbfd249fe0f7ad6,97a09cf1a2eae7c494df3c6f8a9445bfb8c09d60832f9b0b9d5eabe25fbd14b9,valid_x(x1)
+a1ed0a0bd79d8a23cfe4ec5fef5ba5cccfd844e4ff5cb4b0f2e71627341f1c5b17c499249e0ac08d5d11ea1c2c8ca7001616559a7994eadec9ca10fb4b8516dc,65a89640744192cdac64b2d21ddf989cdac7500725b645bef8e2200ae39691f2,valid_x(x2)
+ba94594a432721aa3580b84c161d0d134bc354b690404d7cd4ec57c16d3fbe98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffea507dd7,5e0d76564aae92cb347e01a62afd389a9aa401c76c8dd227543dc9cd0efe685a,valid_x(x1);t>=p
+bcaf7219f2f6fbf55fe5e062dce0e48c18f68103f10b8198e974c184750e1be3932016cbf69c4471bd1f656c6a107f1973de4af7086db897277060e25677f19a,2d97f96cac882dfe73dc44db6ce0f1d31d6241358dd5d74eb3d3b50003d24c2b,valid_x(x3);valid_x(x2);valid_x(x1)
+bcaf7219f2f6fbf55fe5e062dce0e48c18f68103f10b8198e974c184750e1be3ffffffffffffffffffffffffffffffffffffffffffffffffffffffff6507d09a,e7008afe6e8cbd5055df120bd748757c686dadb41cce75e4addcc5e02ec02b44,valid_x(x3);valid_x(x2);valid_x(x1);t>=p
+c5981bae27fd84401c72a155e5707fbb811b2b620645d1028ea270cbe0ee225d4b62aa4dca6506c1acdbecc0552569b4b21436a5692e25d90d3bc2eb7ce24078,948b40e7181713bc018ec1702d3d054d15746c59a7020730dd13ecf985a010d7,(u'^3+t'^2+7)%p=0;valid_x(x3)
+c894ce48bfec433014b931a6ad4226d7dbd8eaa7b6e3faa8d0ef94052bcf8cff336eeb3919e2b4efb746c7f71bbca7e9383230fbbc48ffafe77e8bcc69542471,f1c91acdc2525330f9b53158434a4d43a1c547cff29f15506f5da4eb4fe8fa5a,(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1)
+cbb0deab125754f1fdb2038b0434ed9cb3fb53ab735391129994a535d925f6730000000000000000000000000000000000000000000000000000000000000000,872d81ed8831d9998b67cb7105243edbf86c10edfebb786c110b02d07b2e67cd,t%p=0;(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1)
+d917b786dac35670c330c9c5ae5971dfb495c8ae523ed97ee2420117b171f41effffffffffffffffffffffffffffffffffffffffffffffffffffffff2001f6f6,e45b71e110b831f2bdad8651994526e58393fde4328b1ec04d59897142584691,valid_x(x3);t>=p
+e28bd8f5929b467eb70e04332374ffb7e7180218ad16eaa46b7161aa679eb4260000000000000000000000000000000000000000000000000000000000000000,66b8c980a75c72e598d383a35a62879f844242ad1e73ff12edaa59f4e58632b5,t%p=0;valid_x(x3)
+e28bd8f5929b467eb70e04332374ffb7e7180218ad16eaa46b7161aa679eb426fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,66b8c980a75c72e598d383a35a62879f844242ad1e73ff12edaa59f4e58632b5,t%p=0;valid_x(x3);t>=p
+e7ee5814c1706bf8a89396a9b032bc014c2cac9c121127dbf6c99278f8bb53d1dfd04dbcda8e352466b6fcd5f2dea3e17d5e133115886eda20db8a12b54de71b,e842c6e3529b234270a5e97744edc34a04d7ba94e44b6d2523c9cf0195730a50,(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1)
+f292e46825f9225ad23dc057c1d91c4f57fcb1386f29ef10481cb1d22518593fffffffffffffffffffffffffffffffffffffffffffffffffffffffff7011c989,3cea2c53b8b0170166ac7da67194694adacc84d56389225e330134dab85a4d55,(u'^3-t'^2+7)%p=0;valid_x(x3);t>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000000000000000000000000000000000000000000000000000000000000000,edd1fd3e327ce90cc7a3542614289aee9682003e9cf7dcc9cf2ca9743be5aa0c,u%p=0;t%p=0;valid_x(x2);u>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f01d3475bf7655b0fb2d852921035b2ef607f49069b97454e6795251062741771,b5da00b73cd6560520e7c364086e7cd23a34bf60d0e707be9fc34d4cd5fdfa2c,u%p=0;valid_x(x1);u>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f4218f20ae6c646b363db68605822fb14264ca8d2587fdd6fbc750d587e76a7ee,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9fffffd6b,u%p=0;(u'^3-t'^2+7)%p=0;valid_x(x3);u>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f82277c4a71f9d22e66ece523f8fa08741a7c0912c66a69ce68514bfd3515b49f,f482f2e241753ad0fb89150d8491dc1e34ff0b8acfbb442cfe999e2e5e6fd1d2,u%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f8421cc930e77c9f514b6915c3dbe2a94c6d8f690b5b739864ba6789fb8a55dd0,9f59c40275f5085a006f05dae77eb98c6fd0db1ab4a72ac47eae90a4fc9e57e0,u%p=0;valid_x(x2);u>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fd19c182d2759cd99824228d94799f8c6557c38a1c0d6779b9d4b729c6f1ccc42,70720db7e238d04121f5b1afd8cc5ad9d18944c6bdc94881f502b7a3af3aecff,u%p=0;valid_x(x3);u>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,edd1fd3e327ce90cc7a3542614289aee9682003e9cf7dcc9cf2ca9743be5aa0c,u%p=0;t%p=0;valid_x(x2);u>=p;t>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fffffffffffffffffffffffffffffffffffffffffffffffffffffffff2664bbd5,50873db31badcc71890e4f67753a65757f97aaa7dd5f1e82b753ace32219064b,u%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p;t>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fffffffffffffffffffffffffffffffffffffffffffffffffffffffff7028de7d,1eea9cc59cfcf2fa151ac6c274eea4110feb4f7b68c5965732e9992e976ef68e,u%p=0;valid_x(x2);u>=p;t>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fffffffffffffffffffffffffffffffffffffffffffffffffffffffffcbcfb7e7,12303941aedc208880735b1f1795c8e55be520ea93e103357b5d2adb7ed59b8e,u%p=0;valid_x(x1);u>=p;t>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3113ad9,7eed6b70e7b0767c7d7feac04e57aa2a12fef5e0f48f878fcbb88b3b6b5e0783,u%p=0;valid_x(x3);u>=p;t>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff13cea4a70000000000000000000000000000000000000000000000000000000000000000,649984435b62b4a25d40c6133e8d9ab8c53d4b059ee8a154a3be0fcf4e892edb,t%p=0;valid_x(x1);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff13cea4a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,649984435b62b4a25d40c6133e8d9ab8c53d4b059ee8a154a3be0fcf4e892edb,t%p=0;valid_x(x1);u>=p;t>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff15028c590063f64d5a7f1c14915cd61eac886ab295bebd91992504cf77edb028bdd6267f,3fde5713f8282eead7d39d4201f44a7c85a5ac8a0681f35e54085c6b69543374,(u'^3+t'^2+7)%p=0;valid_x(x2);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff2715de860000000000000000000000000000000000000000000000000000000000000000,3524f77fa3a6eb4389c3cb5d27f1f91462086429cd6c0cb0df43ea8f1e7b3fb4,t%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff2715de86fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,3524f77fa3a6eb4389c3cb5d27f1f91462086429cd6c0cb0df43ea8f1e7b3fb4,t%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p;t>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff2c2c5709e7156c417717f2feab147141ec3da19fb759575cc6e37b2ea5ac9309f26f0f66,d2469ab3e04acbb21c65a1809f39caafe7a77c13d10f9dd38f391c01dc499c52,(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff3a08cc1efffffffffffffffffffffffffffffffffffffffffffffffffffffffff760e9f0,38e2a5ce6a93e795e16d2c398bc99f0369202ce21e8f09d56777b40fc512bccc,valid_x(x3);u>=p;t>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e91257d932016cbf69c4471bd1f656c6a107f1973de4af7086db897277060e25677f19a,864b3dc902c376709c10a93ad4bbe29fce0012f3dc8672c6286bba28d7d6d6fc,valid_x(x3);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff795d6c1c322cadf599dbb86481522b3cc55f15a67932db2afa0111d9ed6981bcd124bf44,766dfe4a700d9bee288b903ad58870e3d4fe2f0ef780bcac5c823f320d9a9bef,(u'^3+t'^2+7)%p=0;valid_x(x1);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff8e426f0392389078c12b1a89e9542f0593bc96b6bfde8224f8654ef5d5cda935a3582194,faec7bc1987b63233fbc5f956edbf37d54404e7461c58ab8631bc68e451a0478,valid_x(x1);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff91192139ffffffffffffffffffffffffffffffffffffffffffffffffffffffff45f0f1eb,ec29a50bae138dbf7d8e24825006bb5fc1a2cc1243ba335bc6116fb9e498ec1f,valid_x(x2);u>=p;t>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff98eb9ab76e84499c483b3bf06214abfe065dddf43b8601de596d63b9e45a166a580541fe,1e0ff2dee9b09b136292a9e910f0d6ac3e552a644bba39e64e9dd3e3bbd3d4d4,(u'^3-t'^2+7)%p=0;valid_x(x3);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9b77b7f2c74d99efceaa550f1ad1c0f43f46e7ff1ee3bd0162b7bf55f2965da9c3450646,8b7dd5c3edba9ee97b70eff438f22dca9849c8254a2f3345a0a572ffeaae0928,valid_x(x2);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9b77b7f2ffffffffffffffffffffffffffffffffffffffffffffffffffffffff156ca896,0881950c8f51d6b9a6387465d5f12609ef1bb25412a08a74cb2dfb200c74bfbf,valid_x(x3);valid_x(x2);valid_x(x1);u>=p;t>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffa2f5cd838816c16c4fe8a1661d606fdb13cf9af04b979a2e159a09409ebc8645d58fde02,2f083207b9fd9b550063c31cd62b8746bd543bdc5bbf10e3a35563e927f440c8,(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffb13f75c00000000000000000000000000000000000000000000000000000000000000000,4f51e0be078e0cddab2742156adba7e7a148e73157072fd618cd60942b146bd0,t%p=0;valid_x(x3);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffb13f75c0fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,4f51e0be078e0cddab2742156adba7e7a148e73157072fd618cd60942b146bd0,t%p=0;valid_x(x3);u>=p;t>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7bc1f8d0000000000000000000000000000000000000000000000000000000000000000,16c2ccb54352ff4bd794f6efd613c72197ab7082da5b563bdf9cb3edaafe74c2,t%p=0;valid_x(x2);u>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7bc1f8dfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,16c2ccb54352ff4bd794f6efd613c72197ab7082da5b563bdf9cb3edaafe74c2,t%p=0;valid_x(x2);u>=p;t>=p
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffef64d162750546ce42b0431361e52d4f5242d8f24f33e6b1f99b591647cbc808f462af51,d41244d11ca4f65240687759f95ca9efbab767ededb38fd18c36e18cd3b6f6a9,(u'^3+t'^2+7)%p=0;valid_x(x3);u>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0e5be52372dd6e894b2a326fc3605a6e8f3c69c710bf27d630dfe2004988b78eb6eab36,64bf84dd5e03670fdb24c0f5d3c2c365736f51db6c92d95010716ad2d36134c8,valid_x(x3);valid_x(x2);valid_x(x1);u>=p
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffefbb982fffffffffffffffffffffffffffffffffffffffffffffffffffffffff6d6db1f,1c92ccdfcf4ac550c28db57cff0c8515cb26936c786584a70114008d6c33a34b,valid_x(x1);u>=p;t>=p
diff --git a/bip-0324/garbage_terminator.png b/bip-0324/garbage_terminator.png
new file mode 100644
index 0000000000..536763e4a9
Binary files /dev/null and b/bip-0324/garbage_terminator.png differ
diff --git a/bip-0324/gen_test_vectors.py b/bip-0324/gen_test_vectors.py
new file mode 100644
index 0000000000..05b30a8335
--- /dev/null
+++ b/bip-0324/gen_test_vectors.py
@@ -0,0 +1,418 @@
+"""Generate the BIP-0324 test vectors."""
+
+import csv
+import hashlib
+import os
+import sys
+from reference import (
+ FE,
+ GE,
+ MINUS_3_SQRT,
+ hkdf_sha256,
+ SECP256K1_G,
+ ellswift_decode,
+ ellswift_ecdh_xonly,
+ xswiftec_inv,
+ xswiftec,
+ v2_ecdh,
+ initialize_v2_transport,
+ v2_enc_packet
+)
+
+FILENAME_PACKET_TEST = os.path.join(sys.path[0], 'packet_encoding_test_vectors.csv')
+FILENAME_XSWIFTEC_INV_TEST = os.path.join(sys.path[0], 'xswiftec_inv_test_vectors.csv')
+FILENAME_ELLSWIFT_DECODE_TEST = os.path.join(sys.path[0], 'ellswift_decode_test_vectors.csv')
+
+def xswiftec_flagged(u, t, simplified=False):
+ """A variant of xswiftec which also returns 'flags', describing conditions encountered."""
+ flags = []
+ if u == 0:
+ flags.append("u%p=0")
+ u = FE(1)
+ if t == 0:
+ flags.append("t%p=0")
+ t = FE(1)
+ if u**3 + t**2 + 7 == 0:
+ flags.append("(u'^3+t'^2+7)%p=0")
+ t = 2 * t
+ X = (u**3 + 7 - t**2) / (2 * t)
+ Y = (X + t) / (MINUS_3_SQRT * u)
+ if X == 0:
+ if not simplified:
+ flags.append("(u'^3-t'^2+7)%p=0")
+ x3 = u + 4 * Y**2
+ if GE.is_valid_x(x3):
+ flags.append("valid_x(x3)")
+ x2 = (-X / Y - u) / 2
+ if GE.is_valid_x(x2):
+ flags.append("valid_x(x2)")
+ x1 = (X / Y - u) / 2
+ if GE.is_valid_x(x1):
+ flags.append("valid_x(x1)")
+ for x in (x3, x2, x1):
+ if GE.is_valid_x(x):
+ break
+ return x, flags
+
+
+def ellswift_create_deterministic(seed, features):
+ """This is a variant of ellswift_create which doesn't use randomness.
+
+ features is an integer selecting some properties of the result:
+ - (f & 3) == 0: only x1 is valid on decoding (see xswiftec{_flagged})
+ - (f & 3) == 1: only x2 is valid on decoding
+ - (f & 3) == 2: only x3 is valid on decoding
+ - (f & 3) == 3: x1,x2,x3 are all valid on decoding
+ - (f & 4) == 4: u >= p
+ - (f & 8) == 8: u mod n == 0
+
+ Returns privkey, ellswift
+ """
+
+ cnt = 0
+ while True:
+ sec = hkdf_sha256(32, seed, (cnt).to_bytes(4, 'little'), b"sec")
+ xval = (int.from_bytes(sec, 'big') * SECP256K1_G).x
+ cnt += 1
+ if features & 8:
+ u = 0
+ if features & 4:
+ u += FE.SIZE
+ else:
+ udat = hkdf_sha256(64, seed, (cnt).to_bytes(4, 'little'), b"u")
+ if features & 4:
+ u = FE.SIZE + 1 + int.from_bytes(udat, 'big') % (2**256 - FE.SIZE - 1)
+ else:
+ u = 1 + int.from_bytes(udat, 'big') % (FE.SIZE - 1)
+ case = hkdf_sha256(1, seed, (cnt).to_bytes(4, 'little'), b"case")[0] & 7
+ coru = FE(u) + ((features & 8) == 8)
+ t = xswiftec_inv(xval, coru, case)
+ if t is None:
+ continue
+ assert xswiftec(FE(u), t) == xval
+ x2, flags = xswiftec_flagged(FE(u), t)
+ assert x2 == xval
+ have_x1 = "valid_x(x1)" in flags
+ have_x2 = "valid_x(x2)" in flags
+ have_x3 = "valid_x(x3)" in flags
+ if (features & 4) == 0 and not (have_x1 and not have_x2 and not have_x3):
+ continue
+ if (features & 4) == 1 and not (not have_x1 and have_x2 and not have_x3):
+ continue
+ if (features & 4) == 2 and not (not have_x1 and not have_x2 and have_x3):
+ continue
+ if (features & 4) == 3 and not (have_x1 and have_x2 and have_x3):
+ continue
+ return sec, u.to_bytes(32, 'big') + t.to_bytes()
+
+def ellswift_decode_flagged(ellswift, simplified=False):
+ """Decode a 64-byte ElligatorSwift encoded coordinate, returning byte array + flag string."""
+ uv = int.from_bytes(ellswift[:32], 'big')
+ tv = int.from_bytes(ellswift[32:], 'big')
+ x, flags = xswiftec_flagged(FE(uv), FE(tv))
+ if not simplified:
+ if uv >= FE.SIZE:
+ flags.append("u>=p")
+ if tv >= FE.SIZE:
+ flags.append("t>=p")
+ return int(x).to_bytes(32, 'big'), ";".join(flags)
+
+def random_fe_int(_, seed, i, p):
+ """Function to use in tuple_expand, generating a random integer in 0..p-1."""
+ rng_out = hkdf_sha256(64, seed, i.to_bytes(4, 'little'), b"v%i_fe" % p)
+ return int.from_bytes(rng_out, 'big') % FE.SIZE
+
+def random_fe_int_high(_, seed, i, p):
+ """Function to use in tuple_expand, generating a random integer in p..2^256-1."""
+ rng_out = hkdf_sha256(64, seed, i.to_bytes(4, 'little'), b"v%i_fe_high" % p)
+ return FE.SIZE + int.from_bytes(rng_out, 'big') % (2**256 - FE.SIZE)
+
+def fn_of(p_in, fn):
+ """Function to use in tuple_expand, to pick one variable in function of another."""
+ def inner(vs, _seed, _i, p):
+ assert p != p_in
+ if isinstance(vs[p_in], int):
+ return fn(vs[p_in])
+ return None
+ return inner
+
+def tuple_expand(out, tuplespec, prio, seed=None, cnt=1):
+ """Given a tuple specification, expand it cnt times, and add results to out.
+
+ Expansion is defined recursively:
+ - If any of the spec elements is a list, each element of the list results
+ in an expansion (by replacing the list with its element).
+ - If any of the spec elements is a function, that function is invoked with
+ (spec, seed, expansion count, index in spec) as arguments. If the function
+ needs to wait for other indices to be expanded, it can return None.
+
+ The output consists of (prio, expansion count, SHA256(result), result, seed)
+ tuples."""
+
+ def recurse(vs, seed, i, change_pos=None, change=None):
+ if change_pos is not None:
+ vs = list(vs)
+ vs[change_pos] = change
+ for p, v in enumerate(vs):
+ if v is None:
+ return
+ if isinstance(v, list):
+ for ve in v:
+ recurse(vs, seed, i, p, ve)
+ return
+ if callable(v):
+ res = v(vs, seed, i, p)
+ if res is not None:
+ recurse(vs, seed, i, p, res)
+ return
+ h = hashlib.sha256()
+ for v in vs:
+ h.update(int(v).to_bytes(32, 'big'))
+ out.append((prio, i, h.digest(), vs, seed))
+ for i in range(cnt):
+ recurse(tuplespec, seed, i)
+
+def gen_ellswift_decode_cases(seed, simplified=False):
+ """Generate a set of interesting (ellswift, x, flags) ellswift decoding cases."""
+ inputs = []
+
+ # Aggregate for use in tuple_expand, expanding to int in 0..p-1, and one in p..2^256-1.
+ RANDOM_VAL = [random_fe_int, random_fe_int_high]
+ # Aggregate for use in tuple_expand, expanding to integers which %p equal 0.
+ ZERO_VAL = [0, FE.SIZE]
+ # Helpers for constructing u and t values such that u^3+t^2+7=0 or u^3-t^2+7=0.
+ T_FOR_SUM_ZERO = fn_of(0, lambda u: (-FE(u)**3 - 7).sqrts())
+ T_FOR_DIFF_ZERO = fn_of(0, lambda u: (FE(u)**3 + 7).sqrts())
+ U_FOR_SUM_ZERO = fn_of(1, lambda t: (-FE(t)**2 - 7).cbrts())
+ U_FOR_DIFF_ZERO = fn_of(1, lambda t: (FE(t)**2 - 7).cbrts())
+
+ tuple_expand(inputs, [RANDOM_VAL, RANDOM_VAL], 0, seed + b"random", 64)
+ tuple_expand(inputs, [RANDOM_VAL, T_FOR_SUM_ZERO], 1, seed + b"t=sqrt(-u^3-7)", 64)
+ tuple_expand(inputs, [U_FOR_SUM_ZERO, RANDOM_VAL], 1, seed + b"u=cbrt(-t^2-7)", 64)
+ tuple_expand(inputs, [RANDOM_VAL, T_FOR_DIFF_ZERO], 1, seed + b"t=sqrt(u^3+7)", 64)
+ tuple_expand(inputs, [U_FOR_DIFF_ZERO, RANDOM_VAL], 1, seed + b"u=cbrt(t^2-7)", 64)
+ tuple_expand(inputs, [ZERO_VAL, RANDOM_VAL], 2, seed + b"u=0", 64)
+ tuple_expand(inputs, [RANDOM_VAL, ZERO_VAL], 2, seed + b"t=0", 64)
+ tuple_expand(inputs, [ZERO_VAL, FE(8).sqrts()], 3, seed + b"u=0;t=sqrt(8)")
+ tuple_expand(inputs, [FE(-8).cbrts(), ZERO_VAL], 3, seed + b"t=0;u=cbrt(-8)")
+ tuple_expand(inputs, [FE(-6).cbrts(), ZERO_VAL], 3, seed + b"t=0;u=cbrt(-6)")
+ tuple_expand(inputs, [ZERO_VAL, ZERO_VAL], 3, seed + b"u=0;t=0")
+ # Unused.
+ tuple_expand(inputs, [ZERO_VAL, FE(-8).sqrts()], 4, seed + b"u=0;t=sqrt(-8)")
+
+ seen = set()
+ cases = []
+ for _prio, _cnt, _hash, vs, _seed in sorted(inputs):
+ inp = int(vs[0]).to_bytes(32, 'big') + int(vs[1]).to_bytes(32, 'big')
+ outp, flags = ellswift_decode_flagged(inp, simplified)
+ if flags not in seen:
+ cases.append((inp, outp, flags))
+ seen.add(flags)
+
+ return cases
+
+def gen_all_ellswift_decode_vectors(fil):
+ """Generate all xelligatorswift decoding test vectors."""
+
+ cases = gen_ellswift_decode_cases(b"")
+ writer = csv.DictWriter(fil, ["ellswift", "x", "comment"])
+ writer.writeheader()
+ for val, x, flags in sorted(cases):
+ writer.writerow({"ellswift": val.hex(), "x": x.hex(), "comment": flags})
+
+def xswiftec_inv_flagged(x, u, case):
+ """A variant of xswiftec_inv which also returns flags, describing conditions encountered."""
+
+ flags = []
+
+ if case & 2 == 0:
+ if GE.is_valid_x(-x - u):
+ flags.append("bad[valid_x(-x-u)]")
+ return None, flags
+ v = x if case & 1 == 0 else -x - u
+ if v == 0:
+ flags.append("info[v=0]")
+ s = -(u**3 + 7) / (u**2 + u*v + v**2)
+ assert s != 0 # would imply X=0 on curve
+ else:
+ s = x - u
+ if s == 0:
+ flags.append("bad[s=0]")
+ return None, flags
+ q = (-s * (4 * (u**3 + 7) + 3 * s * u**2))
+ if q == 0:
+ flags.append("info[q=0]")
+ r = q.sqrt()
+ if r is None:
+ flags.append("bad[non_square(q)]")
+ return None, flags
+ if case & 1:
+ if r == 0:
+ flags.append("bad[r=0]")
+ return None, flags
+ r = -r
+ v = (-u + r / s) / 2
+ if v == 0:
+ flags.append("info[v=0]")
+ w = s.sqrt()
+ assert w != 0
+ if w is None:
+ flags.append("bad[non_square(s)]")
+ return None, flags
+ if case & 4:
+ w = -w
+ Y = w / 2
+ assert Y != 0
+ X = 2 * Y * (v + u / 2)
+ if X == 0:
+ flags.append("info[X=0]")
+ flags.append("ok")
+ return w * (u * (MINUS_3_SQRT - 1) / 2 - v), flags
+
+def xswiftec_inv_combo_flagged(x, u):
+ """Compute the aggregate results and flags from xswiftec_inv_flagged for case=0..7."""
+ ts = []
+ allflags = []
+ for case in range(8):
+ t, flags = xswiftec_inv_flagged(x, u, case)
+ if t is not None:
+ assert x == xswiftec(u, t)
+ ts.append(t)
+ allflags.append(f"case{case}:{'&'.join(flags)}")
+ return ts, ";".join(allflags)
+
+def gen_all_xswiftec_inv_vectors(fil):
+ """Generate all xswiftec_inv test vectors."""
+
+ # Two constants used below. Compute them only once.
+ C1 = (FE(MINUS_3_SQRT) - 1) / 2
+ C2 = (-FE(MINUS_3_SQRT) - 1) / 2
+ # Helper functions that pick x and u with special properties.
+ TRIGGER_Q_ZERO = fn_of(1, lambda u: (FE(u)**3 + 28) / (FE(-3) * FE(u)**2))
+ TRIGGER_DIVZERO_A = fn_of(1, lambda u: FE(u) * C1)
+ TRIGGER_DIVZERO_B = fn_of(1, lambda u: FE(u) * C2)
+ TRIGGER_V_ZERO = fn_of(1, lambda u: FE(-7) / FE(u)**2)
+ TRIGGER_X_ZERO = fn_of(0, lambda x: FE(-2) * FE(x))
+
+ inputs = []
+ tuple_expand(inputs, [random_fe_int, random_fe_int], 0, b"uniform", 256)
+ tuple_expand(inputs, [TRIGGER_Q_ZERO, random_fe_int], 1, b"x=-(u^3+28)/(3*u^2)", 64)
+ tuple_expand(inputs, [TRIGGER_V_ZERO, random_fe_int], 1, b"x=-7/u^2", 512)
+ tuple_expand(inputs, [random_fe_int, fn_of(0, lambda x: x)], 2, b"u=x", 64)
+ tuple_expand(inputs, [random_fe_int, fn_of(0, lambda x: -FE(x))], 2, b"u=-x", 64)
+ # Unused.
+ tuple_expand(inputs, [TRIGGER_DIVZERO_A, random_fe_int], 3, b"x=u*(sqrt(-3)-1)/2", 64)
+ tuple_expand(inputs, [TRIGGER_DIVZERO_B, random_fe_int], 3, b"x=u*(-sqrt(-3)-1)/2", 64)
+ tuple_expand(inputs, [random_fe_int, TRIGGER_X_ZERO], 3, b"u=-2x", 64)
+
+ seen = set()
+ cases = []
+ for _prio, _cnt, _hash, vs, _seed in sorted(inputs):
+ x, u = FE(vs[0]), FE(vs[1])
+ if u == 0:
+ continue
+ if not GE.is_valid_x(x):
+ continue
+ ts, flags = xswiftec_inv_combo_flagged(x, u)
+ if flags not in seen:
+ cases.append((int(u), int(x), ts, flags))
+ seen.add(flags)
+
+ writer = csv.DictWriter(fil, ["u", "x"] + [f"case{c}_t" for c in range(8)] + ["comment"])
+ writer.writeheader()
+ for u, x, ts, flags in sorted(cases):
+ row = {"u": FE(u), "x": FE(x), "comment": flags}
+ for c in range(8):
+ if ts[c] is not None:
+ row[f"case{c}_t"] = FE(ts[c])
+ writer.writerow(row)
+
+def gen_packet_encoding_vector(case):
+ """Given a dict case with specs, construct a packet_encoding test vector as a CSV line."""
+ ikm = str(case).encode('utf-8')
+ in_initiating = case["init"]
+ in_ignore = int(case["ignore"])
+ in_priv_ours, in_ellswift_ours = ellswift_create_deterministic(ikm, case["features"])
+ mid_x_ours = (int.from_bytes(in_priv_ours, 'big') * SECP256K1_G).x.to_bytes()
+ assert mid_x_ours == ellswift_decode(in_ellswift_ours)
+ in_ellswift_theirs = case["theirs"]
+ in_contents = hkdf_sha256(case["contentlen"], ikm, b"contents", b"")
+ contents = in_contents * case["multiply"]
+ in_aad = hkdf_sha256(case["aadlen"], ikm, b"aad", b"")
+ mid_shared_secret = v2_ecdh(in_priv_ours, in_ellswift_theirs, in_ellswift_ours, in_initiating)
+
+ peer = initialize_v2_transport(mid_shared_secret, in_initiating)
+ for _ in range(case["idx"]):
+ v2_enc_packet(peer, b"")
+ ciphertext = v2_enc_packet(peer, contents, in_aad, case["ignore"])
+ long_msg = len(ciphertext) > 128
+
+ return {
+ "in_idx": case['idx'],
+ "in_priv_ours": in_priv_ours.hex(),
+ "in_ellswift_ours": in_ellswift_ours.hex(),
+ "in_ellswift_theirs": in_ellswift_theirs.hex(),
+ "in_initiating": int(in_initiating),
+ "in_contents": in_contents.hex(),
+ "in_multiply": case['multiply'],
+ "in_aad": in_aad.hex(),
+ "in_ignore": in_ignore,
+ "mid_x_ours": mid_x_ours.hex(),
+ "mid_x_theirs": ellswift_decode(in_ellswift_theirs).hex(),
+ "mid_x_shared": ellswift_ecdh_xonly(in_ellswift_theirs, in_priv_ours).hex(),
+ "mid_shared_secret": mid_shared_secret.hex(),
+ "mid_initiator_l": peer['initiator_L'].hex(),
+ "mid_initiator_p": peer['initiator_P'].hex(),
+ "mid_responder_l": peer['responder_L'].hex(),
+ "mid_responder_p": peer['responder_P'].hex(),
+ "mid_send_garbage_terminator": peer["send_garbage_terminator"].hex(),
+ "mid_recv_garbage_terminator": peer["recv_garbage_terminator"].hex(),
+ "out_session_id": peer["session_id"].hex(),
+ "out_ciphertext": "" if long_msg else ciphertext.hex(),
+ "out_ciphertext_endswith": ciphertext[-128:].hex() if long_msg else ""
+ }
+
+def gen_all_packet_encoding_vectors(fil):
+ """Return a list of CSV lines, one for each packet encoding vector."""
+
+ ellswift = gen_ellswift_decode_cases(b"simplified_", simplified=True)
+ ellswift.sort(key=lambda x: hashlib.sha256(b"simplified:" + x[0]).digest())
+
+ fields = [
+ "in_idx", "in_priv_ours", "in_ellswift_ours", "in_ellswift_theirs", "in_initiating",
+ "in_contents", "in_multiply", "in_aad", "in_ignore", "mid_x_ours", "mid_x_theirs",
+ "mid_x_shared", "mid_shared_secret", "mid_initiator_l", "mid_initiator_p",
+ "mid_responder_l", "mid_responder_p", "mid_send_garbage_terminator",
+ "mid_recv_garbage_terminator", "out_session_id", "out_ciphertext", "out_ciphertext_endswith"
+ ]
+
+ writer = csv.DictWriter(fil, fields)
+ writer.writeheader()
+ for case in [
+ {"init": True, "contentlen": 1, "multiply": 1, "aadlen": 0, "ignore": False, "idx": 1,
+ "theirs": ellswift[0][0], "features": 0},
+ {"init": False, "contentlen": 17, "multiply": 1, "aadlen": 0, "ignore": False, "idx": 999,
+ "theirs": ellswift[1][0], "features": 1},
+ {"init": True, "contentlen": 63, "multiply": 1, "aadlen": 4095, "ignore": False, "idx": 0,
+ "theirs": ellswift[2][0], "features": 2},
+ {"init": False, "contentlen": 128, "multiply": 1, "aadlen": 0, "ignore": True, "idx": 223,
+ "theirs": ellswift[3][0], "features": 3},
+ {"init": True, "contentlen": 193, "multiply": 1, "aadlen": 0, "ignore": False, "idx": 448,
+ "theirs": ellswift[4][0], "features": 4},
+ {"init": False, "contentlen": 41, "multiply": 97561, "aadlen": 0, "ignore": False,
+ "idx": 673, "theirs": ellswift[5][0], "features": 5},
+ {"init": True, "contentlen": 241, "multiply": 69615, "aadlen": 0, "ignore": True,
+ "idx": 1024, "theirs": ellswift[6][0], "features": 6},
+ ]:
+ writer.writerow(gen_packet_encoding_vector(case))
+
+if __name__ == "__main__":
+ print(f"Generating {FILENAME_PACKET_TEST}...")
+ with open(FILENAME_PACKET_TEST, "w", encoding="utf-8") as fil_packet:
+ gen_all_packet_encoding_vectors(fil_packet)
+ print(f"Generating {FILENAME_XSWIFTEC_INV_TEST}...")
+ with open(FILENAME_XSWIFTEC_INV_TEST, "w", encoding="utf-8") as fil_xswiftec_inv:
+ gen_all_xswiftec_inv_vectors(fil_xswiftec_inv)
+ print(f"Generating {FILENAME_ELLSWIFT_DECODE_TEST}...")
+ with open(FILENAME_ELLSWIFT_DECODE_TEST, "w", encoding="utf-8") as fil_ellswift_decode:
+ gen_all_ellswift_decode_vectors(fil_ellswift_decode)
diff --git a/bip-0324/packet_encoding_test_vectors.csv b/bip-0324/packet_encoding_test_vectors.csv
new file mode 100644
index 0000000000..4f70b92daf
--- /dev/null
+++ b/bip-0324/packet_encoding_test_vectors.csv
@@ -0,0 +1,8 @@
+in_idx,in_priv_ours,in_ellswift_ours,in_ellswift_theirs,in_initiating,in_contents,in_multiply,in_aad,in_ignore,mid_x_ours,mid_x_theirs,mid_x_shared,mid_shared_secret,mid_initiator_l,mid_initiator_p,mid_responder_l,mid_responder_p,mid_send_garbage_terminator,mid_recv_garbage_terminator,out_session_id,out_ciphertext,out_ciphertext_endswith
+1,61062ea5071d800bbfd59e2e8b53d47d194b095ae5a4df04936b49772ef0d4d7,ec0adff257bbfe500c188c80b4fdd640f6b45a482bbc15fc7cef5931deff0aa186f6eb9bba7b85dc4dcc28b28722de1e3d9108b985e2967045668f66098e475b,a4a94dfce69b4a2a0a099313d10f9f7e7d649d60501c9e1d274c300e0d89aafaffffffffffffffffffffffffffffffffffffffffffffffffffffffff8faf88d5,1,8e,1,,0,19e965bc20fc40614e33f2f82d4eeff81b5e7516b12a5c6c0d6053527eba0923,0c71defa3fafd74cb835102acd81490963f6b72d889495e06561375bd65f6ffc,4eb2bf85bd00939468ea2abb25b63bc642e3d1eb8b967fb90caa2d89e716050e,c6992a117f5edbea70c3f511d32d26b9798be4b81a62eaee1a5acaa8459a3592,9a6478b5fbab1f4dd2f78994b774c03211c78312786e602da75a0d1767fb55cf,7d0c7820ba6a4d29ce40baf2caa6035e04f1e1cefd59f3e7e59e9e5af84f1f51,17bc726421e4054ac6a1d54915085aaa766f4d3cf67bbd168e6080eac289d15e,9f0fc1c0e85fd9a8eee07e6fc41dba2ff54c7729068a239ac97c37c524cca1c0,faef555dfcdb936425d84aba524758f3,02cb8ff24307a6e27de3b4e7ea3fa65b,ce72dffb015da62b0d0f5474cab8bc72605225b0cee3f62312ec680ec5f41ba5,7530d2a18720162ac09c25329a60d75adf36eda3c3,
+999,1f9c581b35231838f0f17cf0c979835baccb7f3abbbb96ffcc318ab71e6e126f,a1855e10e94e00baa23041d916e259f7044e491da6171269694763f018c7e63693d29575dcb464ac816baa1be353ba12e3876cba7628bd0bd8e755e721eb0140,fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000000000000000000000000000000000000000000000000000000000000000,0,3eb1d4e98035cfd8eeb29bac969ed3824a,1,,0,45b6f1f684fd9f2b16e2651ddc47156c0695c8c5cd2c0c9df6d79a1056c61120,edd1fd3e327ce90cc7a3542614289aee9682003e9cf7dcc9cf2ca9743be5aa0c,c40eb6190caf399c9007254ad5e5fa20d64af2b41696599c59b2191d16992955,a0138f564f74d0ad70bc337dacc9d0bf1d2349364caf1188a1e6e8ddb3b7b184,b82a0a7ce7219777f914d2ab873c5c487c56bd7b68622594d67fe029a8fa7def,d760ba8f62dd3d29d7d5584e310caf2540285edc6b51c640f9497e99c3536fd2,9db0c6f9a903cbab5d7b3c58273a3421eec0001814ec53236bd405131a0d8e90,23d2b5e653e6a3a8db160a2ca03d11cb5a79983babba861fcb57c38413323c0c,efb64fd80acd3825ac9bc2a67216535a,b3cb553453bceb002897e751ff7588bf,9267c54560607de73f18c563b76a2442718879c52dd39852885d4a3c9912c9ea,1da1bcf589f9b61872f45b7fa5371dd3f8bdf5d515b0c5f9fe9f0044afb8dc0aa1cd39a8c4,
+0,0286c41cd30913db0fdff7a64ebda5c8e3e7cef10f2aebc00a7650443cf4c60d,d1ee8a93a01130cbf299249a258f94feb5f469e7d0f2f28f69ee5e9aa8f9b54a60f2c3ff2d023634ec7f4127a96cc11662e402894cf1f694fb9a7eaa5f1d9244,ffffffffffffffffffffffffffffffffffffffffffffffffffffffff22d5e441524d571a52b3def126189d3f416890a99d4da6ede2b0cde1760ce2c3f98457ae,1,054290a6c6ba8d80478172e89d32bf690913ae9835de6dcf206ff1f4d652286fe0ddf74deba41d55de3edc77c42a32af79bbea2c00bae7492264c60866ae5a,1,84932a55aac22b51e7b128d31d9f0550da28e6a3f394224707d878603386b2f9d0c6bcd8046679bfed7b68c517e7431e75d9dd34605727d2ef1c2babbf680ecc8d68d2c4886e9953a4034abde6da4189cd47c6bb3192242cf714d502ca6103ee84e08bc2ca4fd370d5ad4e7d06c7fbf496c6c7cc7eb19c40c61fb33df2a9ba48497a96c98d7b10c1f91098a6b7b16b4bab9687f27585ade1491ae0dba6a79e1e2d85dd9d9d45c5135ca5fca3f0f99a60ea39edbc9efc7923111c937913f225d67788d5f7e8852b697e26b92ec7bfcaa334a1665511c2b4c0a42d06f7ab98a9719516c8fd17f73804555ee84ab3b7d1762f6096b778d3cb9c799cbd49a9e4a325197b4e6cc4a5c4651f8b41ff88a92ec428354531f970263b467c77ed11312e2617d0d53fe9a8707f51f9f57a77bfb49afe3d89d85ec05ee17b9186f360c94ab8bb2926b65ca99dae1d6ee1af96cad09de70b6767e949023e4b380e66669914a741ed0fa420a48dbc7bfae5ef2019af36d1022283dd90655f25eec7151d471265d22a6d3f91dc700ba749bb67c0fe4bc0888593fbaf59d3c6fff1bf756a125910a63b9682b597c20f560ecb99c11a92c8c8c3f7fbfaa103146083a0ccaecf7a5f5e735a784a8820155914a289d57d8141870ffcaf588882332e0bcd8779efa931aa108dab6c3cce76691e345df4a91a03b71074d66333fd3591bff071ea099360f787bbe43b7b3dff2a59c41c7642eb79870222ad1c6f2e5a191ed5acea51134679587c9cf71c7d8ee290be6bf465c4ee47897a125708704ad610d8d00252d01959209d7cd04d5ecbbb1419a7e84037a55fefa13dee464b48a35c96bcb9a53e7ed461c3a1607ee00c3c302fd47cd73fda7493e947c9834a92d63dcfbd65aa7c38c3e3a2748bb5d9a58e7495d243d6b741078c8f7ee9c8813e473a323375702702b0afae1550c8341eedf5247627343a95240cb02e3e17d5dca16f8d8d3b2228e19c06399f8ec5c5e9dbe4caef6a0ea3ffb1d3c7eac03ae030e791fa12e537c80d56b55b764cadf27a8701052df1282ba8b5e3eb62b5dc7973ac40160e00722fa958d95102fc25c549d8c0e84bed95b7acb61ba65700c4de4feebf78d13b9682c52e937d23026fb4c6193e6644e2d3c99f91f4f39a8b9fc6d013f89c3793ef703987954dc0412b550652c01d922f525704d32d70d6d4079bc3551b563fb29577b3aecdc9505011701dddfd94830431e7a4918927ee44fb3831ce8c4513839e2deea1287f3fa1ab9b61a256c09637dbc7b4f0f8fbb783840f9c24526da883b0df0c473cf231656bd7bc1aaba7f321fec0971c8c2c3444bff2f55e1df7fea66ec3e440a612db9aa87bb505163a59e06b96d46f50d8120b92814ac5ab146bc78dbbf91065af26107815678ce6e33812e6bf3285d4ef3b7b04b076f21e7820dcbfdb4ad5218cf4ff6a65812d8fcb98ecc1e95e2fa58e3efe4ce26cd0bd400d6036ab2ad4f6c713082b5e3f1e04eb9e3b6c8f63f57953894b9e220e0130308e1fd91f72d398c1e7962ca2c31be83f31d6157633581a0a6910496de8d55d3d07090b6aa087159e388b7e7dec60f5d8a60d93ca2ae91296bd484d916bfaaa17c8f45ea4b1a91b37c82821199a2b7596672c37156d8701e7352aa48671d3b1bbbd2bd5f0a2268894a25b0cb2514af39c8743f8cce8ab4b523053739fd8a522222a09acf51ac704489cf17e4b7125455cb8f125b4d31af1eba1f8cf7f81a5a100a141a7ee72e8083e065616649c241f233645c5fc865d17f0285f5c52d9f45312c979bfb3ce5f2a1b951deddf280ffb3f370410cffd1583bfa90077835aa201a0712d1dcd1293ee177738b14e6b5e2a496d05220c3253bb6578d6aff774be91946a614dd7e879fb3dcf7451e0b9adb6a8c44f53c2c464bcc0019e9fad89cac7791a0a3f2974f759a9856351d4d2d7c5612c17cfc50f8479945df57716767b120a590f4bf656f4645029a525694d8a238446c5f5c2c1c995c09c1405b8b1eb9e0352ffdf766cc964f8dcf9f8f043dfab6d102cf4b298021abd78f1d9025fa1f8e1d710b38d9d1652f2d88d1305874ec41609b6617b65c5adb19b6295dc5c5da5fdf69f28144ea12f17c3c6fcce6b9b5157b3dfc969d6725fa5b098a4d9b1d31547ed4c9187452d281d0a5d456008caf1aa251fac8f950ca561982dc2dc908d3691ee3b6ad3ae3d22d002577264ca8e49c523bd51c4846be0d198ad9407bf6f7b82c79893eb2c05fe9981f687a97a4f01fe45ff8c8b7ecc551135cd960a0d6001ad35020be07ffb53cb9e731522ca8ae9364628914b9b8e8cc2f37f03393263603cc2b45295767eb0aac29b0930390eb89587ab2779d2e3decb8042acece725ba42eda650863f418f8d0d50d104e44fbbe5aa7389a4a144a8cecf00f45fb14c39112f9bfb56c0acbd44fa3ff261f5ce4acaa5134c2c1d0cca447040820c81ab1bcdc16aa075b7c68b10d06bbb7ce08b5b805e0238f24402cf24a4b4e00701935a0c68add3de090903f9b85b153cb179a582f57113bfc21c2093803f0cfa4d9d4672c2b05a24f7e4c34a8e9101b70303a7378b9c50b6cddd46814ef7fd73ef6923feceab8fc5aa8b0d185f2e83c7a99dcb1077c0ab5c1f5d5f01ba2f0420443f75c4417db9ebf1665efbb33dca224989920a64b44dc26f682cc77b4632c8454d49135e52503da855bc0f6ff8edc1145451a9772c06891f41064036b66c3119a0fc6e80dffeb65dc456108b7ca0296f4175fff3ed2b0f842cd46bd7e86f4c62dfaf1ddbf836263c00b34803de164983d0811cebfac86e7720c726d3048934c36c23189b02386a722ca9f0fe00233ab50db928d3bccea355cc681144b8b7edcaae4884d5a8f04425c0890ae2c74326e138066d8c05f4c82b29df99b034ea727afde590a1f2177ace3af99cfb1729d6539ce7f7f7314b046aab74497e63dd399e1f7d5f16517c23bd830d1fdee810f3c3b77573dd69c4b97d80d71fb5a632e00acdfa4f8e829faf3580d6a72c40b28a82172f8dcd4627663ebf6069736f21735fd84a226f427cd06bb055f94e7c92f31c48075a2955d82a5b9d2d0198ce0d4e131a112570a8ee40fb80462a81436a58e7db4e34b6e2c422e82f934ecda9949893da5730fc5c23c7c920f363f85ab28cc6a4206713c3152669b47efa8238fa826735f17b4e78750276162024ec85458cd5808e06f40dd9fd43775a456a3ff6cae90550d76d8b2899e0762ad9a371482b3e38083b1274708301d6346c22fea9bb4b73db490ff3ab05b2f7f9e187adef139a7794454b7300b8cc64d3ad76c0e4bc54e08833a4419251550655380d675bc91855aeb82585220bb97f03e976579c08f321b5f8f70988d3061f41465517d53ac571dbf1b24b94443d2e9a8e8a79b392b3d6a4ecdd7f626925c365ef6221305105ce9b5f5b6ecc5bed3d702bd4b7f5008aa8eb8c7aa3ade8ecf6251516fbefeea4e1082aa0e1848eddb31ffe44b04792d296054402826e4bd054e671f223e5557e4c94f89ca01c25c44f1a2ff2c05a70b43408250705e1b858bf0670679fdcd379203e36be3500dd981b1a6422c3cf15224f7fefdef0a5f225c5a09d15767598ecd9e262460bb33a4b5d09a64591efabc57c923d3be406979032ae0bc0997b65336a06dd75b253332ad6a8b63ef043f780a1b3fb6d0b6cad98b1ef4a02535eb39e14a866cfc5fc3a9c5deb2261300d71280ebe66a0776a151469551c3c5fa308757f956655278ec6330ae9e3625468c5f87e02cd9a6489910d4143c1f4ee13aa21a6859d907b788e28572fecee273d44e4a900fa0aa668dd861a60fb6b6b12c2c5ef3c8df1bd7ef5d4b0d1cdb8c15fffbb365b9784bd94abd001c6966216b9b67554ad7cb7f958b70092514f7800fc40244003e0fd1133a9b850fb17f4fcafde07fc87b07fb510670654a5d2d6fc9876ac74728ea41593beef003d6858786a52d3a40af7529596767c17000bfaf8dc52e871359f4ad8bf6e7b2853e5229bdf39657e213580294a5317c5df172865e1e17fe37093b585e04613f5f078f761b2b1752eb32983afda24b523af8851df9a02b37e77f543f18888a782a994a50563334282bf9cdfccc183fdf4fcd75ad86ee0d94f91ee2300a5befbccd14e03a77fc031a8cfe4f01e4c5290f5ac1da0d58ea054bd4837cfd93e5e34fc0eb16e48044ba76131f228d16cde9b0bb978ca7cdcd10653c358bdb26fdb723a530232c32ae0a4cecc06082f46e1c1d596bfe60621ad1e354e01e07b040cc7347c016653f44d926d13ca74e6cbc9d4ab4c99f4491c95c76fff5076b3936eb9d0a286b97c035ca88a3c6309f5febfd4cdaac869e4f58ed409b1e9eb4192fb2f9c2f12176d460fd98286c9d6df84598f260119fd29c63f800c07d8df83d5cc95f8c2fea2812e7890e8a0718bb1e031ecbebc0436dcf3e3b9a58bcc06b4c17f711f80fe1dffc3326a6eb6e00283055c6dabe20d311bfd5019591b7954f8163c9afad9ef8390a38f3582e0a79cdf0353de8eeb6b5f9f27b16ffdef7dd62869b4840ee226ccdce95e02c4545eb981b60571cd83f03dc5eaf8c97a0829a4318a9b3dc06c0e003db700b2260ff1fa8fee66890e637b109abb03ec901b05ca599775f48af50154c0e67d82bf0f558d7d3e0778dc38bea1eb5f74dc8d7f90abdf5511a424be66bf8b6a3cacb477d2e7ef4db68d2eba4d5289122d851f9501ba7e9c4957d8eba3be3fc8e785c4265a1d65c46f2809b70846c693864b169c9dcb78be26ea14b8613f145b01887222979a9e67aee5f800caa6f5c4229bdeefc901232ace6143c9865e4d9c07f51aa200afaf7e48a7d1d8faf366023beab12906ffcb3eaf72c0eb68075e4daf3c080e0c31911befc16f0cc4a09908bb7c1e26abab38bd7b788e1a09c0edf1a35a38d2ff1d3ed47fcdaae2f0934224694f5b56705b9409b6d3d64f3833b686f7576ec64bbdd6ff174e56c2d1edac0011f904681a73face26573fbba4e34652f7ae84acfb2fa5a5b3046f98178cd0831df7477de70e06a4c00e305f31aafc026ef064dd68fd3e4252b1b91d617b26c6d09b6891a00df68f105b5962e7f9d82da101dd595d286da721443b72b2aba2377f6e7772e33b3a5e3753da9c2578c5d1daab80187f55518c72a64ee150a7cb5649823c08c9f62cd7d020b45ec2cba8310db1a7785a46ab24785b4d54ff1660b5ca78e05a9a55edba9c60bf044737bc468101c4e8bd1480d749be5024adefca1d998abe33eaeb6b11fbb39da5d905fdd3f611b2e51517ccee4b8af72c2d948573505590d61a6783ab7278fc43fe55b1fcc0e7216444d3c8039bb8145ef1ce01c50e95a3f3feab0aee883fdb94cc13ee4d21c542aa795e18932228981690f4d4c57ca4db6eb5c092e29d8a05139d509a8aeb48baa1eb97a76e597a32b280b5e9d6c36859064c98ff96ef5126130264fa8d2f49213870d9fb036cff95da51f270311d9976208554e48ffd486470d0ecdb4e619ccbd8226147204baf8e235f54d8b1cba8fa34a9a4d055de515cdf180d2bb6739a175183c472e30b5c914d09eeb1b7dafd6872b38b48c6afc146101200e6e6a44fe5684e220adc11f5c403ddb15df8051e6bdef09117a3a5349938513776286473a3cf1d2788bb875052a2e6459fa7926da33380149c7f98d7700528a60c954e6f5ecb65842fde69d614be69eaa2040a4819ae6e756accf936e14c1e894489744a79c1f2c1eb295d13e2d767c09964b61f9cfe497649f712,0,33a32d10066fa3963a9518a14d1bd1cb5ccaceaeaaeddb4d7aead90c08395bfd,568146140669e69646a6ffeb3793e8010e2732209b4c34ec13e209a070109183,a1017beaa8784f283dee185cd847ae3a327a981e62ae21e8c5face175fc97e9b,250b93570d411149105ab8cb0bc5079914906306368c23e9d77c2a33265b994c,4ec7daf7294a4a2c717442dd21cf2f052a3bfe9d535b55da0f66fecf87a27534,52ab4db9c4b06621f8ded3405691eb32465b1360d15a6b127ded4d15f9cde466,ba9906da802407ddedf6733e29f3996c62425e79d3cbfeebbd6ec4cdc7c976a8,ee661e18c97319ad071106bf35fe1085034832f70718d92f887932128b6100c7,d4e3f18ac2e2095edb5c3b94236118ad,4faa6c4233d9fd53d170ede4172142a8,23f154ac43cfc59c4243e9fc68aeec8f19ad3942d74108e833b36f0dd3dcd357,8da7de6ea7bf2a81a396a42880ba1f5756734c4821309ac9aeffa2a26ce86873b9dc4935a772de6ec5162c6d075b14536800fb174841153511bfb597e992e2fe8a450c4bce102cc550bb37fd564c4d60bf884e,
+223,6c77432d1fda31e9f942f8af44607e10f3ad38a65f8a4bddae823e5eff90dc38,d2685070c1e6376e633e825296634fd461fa9e5bdf2109bcebd735e5a91f3e587c5cb782abb797fbf6bb5074fd1542a474f2a45b673763ec2db7fb99b737bbb9,56bd0c06f10352c3a1a9f4b4c92f6fa2b26df124b57878353c1fc691c51abea77c8817daeeb9fa546b77c8daf79d89b22b0e1b87574ece42371f00237aa9d83a,0,7e0e78eb6990b059e6cf0ded66ea93ef82e72aa2f18ac24f2fc6ebab561ae557420729da103f64cecfa20527e15f9fb669a49bbbf274ef0389b3e43c8c44e5f60bf2ac38e2b55e7ec4273dba15ba41d21f8f5b3ee1688b3c29951218caf847a97fb50d75a86515d445699497d968164bf740012679b8962de573be941c62b7ef,1,,1,193d019db571162e52567e0cfdf9dd6964394f32769ae2edc4933b03b502d771,2dd7b9cc85524f8670f695c3143ac26b45cebcabb2782a85e0fe15aee3956535,5e35f94adfd57976833bffec48ef6dde983d18a55501154191ea352ef06732ee,1918b741ef5f9d1d7670b050c152b4a4ead2c31be9aecb0681c0cd4324150853,97124c56236425d792b1ec85e34b846e8d88c9b9f1d4f23ac6cdcc4c177055a0,8c71b468c61119415e3c1dfdd184134211951e2f623199629a46bff9673611f2,b43b8791b51ed682f56d64351601be28e478264411dcf963b14ee60b9ae427fa,794dde4b38ef04250c534a7fa638f2e8cc8b6d2c6110ec290ab0171fdf277d51,cf2e25f23501399f30738d7eee652b90,225a477a28a54ea7671d2b217a9c29db,7ec02fea8c1484e3d0875f978c5f36d63545e2e4acf56311394422f4b66af612,,729847a3e9eba7a5bff454b5de3b393431ee360736b6c030d7a5bd01d1203d2e98f528543fd2bf886ccaa1ada5e215a730a36b3f4abfc4e252c89eb01d9512f94916dae8a76bf16e4da28986ffe159090fe5267ee3394300b7ccf4dfad389a26321b3a3423e4594a82ccfbad16d6561ecb8772b0cb040280ff999a29e3d9d4fd
+448,a6ec25127ca1aa4cf16b20084ba1e6516baae4d32422288e9b36d8bddd2de35a,ffffffffffffffffffffffffffffffffffffffffffffffffffffffff053d7ecca53e33e185a8b9be4e7699a97c6ff4c795522e5918ab7cd6b6884f67e683f3dc,ffffffffffffffffffffffffffffffffffffffffffffffffffffffffa7730be30000000000000000000000000000000000000000000000000000000000000000,1,00cf68f8f7ac49ffaa02c4864fdf6dfe7bbf2c740b88d98c50ebafe32c92f3427f57601ffcb21a3435979287db8fee6c302926741f9d5e464c647eeb9b7acaeda46e00abd7506fc9a719847e9a7328215801e96198dac141a15c7c2f68e0690dd1176292a0dded04d1f548aad88f1aebdc0a8f87da4bb22df32dd7c160c225b843e83f6525d6d484f502f16d923124fc538794e21da2eb689d18d87406ecced5b9f92137239ed1d37bcfa7836641a83cf5e0a1cf63f51b06f158e499a459ede41c,1,,0,02b225089255f7b02b20276cfe9779144df8fb1957b477bff3239d802d1256e9,5232c4b6bde9d3d45d7b763ebd7495399bb825cc21de51011761cd81a51bdc84,379223d2f1ea7f8a22043c4ce4122623098309e15b1ce58286ebe3d3bf40f4e1,dd210aa6629f20bb328e5d89daa6eb2ac3d1c658a725536ff154f31b536c23b2,393472f85a5cc6b0f02c4bd466db7a2dc5b91fc9dcb15c0dd6dc21116ece8bca,c80b87b793db47320b2795db66d331bd3021cc24e360d59d0fa8974f54687e0c,ef16a43d77e2b270b0a145ee1618d35f3c943cc7877d6cfcff2287d41692be39,20d4b62e2d982c61bb0cc39a93283d98af36530ef12331d44b2477b0e521b490,fead69be77825a23daec377c362aa560,511d4980526c5e64aa7187462faeafdd,acb8f084ea763ddd1b92ac4ed23bf44de20b84ab677d4e4e6666a6090d40353d,,77b4656934a82de1a593d8481f020194ddafd8cac441f9d72aeb8721e6a14f49698ca6d9b2b6d59d07a01aa552fd4d5b68d0d1617574c77dea10bfadbaa31b83885b7ceac2fd45e3e4a331c51a74e7b1698d81b64c87c73c5b9258b4d83297f9debc2e9aa07f8572ff434dc792b83ecf07b3197de8dc9cf7be56acb59c66cff5
+673,0af952659ed76f80f585966b95ab6e6fd68654672827878684c8b547b1b94f5a,ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc81017fd92fd31637c26c906b42092e11cc0d3afae8d9019d2578af22735ce7bc469c72d,9652d78baefc028cd37a6a92625b8b8f85fde1e4c944ad3f20e198bef8c02f19fffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e91870,0,5c6272ee55da855bbbf7b1246d9885aa7aa601a715ab86fa46c50da533badf82b97597c968293ae04e,97561,,0,4b1767466fe2fb8deddf2dc52cc19c7e2032007e19bfb420b30a80152d0f22d6,64c383e0e78ac99476ddff2061683eeefa505e3666673a1371342c3e6c26981d,5bcfeac98d87e87e158bf839f1269705429f7af2a25b566a25811b5f9aef9560,3568f2aea2e14ef4ee4a3c2a8b8d31bc5e3187ba86db10739b4ff8ec92ff6655,c7df866a62b7d404eb530b2be245a7aece0fb4791402a1de8f33530cbf777cc1,8f732e4aae2ba9314e0982492fa47954de9c189d92fbc549763b27b1b47642ce,992085edfecb92c62a3a7f96ea416f853f34d0dfe065b966b6968b8b87a83081,c5ba5eaf9e1c807154ebab3ea472499e815a7be56dfaf0c201cf6e91ffeca8e6,5e2375ac629b8df1e4ff3617c6255a70,70bcbffcb62e4d29d2605d30bceef137,7332e92a3f9d2792c4d444fac5ed888c39a073043a65eefb626318fd649328f8,,657a4a19711ce593c3844cb391b224f60124aba7e04266233bc50cafb971e26c7716b76e98376448f7d214dd11e629ef9a974d60e3770a695810a61c4ba66d78b936ee7892b98f0b48ddae9fcd8b599dca1c9b43e9b95e0226cf8d4459b8a7c2c4e6db80f1d58c7b20dd7208fa5c1057fb78734223ee801dbd851db601fee61e
+1024,f90e080c64b05824c5a24b2501d5aeaf08af3872ee860aa80bdcd430f7b63494,ffffffffffffffffffffffffffffffffffffffffffffffffffffffff115173765dc202cf029ad3f15479735d57697af12b0131dd21430d5772e4ef11474d58b9,12a50f3fafea7c1eeada4cf8d33777704b77361453afc83bda91eef349ae044d20126c6200547ea5a6911776c05dee2a7f1a9ba7dfbabbbd273c3ef29ef46e46,1,5f67d15d22ca9b2804eeab0a66f7f8e3a10fa5de5809a046084348cbc5304e843ef96f59a59c7d7fdfe5946489f3ea297d941bac326225df316a25fc90f0e65b0d31a9c497e960fdbf8c482516bc8a9c1c77b7f6d0e1143810c737f76f9224e6f2c9af5186b4f7259c7e8d165b6e4fe3d38a60bdbdd4d06ecdcaaf62086070dbb68686b802d53dfd7db14b18743832605f5461ad81e2af4b7e8ff0eff0867a25b93cec7becf15c43131895fed09a83bf1ee4a87d44dd0f02a837bf5a1232e201cb882734eb9643dc2dc4d4e8b5690840766212c7ac8f38ad8a9ec47c7a9b3e022ae3eb6a32522128b518bd0d0085dd81c5,69615,,1,8b8de966150bf872b4b695c9983df519c909811954d5d76e99ed0d5f1860247b,eef379db9bd4b1aa90fc347fad33f7d53083389e22e971036f59f4e29d325ac2,0a402d812314646ccc2565c315d1429ec1ed130ff92ff3f48d948f29c3762cf1,e25461fb0e4c162e18123ecde88342d54d449631e9b75a266fd9260c2bb2f41d,97771ce2ce17a25c3d65bf9f8e4acb830dce8d41392be3e4b8ed902a3106681a,2e7022b4eae9152942f68160a93e25d3e197a557385594aa587cb5e431bb470d,613f85a82d783ce450cfd7e91a027fcc4ad5610872f83e4dbe9e2202184c6d6e,cb5de4ed1083222e381401cf88e3167796bc9ab5b8aa1f27b718f39d1e6c0e87,b709dea25e0be287c50e3603482c2e98,1f677e9d7392ebe3633fd82c9efb0f16,889f339285564fd868401fac8380bb9887925122ec8f31c8ae51ce067def103b,,7c4b9e1e6c1ce69da7b01513cdc4588fd93b04dafefaf87f31561763d906c672bac3dfceb751ebd126728ac017d4d580e931b8e5c7d5dfe0123be4dc9b2d2238b655c8a7fadaf8082c31e310909b5b731efc12f0a56e849eae6bfeedcc86dd27ef9b91d159256aa8e8d2b71a311f73350863d70f18d0d7302cf551e4303c7733
diff --git a/bip-0324/reference.py b/bip-0324/reference.py
new file mode 100644
index 0000000000..44f4c77465
--- /dev/null
+++ b/bip-0324/reference.py
@@ -0,0 +1,649 @@
+"""Reference implementation for the cryptographic aspects of BIP-324"""
+
+import sys
+import random
+import hashlib
+import hmac
+
+### BIP-340 tagged hash
+
+def TaggedHash(tag, data):
+ """Compute BIP-340 tagged hash with specified tag string of data."""
+ ss = hashlib.sha256(tag.encode('utf-8')).digest()
+ ss += ss
+ ss += data
+ return hashlib.sha256(ss).digest()
+
+### HKDF-SHA256
+
+def hmac_sha256(key, data):
+ """Compute HMAC-SHA256 from specified byte arrays key and data."""
+ return hmac.new(key, data, hashlib.sha256).digest()
+
+def hkdf_sha256(length, ikm, salt, info):
+ """Derive a key using HKDF-SHA256."""
+ if len(salt) == 0:
+ salt = bytes([0] * 32)
+ prk = hmac_sha256(salt, ikm)
+ t = b""
+ okm = b""
+ for i in range((length + 32 - 1) // 32):
+ t = hmac_sha256(prk, t + info + bytes([i + 1]))
+ okm += t
+ return okm[:length]
+
+### secp256k1 field/group elements
+
+def modinv(a, n):
+ """Compute the modular inverse of a modulo n using the extended Euclidean
+ Algorithm. See https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers.
+ """
+ a = a % n
+ if a == 0:
+ return 0
+ if sys.hexversion >= 0x3080000:
+ # A more efficient version is available in Python 3.8.
+ return pow(a, -1, n)
+ t1, t2 = 0, 1
+ r1, r2 = n, a
+ while r2 != 0:
+ q = r1 // r2
+ t1, t2 = t2, t1 - q * t2
+ r1, r2 = r2, r1 - q * r2
+ if r1 > 1:
+ return None
+ if t1 < 0:
+ t1 += n
+ return t1
+
+class FE:
+ """Objects of this class represent elements of the field GF(2**256 - 2**32 - 977).
+
+ They are represented internally in numerator / denominator form, in order to delay inversions.
+ """
+
+ SIZE = 2**256 - 2**32 - 977
+
+ def __init__(self, a=0, b=1):
+ """Initialize an FE as a/b; both a and b can be ints or field elements."""
+ if isinstance(b, FE):
+ if isinstance(a, FE):
+ self.num = (a.num * b.den) % FE.SIZE
+ self.den = (a.den * b.num) % FE.SIZE
+ else:
+ self.num = (a * b.den) % FE.SIZE
+ self.den = b.num
+ else:
+ b = b % FE.SIZE
+ assert b != 0
+ if isinstance(a, FE):
+ self.num = a.num
+ self.den = (a.den * b) % FE.SIZE
+ else:
+ self.num = a % FE.SIZE
+ self.den = b
+
+ def __add__(self, a):
+ """Compute the sum of two field elements (second may be int)."""
+ if isinstance(a, FE):
+ return FE(self.num * a.den + self.den * a.num, self.den * a.den)
+ return FE(self.num + self.den * a, self.den)
+
+ def __radd__(self, a):
+ """Compute the sum of an integer and a field element."""
+ return FE(self.num + self.den * a, self.den)
+
+ def __sub__(self, a):
+ """Compute the difference of two field elements (second may be int)."""
+ if isinstance(a, FE):
+ return FE(self.num * a.den - self.den * a.num, self.den * a.den)
+ return FE(self.num - self.den * a, self.den)
+
+ def __rsub__(self, a):
+ """Compute the difference between an integer and a field element."""
+ return FE(self.den * a - self.num, self.den)
+
+ def __mul__(self, a):
+ """Compute the product of two field elements (second may be int)."""
+ if isinstance(a, FE):
+ return FE(self.num * a.num, self.den * a.den)
+ return FE(self.num * a, self.den)
+
+ def __rmul__(self, a):
+ """Compute the product of an integer with a field element."""
+ return FE(self.num * a, self.den)
+
+ def __truediv__(self, a):
+ """Compute the ratio of two field elements (second may be int)."""
+ return FE(self, a)
+
+ def __rtruediv__(self, a):
+ """Compute the ratio of an integer and a field element."""
+ return FE(a, self)
+
+ def __pow__(self, a):
+ """Raise a field element to a (positive) integer power."""
+ return FE(pow(self.num, a, FE.SIZE), pow(self.den, a, FE.SIZE))
+
+ def __neg__(self):
+ """Negate a field element."""
+ return FE(-self.num, self.den)
+
+ def __int__(self):
+ """Convert a field element to an integer. The result is cached."""
+ if self.den != 1:
+ self.num = (self.num * modinv(self.den, FE.SIZE)) % FE.SIZE
+ self.den = 1
+ return self.num
+
+ def sqrt(self):
+ """Compute the square root of a field element.
+
+ Due to the fact that our modulus p is of the form p = 3 (mod 4), the
+ Tonelli-Shanks algorithm (https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm)
+ is simply raising the argument to the power (p + 1) / 4.
+
+ To see why: p-1 = 0 (mod 2), so 2 divides the order of the multiplicative group,
+ and thus only half of the non-zero field elements are squares. An element a is
+ a (nonzero) square when Euler's criterion, a^((p-1)/2) = 1 (mod p), holds. We're
+ looking for x such that x^2 = a (mod p). Given a^((p-1)/2) = 1 (mod p), that is
+ equivalent to x^2 = a^(1 + (p-1)/2) (mod p). As (1 + (p-1)/2) is even, this is
+ equivalent to x = a^((1 + (p-1)/2)/2) (mod p), or x = a^((p+1)/4) (mod p)."""
+ v = int(self)
+ s = pow(v, (FE.SIZE + 1) // 4, FE.SIZE)
+ if s**2 % FE.SIZE == v:
+ return FE(s)
+ return None
+
+ def sqrts(self):
+ """Compute all square roots of a field element, if any."""
+ s = self.sqrt()
+ if s is None:
+ return []
+ return [FE(s), -FE(s)]
+
+ # The cube roots of 1 (mod p).
+ CBRT1 = [
+ 1,
+ 0x851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40,
+ 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee
+ ]
+
+
+ def cbrts(self):
+ """Compute all cube roots of a field element, if any.
+
+ Due to the fact that our modulus p is of the form p = 7 (mod 9), one cube root
+ can always be computed by raising to the power of (p + 2) / 9. The other roots
+ (if any) can be found by multiplying with the two non-trivial cube roots of 1.
+
+ To see why: p-1 = 0 (mod 3), so 3 divides the order of the multiplicative group,
+ and thus only 1/3 of the non-zero field elements are cubes. An element a is a
+ (nonzero) cube when a^((p-1)/3) = 1 (mod p). We're looking for x such that
+ x^3 = a (mod p). Given a^((p-1)/3) = 1 (mod p), that is equivalent to
+ x^3 = a^(1 + (p-1)/3) (mod p). As (1 + (p-1)/3) is a multiple of 3, this is
+ equivalent to x = a^((1 + (p-1)/3)/3) (mod p), or x = a^((p+2)/9) (mod p)."""
+ v = int(self)
+ c = pow(v, (FE.SIZE + 2) // 9, FE.SIZE)
+
+ if pow(c, 3, FE.SIZE) == v:
+ return [FE(c * f) for f in FE.CBRT1]
+ return []
+
+ def is_square(self):
+ """Determine if this field element has a square root."""
+ # Compute the Jacobi symbol of (self / p). Since our modulus is prime, this
+ # is the same as the Legendre symbol, which determines quadratic residuosity.
+ # See https://en.wikipedia.org/wiki/Jacobi_symbol for the algorithm.
+ n, k, t = (self.num * self.den) % FE.SIZE, FE.SIZE, 0
+ if n == 0:
+ return True
+ while n != 0:
+ while n & 1 == 0:
+ n >>= 1
+ r = k & 7
+ t ^= (r in (3, 5))
+ n, k = k, n
+ t ^= (n & k & 3 == 3)
+ n = n % k
+ assert k == 1
+ return not t
+
+ def __eq__(self, a):
+ """Check whether two field elements are equal (second may be an int)."""
+ if isinstance(a, FE):
+ return (self.num * a.den - self.den * a.num) % FE.SIZE == 0
+ return (self.num - self.den * a) % FE.SIZE == 0
+
+ def to_bytes(self):
+ """Convert a field element to 32-byte big endian encoding."""
+ return int(self).to_bytes(32, 'big')
+
+ @staticmethod
+ def from_bytes(b):
+ """Convert a 32-byte big endian encoding of a field element to an FE."""
+ v = int.from_bytes(b, 'big')
+ if v >= FE.SIZE:
+ return None
+ return FE(v)
+
+ def __str__(self):
+ """Convert this field element to a string."""
+ return f"{int(self):064x}"
+
+ def __repr__(self):
+ """Get a string representation of this field element."""
+ return f"FE(0x{int(self):x})"
+
+assert all(pow(c, 3, FE.SIZE) == 1 for c in FE.CBRT1)
+
+class GE:
+ """Objects of this class represent points (group elements) on the secp256k1 curve.
+
+ The point at infinity is represented as None."""
+
+ ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
+ ORDER_HALF = ORDER // 2
+
+ def __init__(self, x, y):
+ """Initialize a group element with specified x and y coordinates (must be on curve)."""
+ fx = FE(x)
+ fy = FE(y)
+ assert fy**2 == fx**3 + 7
+ self.x = fx
+ self.y = fy
+
+ def double(self):
+ """Compute the double of a point."""
+ l = 3 * self.x**2 / (2 * self.y)
+ x3 = l**2 - 2 * self.x
+ y3 = l * (self.x - x3) - self.y
+ return GE(x3, y3)
+
+ def __add__(self, a):
+ """Add two points, or a point and infinity, together."""
+ if a is None:
+ # Adding point at infinity
+ return self
+ if self.x != a.x:
+ # Adding distinct x coordinates
+ l = (a.y - self.y) / (a.x - self.x)
+ x3 = l**2 - self.x - a.x
+ y3 = l * (self.x - x3) - self.y
+ return GE(x3, y3)
+ if self.y == a.y:
+ # Adding point to itself
+ return self.double()
+ # Adding point to its negation
+ return None
+
+ def __radd__(self, a):
+ """Add infinity to a point."""
+ assert a is None
+ return self
+
+ def __mul__(self, a):
+ """Multiply a point with an integer (scalar multiplication)."""
+ r = None
+ for i in range(a.bit_length() - 1, -1, -1):
+ if r is not None:
+ r = r.double()
+ if (a >> i) & 1:
+ r += self
+ return r
+
+ def __rmul__(self, a):
+ """Multiply an integer with a point (scalar multiplication)."""
+ return self * a
+
+ @staticmethod
+ def lift_x(x):
+ """Take an FE, and return the point with that as X coordinate, and square Y."""
+ y = (FE(x)**3 + 7).sqrt()
+ if y is None:
+ return None
+ return GE(x, y)
+
+ @staticmethod
+ def is_valid_x(x):
+ """Determine whether the provided field element is a valid X coordinate."""
+ return (FE(x)**3 + 7).is_square()
+
+ def __str__(self):
+ """Convert this group element to a string."""
+ return f"({self.x},{self.y})"
+
+ def __repr__(self):
+ """Get a string representation for this group element."""
+ return f"GE(0x{int(self.x)},0x{int(self.y)})"
+
+SECP256K1_G = GE(
+ 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
+ 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
+
+### ElligatorSwift
+
+# Precomputed constant square root of -3 (mod p).
+MINUS_3_SQRT = FE(-3).sqrt()
+
+def xswiftec(u, t):
+ """Decode field elements (u, t) to an X coordinate on the curve."""
+ if u == 0:
+ u = FE(1)
+ if t == 0:
+ t = FE(1)
+ if u**3 + t**2 + 7 == 0:
+ t = 2 * t
+ X = (u**3 + 7 - t**2) / (2 * t)
+ Y = (X + t) / (MINUS_3_SQRT * u)
+ for x in (u + 4 * Y**2, (-X / Y - u) / 2, (X / Y - u) / 2):
+ if GE.is_valid_x(x):
+ return x
+ assert False
+
+def xswiftec_inv(x, u, case):
+ """Given x and u, find t such that xswiftec(u, t) = x, or return None.
+
+ Case selects which of the up to 8 results to return."""
+
+ if case & 2 == 0:
+ if GE.is_valid_x(-x - u):
+ return None
+ v = x
+ s = -(u**3 + 7) / (u**2 + u*v + v**2)
+ else:
+ s = x - u
+ if s == 0:
+ return None
+ r = (-s * (4 * (u**3 + 7) + 3 * s * u**2)).sqrt()
+ if r is None:
+ return None
+ if case & 1 and r == 0:
+ return None
+ v = (-u + r / s) / 2
+ w = s.sqrt()
+ if w is None:
+ return None
+ if case & 5 == 0: return -w * (u * (1 - MINUS_3_SQRT) / 2 + v)
+ if case & 5 == 1: return w * (u * (1 + MINUS_3_SQRT) / 2 + v)
+ if case & 5 == 4: return w * (u * (1 - MINUS_3_SQRT) / 2 + v)
+ if case & 5 == 5: return -w * (u * (1 + MINUS_3_SQRT) / 2 + v)
+
+def xelligatorswift(x):
+ """Given a field element X on the curve, find (u, t) that encode them."""
+ while True:
+ u = FE(random.randrange(1, GE.ORDER))
+ case = random.randrange(0, 8)
+ t = xswiftec_inv(x, u, case)
+ if t is not None:
+ return u, t
+
+def ellswift_create():
+ """Generate a (privkey, ellswift_pubkey) pair."""
+ priv = random.randrange(1, GE.ORDER)
+ u, t = xelligatorswift((priv * SECP256K1_G).x)
+ return priv.to_bytes(32, 'big'), u.to_bytes() + t.to_bytes()
+
+def ellswift_decode(ellswift):
+ """Convert ellswift encoded X coordinate to 32-byte xonly format."""
+ u = FE(int.from_bytes(ellswift[:32], 'big'))
+ t = FE(int.from_bytes(ellswift[32:], 'big'))
+ return xswiftec(u, t).to_bytes()
+
+def ellswift_ecdh_xonly(pubkey_theirs, privkey):
+ """Compute X coordinate of shared ECDH point between elswift pubkey and privkey."""
+ d = int.from_bytes(privkey, 'big')
+ pub = ellswift_decode(pubkey_theirs)
+ return (d * GE.lift_x(FE.from_bytes(pub))).x.to_bytes()
+
+### Poly1305
+
+class Poly1305:
+ """Class representing a running poly1305 computation."""
+ MODULUS = 2**130 - 5
+
+ def __init__(self, key):
+ self.r = int.from_bytes(key[:16], 'little') & 0xffffffc0ffffffc0ffffffc0fffffff
+ self.s = int.from_bytes(key[16:], 'little')
+ self.acc = 0
+
+ def add(self, msg, length=None, pad=False):
+ """Add a message of any length. Input so far must be a multiple of 16 bytes."""
+ length = len(msg) if length is None else length
+ for i in range((length + 15) // 16):
+ chunk = msg[i * 16:i * 16 + min(16, length - i * 16)]
+ val = int.from_bytes(chunk, 'little') + 256**(16 if pad else len(chunk))
+ self.acc = (self.r * (self.acc + val)) % Poly1305.MODULUS
+ return self
+
+ def tag(self):
+ """Compute the poly1305 tag."""
+ return ((self.acc + self.s) & 0xffffffffffffffffffffffffffffffff).to_bytes(16, 'little')
+
+### ChaCha20
+
+CHACHA20_INDICES = (
+ (0, 4, 8, 12), (1, 5, 9, 13), (2, 6, 10, 14), (3, 7, 11, 15),
+ (0, 5, 10, 15), (1, 6, 11, 12), (2, 7, 8, 13), (3, 4, 9, 14)
+)
+
+CHACHA20_CONSTANTS = (0x61707865, 0x3320646e, 0x79622d32, 0x6b206574)
+
+def rotl32(v, bits):
+ """Rotate the 32-bit value v left by bits bits."""
+ return ((v << bits) & 0xffffffff) | (v >> (32 - bits))
+
+def chacha20_doubleround(s):
+ """Apply a ChaCha20 double round to 16-element state array s.
+
+ See https://cr.yp.to/chacha/chacha-20080128.pdf and https://tools.ietf.org/html/rfc8439
+ """
+ for a, b, c, d in CHACHA20_INDICES:
+ s[a] = (s[a] + s[b]) & 0xffffffff
+ s[d] = rotl32(s[d] ^ s[a], 16)
+ s[c] = (s[c] + s[d]) & 0xffffffff
+ s[b] = rotl32(s[b] ^ s[c], 12)
+ s[a] = (s[a] + s[b]) & 0xffffffff
+ s[d] = rotl32(s[d] ^ s[a], 8)
+ s[c] = (s[c] + s[d]) & 0xffffffff
+ s[b] = rotl32(s[b] ^ s[c], 7)
+
+def chacha20_block(key, nonce, cnt):
+ """Compute the 64-byte output of the ChaCha20 block function.
+
+ Takes as input a 32-byte key, 12-byte nonce, and 32-bit integer counter.
+ """
+ # Initial state.
+ init = [0 for _ in range(16)]
+ for i in range(4):
+ init[i] = CHACHA20_CONSTANTS[i]
+ for i in range(8):
+ init[4 + i] = int.from_bytes(key[4 * i:4 * (i+1)], 'little')
+ init[12] = cnt
+ for i in range(3):
+ init[13 + i] = int.from_bytes(nonce[4 * i:4 * (i+1)], 'little')
+ # Perform 20 rounds.
+ state = list(init)
+ for _ in range(10):
+ chacha20_doubleround(state)
+ # Add initial values back into state.
+ for i in range(16):
+ state[i] = (state[i] + init[i]) & 0xffffffff
+ # Produce byte output
+ return b''.join(state[i].to_bytes(4, 'little') for i in range(16))
+
+### ChaCha20Poly1305
+
+def aead_chacha20_poly1305_encrypt(key, nonce, aad, plaintext):
+ """Encrypt a plaintext using ChaCha20Poly1305."""
+ ret = bytearray()
+ msg_len = len(plaintext)
+ for i in range((msg_len + 63) // 64):
+ now = min(64, msg_len - 64 * i)
+ keystream = chacha20_block(key, nonce, i + 1)
+ for j in range(now):
+ ret.append(plaintext[j + 64 * i] ^ keystream[j])
+ poly1305 = Poly1305(chacha20_block(key, nonce, 0)[:32])
+ poly1305.add(aad, pad=True).add(ret, pad=True)
+ poly1305.add(len(aad).to_bytes(8, 'little') + msg_len.to_bytes(8, 'little'))
+ ret += poly1305.tag()
+ return bytes(ret)
+
+def aead_chacha20_poly1305_decrypt(key, nonce, aad, ciphertext):
+ """Decrypt a ChaCha20Poly1305 ciphertext."""
+ if len(ciphertext) < 16:
+ return None
+ msg_len = len(ciphertext) - 16
+ poly1305 = Poly1305(chacha20_block(key, nonce, 0)[:32])
+ poly1305.add(aad, pad=True)
+ poly1305.add(ciphertext, length=msg_len, pad=True)
+ poly1305.add(len(aad).to_bytes(8, 'little') + msg_len.to_bytes(8, 'little'))
+ if ciphertext[-16:] != poly1305.tag():
+ return None
+ ret = bytearray()
+ for i in range((msg_len + 63) // 64):
+ now = min(64, msg_len - 64 * i)
+ keystream = chacha20_block(key, nonce, i + 1)
+ for j in range(now):
+ ret.append(ciphertext[j + 64 * i] ^ keystream[j])
+ return bytes(ret)
+
+### FSChaCha20{,Poly1305}
+
+REKEY_INTERVAL = 224 # packets
+
+class FSChaCha20Poly1305:
+ """Rekeying wrapper AEAD around ChaCha20Poly1305."""
+
+ def __init__(self, initial_key):
+ self.key = initial_key
+ self.packet_counter = 0
+
+ def crypt(self, aad, text, is_decrypt):
+ """Encrypt or decrypt the specified (plain/cipher)text."""
+ nonce = ((self.packet_counter % REKEY_INTERVAL).to_bytes(4, 'little') +
+ (self.packet_counter // REKEY_INTERVAL).to_bytes(8, 'little'))
+ if is_decrypt:
+ ret = aead_chacha20_poly1305_decrypt(self.key, nonce, aad, text)
+ else:
+ ret = aead_chacha20_poly1305_encrypt(self.key, nonce, aad, text)
+ if (self.packet_counter + 1) % REKEY_INTERVAL == 0:
+ rekey_nonce = b"\xFF\xFF\xFF\xFF" + nonce[4:]
+ newkey1 = aead_chacha20_poly1305_encrypt(self.key, rekey_nonce, b"", b"\x00" * 32)[:32]
+ newkey2 = chacha20_block(self.key, rekey_nonce, 1)[:32]
+ assert newkey1 == newkey2
+ self.key = newkey1
+ self.packet_counter += 1
+ return ret
+
+ def encrypt(self, aad, plaintext):
+ """Encrypt the specified plaintext with provided AAD."""
+ return self.crypt(aad, plaintext, False)
+
+ def decrypt(self, aad, ciphertext):
+ """Decrypt the specified ciphertext with provided AAD."""
+ return self.crypt(aad, ciphertext, True)
+
+
+class FSChaCha20:
+ """Rekeying wrapper stream cipher around ChaCha20."""
+
+ def __init__(self, initial_key):
+ self.key = initial_key
+ self.block_counter = 0
+ self.chunk_counter = 0
+ self.keystream = b''
+
+ def get_keystream_bytes(self, nbytes):
+ """Generate nbytes keystream bytes."""
+ while len(self.keystream) < nbytes:
+ nonce = ((0).to_bytes(4, 'little') +
+ (self.chunk_counter // REKEY_INTERVAL).to_bytes(8, 'little'))
+ self.keystream += chacha20_block(self.key, nonce, self.block_counter)
+ self.block_counter += 1
+ ret = self.keystream[:nbytes]
+ self.keystream = self.keystream[nbytes:]
+ return ret
+
+ def crypt(self, chunk):
+ """Encrypt or decrypt chunk."""
+ ks = self.get_keystream_bytes(len(chunk))
+ ret = bytes([ks[i] ^ chunk[i] for i in range(len(chunk))])
+ if ((self.chunk_counter + 1) % REKEY_INTERVAL) == 0:
+ self.key = self.get_keystream_bytes(32)
+ self.block_counter = 0
+ self.chunk_counter += 1
+ return ret
+
+ def encrypt(self, chunk):
+ """Encrypt chunk."""
+ return self.crypt(chunk)
+
+ def decrypt(self, chunk):
+ """Decrypt chunk."""
+ return self.crypt(chunk)
+
+
+### Shared secret computation
+
+def v2_ecdh(priv, ellswift_theirs, ellswift_ours, initiating):
+ """Compute BIP324 shared secret."""
+
+ ecdh_point_x32 = ellswift_ecdh_xonly(ellswift_theirs, priv)
+ if initiating:
+ # Initiating, place our public key encoding first.
+ return TaggedHash("bip324_ellswift_xonly_ecdh",
+ ellswift_ours + ellswift_theirs + ecdh_point_x32)
+ # Responding, place their public key encoding first.
+ return TaggedHash("bip324_ellswift_xonly_ecdh",
+ ellswift_theirs + ellswift_ours + ecdh_point_x32)
+
+### Key derivation
+
+NETWORK_MAGIC = b'\xf9\xbe\xb4\xd9'
+
+def initialize_v2_transport(ecdh_secret, initiating):
+ """Return a peer object with various BIP324 derived keys and ciphers."""
+
+ peer = {}
+ salt = b'bitcoin_v2_shared_secret' + NETWORK_MAGIC
+ for name, length in (
+ ('initiator_L', 32), ('initiator_P', 32), ('responder_L', 32), ('responder_P', 32),
+ ('garbage_terminators', 32), ('session_id', 32)):
+ peer[name] = hkdf_sha256(
+ salt=salt, ikm=ecdh_secret, info=name.encode('utf-8'), length=length)
+ peer['initiator_garbage_terminator'] = peer['garbage_terminators'][:16]
+ peer['responder_garbage_terminator'] = peer['garbage_terminators'][16:]
+ del peer['garbage_terminators']
+ if initiating:
+ peer['send_L'] = FSChaCha20(peer['initiator_L'])
+ peer['send_P'] = FSChaCha20Poly1305(peer['initiator_P'])
+ peer['send_garbage_terminator'] = peer['initiator_garbage_terminator']
+ peer['recv_L'] = FSChaCha20(peer['responder_L'])
+ peer['recv_P'] = FSChaCha20Poly1305(peer['responder_P'])
+ peer['recv_garbage_terminator'] = peer['responder_garbage_terminator']
+ else:
+ peer['send_L'] = FSChaCha20(peer['responder_L'])
+ peer['send_P'] = FSChaCha20Poly1305(peer['responder_P'])
+ peer['send_garbage_terminator'] = peer['responder_garbage_terminator']
+ peer['recv_L'] = FSChaCha20(peer['initiator_L'])
+ peer['recv_P'] = FSChaCha20Poly1305(peer['initiator_P'])
+ peer['recv_garbage_terminator'] = peer['initiator_garbage_terminator']
+
+ return peer
+
+### Packet encryption
+
+LENGTH_FIELD_LEN = 3
+HEADER_LEN = 1
+IGNORE_BIT_POS = 7
+
+def v2_enc_packet(peer, contents, aad=b'', ignore=False):
+ """Encrypt a BIP324 packet."""
+
+ assert len(contents) <= 2**24 - 1
+ header = (ignore << IGNORE_BIT_POS).to_bytes(HEADER_LEN, 'little')
+ plaintext = header + contents
+ aead_ciphertext = peer['send_P'].encrypt(aad, plaintext)
+ enc_plaintext_len = peer['send_L'].encrypt(len(contents).to_bytes(LENGTH_FIELD_LEN, 'little'))
+ return enc_plaintext_len + aead_ciphertext
diff --git a/bip-0324/run_test_vectors.py b/bip-0324/run_test_vectors.py
new file mode 100644
index 0000000000..8e4b8f255b
--- /dev/null
+++ b/bip-0324/run_test_vectors.py
@@ -0,0 +1,69 @@
+"""Run the BIP-324 test vectors."""
+
+import csv
+import os
+import sys
+
+import reference
+
+FILENAME_PACKET_TEST = os.path.join(sys.path[0], 'packet_encoding_test_vectors.csv')
+FILENAME_XSWIFTEC_INV_TEST = os.path.join(sys.path[0], 'xswiftec_inv_test_vectors.csv')
+FILENAME_ELLSWIFT_DECODE_TEST = os.path.join(sys.path[0], 'ellswift_decode_test_vectors.csv')
+
+with open(FILENAME_PACKET_TEST, newline='', encoding='utf-8') as csvfile:
+ print(f"Running {FILENAME_PACKET_TEST} tests...")
+ reader = csv.DictReader(csvfile)
+ for row in reader:
+ in_initiating = int(row['in_initiating'])
+ bytes_priv_ours = bytes.fromhex(row['in_priv_ours'])
+ int_priv_ours = int.from_bytes(bytes_priv_ours, 'big')
+ assert row['mid_x_ours'] == (int_priv_ours * reference.SECP256K1_G).x.to_bytes().hex()
+ bytes_ellswift_ours = bytes.fromhex(row['in_ellswift_ours'])
+ assert row['mid_x_ours'] == reference.ellswift_decode(bytes_ellswift_ours).hex()
+ bytes_ellswift_theirs = bytes.fromhex(row['in_ellswift_theirs'])
+ assert row['mid_x_theirs'] == reference.ellswift_decode(bytes_ellswift_theirs).hex()
+ x_shared = reference.ellswift_ecdh_xonly(bytes_ellswift_theirs, bytes_priv_ours)
+ assert row['mid_x_shared'] == x_shared.hex()
+ shared_secret = reference.v2_ecdh(bytes_priv_ours, bytes_ellswift_theirs,
+ bytes_ellswift_ours, in_initiating)
+ assert row['mid_shared_secret'] == shared_secret.hex()
+
+ peer = reference.initialize_v2_transport(shared_secret, in_initiating)
+ assert row['mid_initiator_l'] == peer['initiator_L'].hex()
+ assert row['mid_initiator_p'] == peer['initiator_P'].hex()
+ assert row['mid_responder_l'] == peer['responder_L'].hex()
+ assert row['mid_responder_p'] == peer['responder_P'].hex()
+ assert row['mid_send_garbage_terminator'] == peer['send_garbage_terminator'].hex()
+ assert row['mid_recv_garbage_terminator'] == peer['recv_garbage_terminator'].hex()
+ assert row['out_session_id'] == peer['session_id'].hex()
+ for _ in range(int(row['in_idx'])):
+ reference.v2_enc_packet(peer, b"")
+ ciphertext = reference.v2_enc_packet(
+ peer,
+ bytes.fromhex(row['in_contents']) * int(row['in_multiply']),
+ bytes.fromhex(row['in_aad']), int(row['in_ignore']))
+ if len(row['out_ciphertext']):
+ assert row['out_ciphertext'] == ciphertext.hex()
+ if len(row['out_ciphertext_endswith']):
+ assert ciphertext.hex().endswith(row['out_ciphertext_endswith'])
+
+with open(FILENAME_XSWIFTEC_INV_TEST, newline='', encoding='utf-8') as csvfile:
+ print(f"Running {FILENAME_XSWIFTEC_INV_TEST} tests...")
+ reader = csv.DictReader(csvfile)
+ for row in reader:
+ u = reference.FE.from_bytes(bytes.fromhex(row['u']))
+ x = reference.FE.from_bytes(bytes.fromhex(row['x']))
+ for case in range(8):
+ ret = reference.xswiftec_inv(x, u, case)
+ if ret is None:
+ assert row[f"case{case}_t"] == ""
+ else:
+ assert row[f"case{case}_t"] == ret.to_bytes().hex()
+ assert reference.xswiftec(u, ret) == x
+
+with open(FILENAME_ELLSWIFT_DECODE_TEST, newline='', encoding='utf-8') as csvfile:
+ print(f"Running {FILENAME_ELLSWIFT_DECODE_TEST} tests...")
+ reader = csv.DictReader(csvfile)
+ for row in reader:
+ ellswift = bytes.fromhex(row['ellswift'])
+ assert reference.ellswift_decode(ellswift).hex() == row['x']
diff --git a/bip-0324/secp256k1_test_vectors.py b/bip-0324/secp256k1_test_vectors.py
new file mode 100644
index 0000000000..57ae801cc7
--- /dev/null
+++ b/bip-0324/secp256k1_test_vectors.py
@@ -0,0 +1,52 @@
+"""Convert the BIP-324 test vectors to secp256k1 code."""
+
+import csv
+import reference
+import os
+import sys
+
+FILENAME_XSWIFTEC_INV_TEST = os.path.join(sys.path[0], 'xswiftec_inv_test_vectors.csv')
+FILENAME_ELLSWIFT_DECODE_TEST = os.path.join(sys.path[0], 'ellswift_decode_test_vectors.csv')
+
+def format_int(v):
+ """Format 0 as "0", but other integers as 0x%08x."""
+ if v == 0:
+ return "0"
+ return f"0x{v:08x}"
+
+def format_fe(fe):
+ """Format a field element constant as SECP256K1_FE_CONST code."""
+ vals = [(int(fe) >> (32 * (7 - i))) & 0xffffffff for i in range(8)]
+ strs = ", ".join(format_int(v) for v in vals)
+ return f"SECP256K1_FE_CONST({strs})"
+
+def output_xswiftec_inv_cases():
+ """Generate lines corresponding to the xswiftec_inv test cases."""
+ with open(FILENAME_XSWIFTEC_INV_TEST, newline='', encoding='utf-8') as csvfile:
+ reader = csv.DictReader(csvfile)
+ print("xswiftec_inv cases:")
+ for row in reader:
+ u = int.from_bytes(bytes.fromhex(row['u']), 'big')
+ x = int.from_bytes(bytes.fromhex(row['x']), 'big')
+ pat = sum(1<
+ BIP: 326
+ Layer: Applications
+ Title: Anti-fee-sniping in taproot transactions
+ Author: Chris Belcher
+ Status: Draft
+ Type: Informational
+ Comments-Summary: No comments yet.
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0326
+ Created: 2021-06-10
+ License: CC0-1.0
+ Post-History: 2021-6-10: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-June/019048.html
+
+
+
+== Abstract ==
+
+This document proposes a certain type of wallet behaviour which uses BIP341 taproot[1]. It provides a greater anonymity set for off-chain protocols which will make use of point-time-locked contracts (PTLCs) such as CoinSwap, Lightning and Discrete Log Contracts.
+
+== Motivation ==
+
+With taproot recently added to bitcoin, and wallet software about to implement taproot wallets, we are in a unique position to improve the privacy of off-chain protocols if we act soon.
+
+Taproot allows for point-time-locked contracts (PTLCs) as a more private replacement for hash-time-locked contracts (HTLCs). If an off-chain contract (for example a Lightning channel) is closed using a PTLC instead of an HTLC, then the blockchain will just see a regular taproot script instead of a hash value and preimage. However, if a contract is closed using the timelock path, then the blockchain will either see a OP_CHECKSEQUENCEVERIFY opcode or a nSequence value in the transaction, neither of which are very common today, and this would mark the closing transaction as something special and unusual.
+
+This BIP proposes to improve the privacy and fungibility of off-chain protocols by having on-chain wallets like Bitcoin Core also set the nSequence field in their taproot transactions as in BIP68[5]. This would be in place of their regular nLockTime anti-fee-sniping protection. The end result is that, if an observer of the blockchain sees a taproot spend with an nSequence value, then that could be either: a regular spend from a wallet, or an off-chain settlement transaction spent with a timelock. The two cases would be indistinguishable, and this could greatly improve the privacy and fungibility of bitcoin. The community and wallet developers should act now to implement this so that the anonymity set of nSequence transactions starts to be built up as soon as taproot itself becomes adopted by wallets.
+
+== Background ==
+
+=== Fee sniping ===
+
+Fee sniping is a hypothetical outcome of bad incentives to bitcoin mining in the low-inflation future. For a large miner the value of the transactions in the best block and the mempool can be exceeded by the cost of deliberately attempting to mine two blocks to orphan the best block. However with anti-fee-sniping protection using nLockTime or nSequence the bad miner will soon run out of transactions that can be put in the first block, which means they now need to go in the second. Anti-fee-sniping adds to the incentive to move the blockchain forward.
+
+The nLockTime field is being used this way today. It is implemented in Bitcoin Core[2] and Electrum[3], and adopted by approximately 20% of all recent transactions[4].
+
+=== Absolute vs relative locktime ===
+
+nLockTime is an absolute lock time, it allows the transaction to only be mined after a certain block height or unix time. The widespread adoption of it might have provided a good anonymity set for off-chain protocols. Unfortunately those protocols also commonly use relative lock times, because it allows contracts (for example Lightning payment channels or CoinSwaps) to remain open indefinitely as the countdown clock only starts ticking when the closing transaction is confirmed.
+
+Absolute locktimes are also still used, so we should keep using nLockTime, but also often use nSequence.
+
+=== Transaction pinning ===
+
+Transaction pinning[8] is a method for making fee bumping prohibitively expensive by abusing node protections against attacks that can waste bandwidth, CPU, and memory. This can make fee management more difficult in multipart contract protocols (such as Lightning Network or CoinSwap). One possible way of solving the problem is to include a 1-block relative timelock `1 OP_CSV` to all spend paths, making it impossible to spend the unconfirmed UTXO. Such a 1-block locktime can also be created with an nSequence value of 1. Many on-chain transactions in bitcoin spend inputs that were created just one or two blocks ago, following this BIP such transactions with `nSequence=1` would also provide cover traffic for off-chain transactions which disable transaction pinning.
+
+== Specifications ==
+
+When wallets create transactions spending UTXOs protected by BIP341 taproot, they should set either an nLockTime value or nSequence values to discourage fee sniping, by allowing the transaction to only be mined in the next block after the tip, not the current block. This BIP suggests 50% probability for using nLockTime and 50% for nSequence. If nSequence is set it should apply to at least one of the inputs of the transaction, if it has multiple inputs. It is suggested that on-chain wallets pick an input randomly.
+
+Wallets should also have a second random branch which sets the nLockTime or nSequence value even further back, so that transactions that are delayed after signing for whatever reason (e.g. high-latency mix networks) have better privacy. Existing behaviour is that with a probability of 10%, choose a random number between 0 and 99, and subtract it from the current block height. See the Bitcoin Core and Electrum source codes linked in the references for an example.
+
+nSequence can only encode up to 65535 for the block distance[5] so if the UTXOs being spent have more than 65535 confirmations, then the wallet should use nLockTime instead.
+
+=== Pseudocode ===
+
+
+def apply_anti_fee_sniping_fields(transaction, rbf_set):
+ # bip68 requires v=2
+ transaction.version = 2
+ # Initialize all nsequence to indicate the requested RBF state
+ # nsequence can not be 2**32 - 1 in order for nlocktime to take effect
+ for input in transaction.inputs:
+ if rbf_set:
+ input.nsequence = 2**32 - 3
+ else:
+ input.nsequence = 2**32 - 2
+ # always set nlocktime if any of the transaction inputs have more
+ # confirmations than 65535 or are not taproot inputs, or have
+ # unconfirmed inputs
+ # otherwise choose either nlocktime or nsequence with 50% probability
+ if not rbf_set || any(map(lambda input: input.confirmations() > 65535
+ || !input.is_taproot() || input.confirmations() == 0,
+ transaction.inputs)) || randint(2) == 0:
+ transaction.nlocktime = blockchain.height()
+ if randint(10) == 0:
+ transaction.nlocktime = max(0, transaction.nlocktime
+ - randint(0, 99))
+ # nsequence must be set in order for nlocktime to take effect
+ else:
+ transaction.nlocktime = 0
+ input_index = randint(len(transaction.inputs))
+ transaction.inputs[input_index].nsequence = transaction.inputs\
+ [input_index].confirmations()
+ if randint(10) == 0:
+ transaction.inputs[input_index].nsequence = max(1,
+ transaction.inputs[input_index].nsequence - randint(0, 99))
+
+
+== Compatibility ==
+
+This BIP doesn't need any consensus changes. It can be adopted unilaterally and gradually by wallets. Although for greater privacy it would be good for software to adopt it as soon as possible. Ideally during the process of developers implementing their taproot wallets, so that when taproot starts to be used it will already include the nSequence code.
+
+All wallet software already keeps track of how many confirmations its UTXOs have, so the information required to set the nSequence field is already available.
+
+== Acknowledgements ==
+
+Originally suggested by David Harding[6] and mentioned to me by ZmnSCPxj.
+
+Thanks to craigraw for suggesting a new value for input nsequence in the absolute locktime case[7].
+
+== Copyright ==
+
+This BIP is licensed under the Creative Commons CC0 1.0 Universal licence.
+
+== References ==
+
+[1] https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki
+
+[2] https://github.com/bitcoin/bitcoin/pull/2340
+
+[3]
+https://github.com/spesmilo/electrum/blob/7e6d65ec11c0dccfc24478471c5951d3ae586937/electrum/wallet.py#L211-L224
+
+[4]
+https://txstats.com/dashboard/db/blocks-statistics?panelId=4&fullscreen&orgId=1
+
+[5] https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
+
+[6]
+https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-January/002412.html
+
+[7] https://github.com/sparrowwallet/sparrow/issues/161#issuecomment-925003231
+
+[8] https://bitcoinops.org/en/topics/transaction-pinning/
diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki
new file mode 100644
index 0000000000..7eb8d1a6ab
--- /dev/null
+++ b/bip-0327.mediawiki
@@ -0,0 +1,830 @@
+
+ BIP: 327
+ Title: MuSig2 for BIP340-compatible Multi-Signatures
+ Author: Jonas Nick
+ Tim Ruffing
+ Elliott Jin
+ Status: Active
+ License: BSD-3-Clause
+ Type: Informational
+ Created: 2022-03-22
+ Post-History: 2022-04-05: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-April/020198.html [bitcoin-dev] MuSig2 BIP
+ 2022-10-11: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/021000.html [bitcoin-dev] MuSig2 BIP
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0327
+
+
+== Introduction ==
+
+=== Abstract ===
+
+This document proposes a standard for the [https://eprint.iacr.org/2020/1261.pdf MuSig2] multi-signature scheme.
+The standard is compatible with [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] public keys and signatures.
+It supports ''tweaking'', which allows deriving [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32] child keys from aggregate public keys and creating [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] Taproot outputs with key and script paths.
+
+=== Copyright ===
+
+This document is licensed under the 3-clause BSD license.
+
+=== Motivation ===
+
+MuSig2 is a multi-signature scheme that allows multiple signers to create a single aggregate public key and cooperatively create ordinary Schnorr signatures valid under the aggregate public key.
+Signing requires interaction between ''all'' signers involved in key aggregation.
+(MuSig2 is a ''n-of-n'' multi-signature scheme and not a ''t-of-n'' threshold-signature scheme.)
+
+The primary motivation is to create a standard that allows users of different software projects to jointly control Taproot outputs ([https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341]).
+Such an output contains a public key which, in this case, would be the aggregate of all users' individual public keys.
+It can be spent using MuSig2 to produce a signature for the key-based spending path.
+
+The on-chain footprint of a MuSig2 Taproot output is essentially a single BIP340 public key, and a transaction spending the output only requires a single signature cooperatively produced by all signers. This is '''more compact''' and has '''lower verification cost''' than each signer providing an individual public key and signature, as would be required by an ''n-of-n'' policy implemented using OP_CHECKSIGADD as introduced in ([https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki BIP342]).
+As a side effect, the number ''n'' of signers is not limited by any consensus rules when using MuSig2.
+
+Moreover, MuSig2 offers a '''higher level of privacy''' than OP_CHECKSIGADD: MuSig2 Taproot outputs are indistinguishable for a blockchain observer from regular, single-signer Taproot outputs even though they are actually controlled by multiple signers. By tweaking an aggregate public key, the shared Taproot output can have script spending paths that are hidden unless used.
+
+There are multi-signature schemes other than MuSig2 that are fully compatible with Schnorr signatures.
+The MuSig2 variant proposed below stands out by combining all the following features:
+* '''Simple Key Setup''': Key aggregation is non-interactive and fully compatible with BIP340 public keys.
+* '''Two Communication Rounds''': MuSig2 is faster in practice than previous three-round multi-signature schemes such as [https://eprint.iacr.org/2018/068.pdf MuSig1], particularly when signers are connected through high-latency anonymous links. Moreover, the need for fewer communication rounds simplifies the algorithms and reduces the probability that implementations and users make security-relevant mistakes.
+* '''Provable security''': MuSig2 has been [https://eprint.iacr.org/2020/1261.pdf proven existentially unforgeable] under the algebraic one-more discrete logarithm (AOMDL) assumption (instead of the discrete logarithm assumption required for single-signer Schnorr signatures). AOMDL is a falsifiable and weaker variant of the well-studied OMDL problem.
+* '''Low complexity''': MuSig2 has a substantially lower computational and implementation complexity than alternative schemes like [https://eprint.iacr.org/2020/1057 MuSig-DN]. However, this comes at the cost of having no ability to generate nonces deterministically and the requirement to securely handle signing state.
+
+=== Design ===
+
+* '''Compatibility with BIP340''': In this proposal, the aggregate public key is a BIP340 X-only public key, and the signature output at the end of the signing protocol is a BIP340 signature that passes BIP340 verification for the aggregate public key and a message. The individual public keys that are input to the key aggregation algorithm are ''plain'' public keys in compressed format.
+* '''Tweaking for BIP32 derivations and Taproot''': This proposal supports tweaking aggregate public keys and signing for tweaked aggregate public keys. We distinguish two modes of tweaking: ''Plain'' tweaking can be used to derive child aggregate public keys per [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32]. ''X-only'' tweaking, on the other hand, allows creating a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] tweak to add script paths to a Taproot output. See [[#tweaking-the-aggregate-public-key|below]] for details.
+* '''Non-interactive signing with preprocessing''': The first communication round, exchanging the nonces, can happen before the message or the exact set of signers is determined. Once the parameters of the signing session are finalized, the signers can send partial signatures without additional interaction.
+* '''Key aggregation optionally independent of order''': The output of the key aggregation algorithm depends on the order in which the individual public keys are provided as input. Key aggregation does not sort the individual public keys by default because applications often already have a canonical order of signers. Nonetheless, applications can mandate sorting before aggregation,Applications that sort individual public keys before aggregation should ensure that the implementation of sorting is reasonably efficient, and in particular does not degenerate to quadratic runtime on pathological inputs. and this proposal specifies a canonical order to sort the individual public keys before key aggregation. Sorting will ensure the same output, independent of the initial order.
+* '''Third-party nonce and partial signature aggregation''': Instead of every signer sending their nonce and partial signature to every other signer, it is possible to use an untrusted third-party ''aggregator'' in order to reduce the communication complexity from quadratic to linear in the number of signers. In each of the two rounds, the aggregator collects all signers' contributions (nonces or partial signatures), aggregates them, and broadcasts the aggregate back to the signers. A malicious aggregator can force the signing session to fail to produce a valid Schnorr signature but cannot negatively affect the unforgeability of the scheme.
+* '''Partial signature verification''': If any signer sends a partial signature contribution that was not created by honestly following the signing protocol, the signing session will fail to produce a valid Schnorr signature. This proposal specifies a partial signature verification algorithm to identify disruptive signers. It is incompatible with third-party nonce aggregation because the individual nonce is required for partial verification.
+* '''MuSig2* optimization''': This proposal uses an optimized scheme MuSig2*, which allows saving a point multiplication in key aggregation as compared to MuSig2. MuSig2* is proven secure in the appendix of the [https://eprint.iacr.org/2020/1261 MuSig2 paper]. The optimization consists of assigning the constant key aggregation coefficient ''1'' to the second distinct key in the list of individual public keys to be aggregated (as well as to any key identical to this key).
+* '''Size of the nonce and security''': In this proposal, each signer's nonce consists of two elliptic curve points. The [https://eprint.iacr.org/2020/1261 MuSig2 paper] gives distinct security proofs depending on the number of points that constitute a nonce. See section [[#choosing-the-size-of-the-nonce|Choosing the Size of the Nonce]] for a discussion.
+
+== Overview ==
+
+Implementers must make sure to understand this section thoroughly to avoid subtle mistakes that may lead to catastrophic failure.
+
+=== Optionality of Features ===
+
+The goal of this proposal is to support a wide range of possible application scenarios.
+Given a specific application scenario, some features may be unnecessary or not desirable, and implementers can choose not to support them.
+Such optional features include:
+* Applying plain tweaks after x-only tweaks.
+* Applying tweaks at all.
+* Dealing with messages that are not exactly 32 bytes.
+* Identifying a disruptive signer after aborting (aborting itself remains mandatory).
+* Dealing with duplicate individual public keys in key aggregation.
+If applicable, the corresponding algorithms should simply fail when encountering inputs unsupported by a particular implementation. (For example, the signing algorithm may fail when given a message which is not 32 bytes.)
+Similarly, the test vectors that exercise the unimplemented features should be re-interpreted to expect an error, or be skipped if appropriate.
+
+=== General Signing Flow ===
+
+The signers start by exchanging their individual public keys and computing an aggregate public key using the ''KeyAgg'' algorithm.
+Whenever they want to sign a message, the basic order of operations to create a multi-signature is as follows:
+
+'''First broadcast round:'''
+The signers start the signing session by running ''NonceGen'' to compute ''secnonce'' and ''pubnonce''.We treat the ''secnonce'' and ''pubnonce'' as grammatically singular even though they include serializations of two scalars and two elliptic curve points, respectively. This treatment may be confusing for readers familiar with the MuSig2 paper. However, serialization is a technical detail that is irrelevant for users of MuSig2 interfaces.
+Then, the signers broadcast their ''pubnonce'' to each other and run ''NonceAgg'' to compute an aggregate nonce.
+
+'''Second broadcast round:'''
+At this point, every signer has the required data to sign, which, in the algorithms specified below, is stored in a data structure called [[#session-context|Session Context]].
+Every signer computes a partial signature by running ''Sign'' with the secret signing key, the ''secnonce'' and the session context.
+Then, the signers broadcast their partial signatures to each other and run ''PartialSigAgg'' to obtain the final signature.
+If all signers behaved honestly, the result passes [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] verification.
+
+Both broadcast rounds can be optimized by using an aggregator who collects all signers' nonces or partial signatures, aggregates them using ''NonceAgg'' or ''PartialSigAgg'', respectively, and broadcasts the aggregate result back to the signers. A malicious aggregator can force the signing session to fail to produce a valid Schnorr signature but cannot negatively affect the unforgeability of the scheme, i.e., even a malicious aggregator colluding with all but one signer cannot forge a signature.
+
+'''IMPORTANT''': The ''Sign'' algorithm must '''not''' be executed twice with the same ''secnonce''.
+Otherwise, it is possible to extract the secret signing key from the two partial signatures output by the two executions of ''Sign''.
+To avoid accidental reuse of ''secnonce'', an implementation may securely erase the ''secnonce'' argument by overwriting it with 64 zero bytes after it has been read by ''Sign''.
+A ''secnonce'' consisting of only zero bytes is invalid for ''Sign'' and will cause it to fail.
+
+To simplify the specification of the algorithms, some intermediary values are unnecessarily recomputed from scratch, e.g., when executing ''GetSessionValues'' multiple times.
+Actual implementations can cache these values.
+As a result, the [[#session-context|Session Context]] may look very different in implementations or may not exist at all.
+However, computation of ''GetSessionValues'' and storage of the result must be protected against modification from an untrusted third party.
+This party would have complete control over the aggregate public key and message to be signed.
+
+=== Public Key Aggregation ===
+
+We distinguish between two public key types, namely ''plain public keys'', the key type traditionally used in Bitcoin, and ''X-only public keys''.
+Plain public keys are byte strings of length 33 (often called ''compressed'' format).
+In contrast, X-only public keys are 32-byte strings defined in [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340].
+
+The individual public keys of signers as input to the key aggregation algorithm ''KeyAgg'' (and to ''GetSessionValues'' and ''PartialSigVerify'') are plain public keys.
+The output of ''KeyAgg'' is a [[#keyagg-context|KeyAgg Context]] which stores information required for tweaking the aggregate public key (see [[#tweaking-the-aggregate-public-key|below]]),
+and it can be used to produce an X-only aggregate public key, or a plain aggregate public key.
+In order to obtain an X-only public key compatible with BIP340 verification, implementations call the ''GetXonlyPubkey'' function with the KeyAgg Context.
+To get the plain aggregate public key, which is required for some applications of [[#tweaking-the-aggregate-public-key|tweaking]], implementations call ''GetPlainPubkey'' instead.
+
+The aggregate public key produced by ''KeyAgg'' (regardless of the type) depends on the order of the individual public keys.
+If the application does not have a canonical order of the signers, the individual public keys can be sorted with the ''KeySort'' algorithm to ensure that the aggregate public key is independent of the order of signers.
+
+The same individual public key is allowed to occur more than once in the input of ''KeyAgg'' and ''KeySort''.
+This is by design: All algorithms in this proposal handle multiple signers who (claim to) have identical individual public keys properly,
+and applications are not required to check for duplicate individual public keys.
+In fact, applications are recommended to omit checks for duplicate individual public keys in order to simplify error handling.
+Moreover, it is often impossible to tell at key aggregation which signer is to blame for the duplicate, i.e., which signer came up with an individual public key honestly and which disruptive signer copied it.
+In contrast, MuSig2 is designed to identify disruptive signers at signing time (see [[#identifying-disruptive-signers|Identifying Disruptive Signers]]).
+
+While the algorithms in this proposal are able to handle duplicate individual public keys, there are scenarios where applications may choose to abort when encountering duplicates.
+For example, we can imagine a scenario where a single entity creates a MuSig2 setup with multiple signing devices.
+In that case, duplicates may not result from a malicious signing device copying an individual public key of another signing device but from accidental initialization of two devices with the same seed.
+Since MuSig2 key aggregation would accept the duplicate keys and not error out, which would in turn reduce the security compared to the intended key setup, applications may reject duplicate individual public keys before passing them to MuSig2 key aggregation and ask the user to investigate.
+
+=== Nonce Generation ===
+
+'''IMPORTANT''': ''NonceGen'' must have access to a high-quality random generator to draw an unbiased, uniformly random value ''rand' ''.
+In contrast to BIP340 signing, the values ''k1'' and ''k2'' '''must not be derived deterministically''' from the session parameters because otherwise active adversaries can [https://medium.com/blockstream/musig-dn-schnorr-multisignatures-with-verifiably-deterministic-nonces-27424b5df9d6#e3b6 trick the victim into reusing a nonce].
+
+The optional arguments to ''NonceGen'' enable a defense-in-depth mechanism that may prevent secret key exposure if ''rand' '' is accidentally not drawn uniformly at random.
+If the value ''rand' '' was identical in two ''NonceGen'' invocations, but any other argument was different, the ''secnonce'' would still be guaranteed to be different as well (with overwhelming probability), and thus accidentally using the same ''secnonce'' for ''Sign'' in both sessions would be avoided.
+Therefore, it is recommended to provide the optional arguments ''sk'', ''aggpk'', and ''m'' if these session parameters are already determined during nonce generation.
+The auxiliary input ''extra_in'' can contain additional contextual data that has a chance of changing between ''NonceGen'' runs,
+e.g., a supposedly unique session id (taken from the application), a session counter wide enough not to repeat in practice, any nonces by other signers (if already known), or the serialization of a data structure containing multiple of the above.
+However, the protection provided by the optional arguments should only be viewed as a last resort.
+In most conceivable scenarios, the assumption that the arguments are different between two executions of ''NonceGen'' is relatively strong, particularly when facing an active adversary.
+
+In some applications, it is beneficial to generate and send a ''pubnonce'' before the other signers, their individual public keys, or the message to sign is known.
+In this case, only the available arguments are provided to the ''NonceGen'' algorithm.
+After this preprocessing phase, the ''Sign'' algorithm can be run immediately when the message and set of signers is determined.
+This way, the final signature is created quicker and with fewer round trips.
+However, applications that use this method presumably store the nonces for a longer time and must therefore be even more careful not to reuse them.
+Moreover, this method is not compatible with the defense-in-depth mechanism described in the previous paragraph.
+
+Instead of every signer broadcasting their ''pubnonce'' to every other signer, the signers can send their ''pubnonce'' to a single aggregator node that runs ''NonceAgg'' and sends the ''aggnonce'' back to the signers.
+This technique reduces the overall communication.
+A malicious aggregator can force the signing session to fail to produce a valid Schnorr signature but cannot negatively affect the unforgeability of the scheme.
+
+In general, MuSig2 signers are stateful in the sense that they first generate ''secnonce'' and then need to store it until they receive the other signers' ''pubnonces'' or the ''aggnonce''.
+However, it is possible for one of the signers to be stateless.
+This signer waits until it receives the ''pubnonce'' of all the other signers and until session parameters such as a message to sign, individual public keys, and tweaks are determined.
+Then, the signer can run ''NonceGen'', ''NonceAgg'' and ''Sign'' in sequence and send out its ''pubnonce'' along with its partial signature.
+Stateless signers may want to consider signing deterministically (see [[#modifications-to-nonce-generation|Modifications to Nonce Generation]]) to remove the reliance on the random number generator in the ''NonceGen'' algorithm.
+
+=== Identifying Disruptive Signers ===
+
+The signing protocol makes it possible to identify malicious signers who send invalid contributions to a signing session in order to make the signing session abort and prevent the honest signers from obtaining a valid signature.
+This property is called "identifiable aborts" and ensures that honest parties can assign blame to malicious signers who cause an abort in the signing protocol.
+
+Aborts are identifiable for an honest party if the following conditions hold in a signing session:
+* The contributions received from all signers have not been tampered with (e.g., because they were sent over authenticated connections).
+* Nonce aggregation is performed honestly (e.g., because the honest signer performs nonce aggregation on its own or because the aggregator is trusted).
+* The partial signatures received from all signers are verified using the algorithm ''PartialSigVerify''.
+
+If these conditions hold and an honest party (signer or aggregator) runs an algorithm that fails due to invalid protocol contributions from malicious signers, then the algorithm run by the honest party will output the index of exactly one malicious signer.
+Additionally, if the honest parties agree on the contributions sent by all signers in the signing session, all the honest parties who run the aborting algorithm will identify the same malicious signer.
+
+==== Further Remarks ====
+
+Some of the algorithms specified below may also assign blame to a malicious aggregator.
+While this is possible for some particular misbehavior of the aggregator, it is not guaranteed that a malicious aggregator can be identified.
+More specifically, a malicious aggregator (whose existence violates the second condition above) can always make signing abort and wrongly hold honest signers accountable for the abort (e.g., by claiming to have received an invalid contribution from a particular honest signer).
+
+The only purpose of the algorithm ''PartialSigVerify'' is to ensure identifiable aborts, and it is not necessary to use it when identifiable aborts are not desired.
+In particular, partial signatures are ''not'' signatures.
+An adversary can forge a partial signature, i.e., create a partial signature without knowing the secret key for the claimed individual public key.Assume an adversary wants to forge a partial signature for individual public key ''P''. It joins the signing session pretending to be two different signers, one with individual public key ''P'' and one with another individual public key. The adversary can then set the second signer's nonce such that it will be able to produce a partial signature for ''P'' but not for the other claimed signer. An explanation of the individual steps required to create a partial signature forgery can be found in [https://gist.github.com/AdamISZ/ca974ed67889cedc738c4a1f65ff620b a write up by Adam Gibson].
+However, if ''PartialSigVerify'' succeeds for all partial signatures then ''PartialSigAgg'' will return a valid Schnorr signature.Given a list of individual public keys, it is an open question whether a BIP-340 signature valid under the corresponding aggregate public key is a proof of knowledge of all secret keys of the individual public keys.
+
+=== Tweaking the Aggregate Public Key ===
+
+The aggregate public key can be ''tweaked'', which modifies the key as defined in the [[#tweaking-definition|Tweaking Definition]] subsection.
+In order to apply a tweak, the KeyAgg Context output by ''KeyAgg'' is provided to the ''ApplyTweak'' algorithm with the ''is_xonly_t'' argument set to false for plain tweaking and true for X-only tweaking.
+The resulting KeyAgg Context can be used to apply another tweak with ''ApplyTweak'' or obtain the aggregate public key with ''GetXonlyPubkey'' or ''GetPlainPubkey''.
+
+The purpose of supporting tweaking is to ensure compatibility with existing uses of tweaking, i.e., that the result of signing is a valid signature for the tweaked public key.
+The MuSig2 algorithms take arbitrary tweaks as input but accepting arbitrary tweaks may negatively affect the security of the scheme.It is an open question whether allowing arbitrary tweaks from an adversary affects the unforgeability of MuSig2.
+Instead, signers should obtain the tweaks according to other specifications.
+This typically involves deriving the tweaks from a hash of the aggregate public key and some other information.
+Depending on the specific scheme that is used for tweaking, either the plain or the X-only aggregate public key is required.
+For example, to do [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32] derivation, you call ''GetPlainPubkey'' to be able to compute the tweak, whereas [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] TapTweaks require X-only public keys that are obtained with ''GetXonlyPubkey''.
+
+The tweak mode provided to ''ApplyTweak'' depends on the application:
+Plain tweaking can be used to derive child public keys from an aggregate public key using [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32].
+On the other hand, X-only tweaking is required for Taproot tweaking per [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341].
+A Taproot-tweaked public key commits to a ''script path'', allowing users to create transaction outputs that are spendable either with a MuSig2 multi-signature or by providing inputs that satisfy the script path.
+Script path spends require a control block that contains a parity bit for the tweaked X-only public key.
+The bit can be obtained with ''GetPlainPubkey(keyagg_ctx)[0] & 1''.
+
+== Algorithms ==
+
+The following specification of the algorithms has been written with a focus on clarity.
+As a result, the specified algorithms are not always optimal in terms of computation and space.
+In particular, some values are recomputed but can be cached in actual implementations (see [[#general-signing-flow|General Signing Flow]]).
+
+=== Notation ===
+
+The following conventions are used, with constants as defined for [https://www.secg.org/sec2-v2.pdf secp256k1]. We note that adapting this proposal to other elliptic curves is not straightforward and can result in an insecure scheme.
+* Lowercase variables represent integers or byte arrays.
+** The constant ''p'' refers to the field size, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F''.
+** The constant ''n'' refers to the curve order, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141''.
+* Uppercase variables refer to points on the curve with equation ''y2 = x3 + 7'' over the integers modulo ''p''.
+** ''is_infinite(P)'' returns whether ''P'' is the point at infinity.
+** ''x(P)'' and ''y(P)'' are integers in the range ''0..p-1'' and refer to the X and Y coordinates of a point ''P'' (assuming it is not infinity).
+** The constant ''G'' refers to the base point, for which ''x(G) = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798'' and ''y(G) = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8''.
+** Addition of points refers to the usual [https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law elliptic curve group operation].
+** [https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication Multiplication (⋅) of an integer and a point] refers to the repeated application of the group operation.
+* Functions and operations:
+** ''||'' refers to byte array concatenation.
+** The function ''x[i:j]'', where ''x'' is a byte array and ''i, j ≥ 0'', returns a ''(j - i)''-byte array with a copy of the ''i''-th byte (inclusive) to the ''j''-th byte (exclusive) of ''x''.
+** The function ''bytes(n, x)'', where ''x'' is an integer, returns the n-byte encoding of ''x'', most significant byte first.
+** The constant ''empty_bytestring'' refers to the empty byte array. It holds that ''len(empty_bytestring) = 0''.
+** The function ''xbytes(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''bytes(32, x(P))''.
+** The function ''len(x)'' where ''x'' is a byte array returns the length of the array.
+** The function ''has_even_y(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''y(P) mod 2 == 0''.
+** The function ''with_even_y(P)'', where ''P'' is a point, returns ''P'' if ''is_infinite(P)'' or ''has_even_y(P)''. Otherwise, ''with_even_y(P)'' returns ''-P''.
+** The function ''cbytes(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''a || xbytes(P)'' where ''a'' is a byte that is ''2'' if ''has_even_y(P)'' and ''3'' otherwise.
+** The function ''cbytes_ext(P)'', where ''P'' is a point, returns ''bytes(33, 0)'' if ''is_infinite(P)''. Otherwise, it returns ''cbytes(P)''.
+** The function ''int(x)'', where ''x'' is a 32-byte array, returns the 256-bit unsigned integer whose most significant byte first encoding is ''x''.
+** The function ''lift_x(x)'', where ''x'' is an integer in range ''0..2256-1'', returns the point ''P'' for which ''x(P) = x''
+ Given a candidate X coordinate ''x'' in the range ''0..p-1'', there exist either exactly two or exactly zero valid Y coordinates. If no valid Y coordinate exists, then ''x'' is not a valid X coordinate either, i.e., no point ''P'' exists for which ''x(P) = x''. The valid Y coordinates for a given candidate ''x'' are the square roots of ''c = x3 + 7 mod p'' and they can be computed as ''y = ±c(p+1)/4 mod p'' (see [https://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus Quadratic residue]) if they exist, which can be checked by squaring and comparing with ''c''. and ''has_even_y(P)'', or fails if ''x'' is greater than ''p-1'' or no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode:
+*** Fail if ''x > p-1''.
+*** Let ''c = x3 + 7 mod p''.
+*** Let ''y' = c(p+1)/4 mod p''.
+*** Fail if ''c ≠ y'2 mod p''.
+*** Let ''y = y' '' if ''y' mod 2 = 0'', otherwise let ''y = p - y' ''.
+*** Return the unique point ''P'' such that ''x(P) = x'' and ''y(P) = y''.
+** The function ''cpoint(x)'', where ''x'' is a 33-byte array (compressed serialization), sets ''P = lift_x(int(x[1:33]))'' and fails if that fails. If ''x[0] = 2'' it returns ''P'' and if ''x[0] = 3'' it returns ''-P''. Otherwise, it fails.
+** The function ''cpoint_ext(x)'', where ''x'' is a 33-byte array (compressed serialization), returns the point at infinity if ''x = bytes(33, 0)''. Otherwise, it returns ''cpoint(x)'' and fails if that fails.
+** The function ''hashtag(x)'' where ''tag'' is a UTF-8 encoded tag name and ''x'' is a byte array returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)''.
+* Other:
+** Tuples are written by listing the elements within parentheses and separated by commas. For example, ''(2, 3, 1)'' is a tuple.
+
+=== Key Generation and Aggregation ===
+
+==== Key Generation of an Individual Signer ====
+
+
+Algorithm ''IndividualPubkey(sk)'':The ''IndividualPubkey'' algorithm matches the key generation procedure traditionally used for ECDSA in Bitcoin
+* Inputs:
+** The secret key ''sk'': a 32-byte array, freshly generated uniformly at random
+* Let ''d' = int(sk)''.
+* Fail if ''d' = 0'' or ''d' ≥ n''.
+* Return ''cbytes(d'⋅G)''.
+
+
+==== KeyAgg Context ====
+
+The KeyAgg Context is a data structure consisting of the following elements:
+* The point ''Q'' representing the potentially tweaked aggregate public key: an elliptic curve point
+* The accumulated tweak ''tacc'': an integer with ''0 ≤ tacc < n''
+* The value ''gacc'' : 1 or -1 mod n
+
+We write "Let ''(Q, gacc, tacc) = keyagg_ctx''" to assign names to the elements of a KeyAgg Context.
+
+
+Algorithm ''KeySort(pk1..u)'':
+* Inputs:
+** The number ''u'' of individual public keys with ''0 < u < 2^32''
+** The individual public keys ''pk1..u'': ''u'' 33-byte arrays
+* Return ''pk1..u'' sorted in lexicographical order.
+
+
+==== Key Aggregation ====
+
+
+Algorithm ''KeyAgg(pk1..u)'':
+* Inputs:
+** The number ''u'' of individual public keys with ''0 < u < 2^32''
+** The individual public keys ''pk1..u'': ''u'' 33-byte arrays
+* Let ''pk2 = GetSecondKey(pk1..u)''
+* For ''i = 1 .. u'':
+** Let ''Pi = cpoint(pki)''; fail if that fails and blame signer ''i'' for invalid individual public key.
+** Let ''ai = KeyAggCoeffInternal(pk1..u, pki, pk2)''.
+* Let ''Q = a1⋅P1 + a2⋅P2 + ... + au⋅Pu''
+* Fail if ''is_infinite(Q)''.
+* Let ''gacc = 1''
+* Let ''tacc = 0''
+* Return ''keyagg_ctx = (Q, gacc, tacc)''.
+
+Internal Algorithm ''KeyAggCoeffInternal(pk1..u, pk', pk2)'':
+* Let ''L = HashKeys(pk1..u)''
+* If ''pk' = pk2'':
+** Return 1
+* Return ''int(hashKeyAgg coefficient(L || pk')) mod n''The key aggregation coefficient is computed by hashing the individual public key instead of its index, which requires one more invocation of the SHA-256 compression function. However, it results in significantly simpler implementations because signers do not need to translate between public key indices before and after sorting.
+
+
+==== Applying Tweaks ====
+
+
+Algorithm ''ApplyTweak(keyagg_ctx, tweak, is_xonly_t)'':
+* Inputs:
+** The ''keyagg_ctx'': a [[#keyagg-context|KeyAgg Context]] data structure
+** The ''tweak'': a 32-byte array
+** The tweak mode ''is_xonly_t'': a boolean
+* Let ''(Q, gacc, tacc) = keyagg_ctx''
+* If ''is_xonly_t'' and ''not has_even_y(Q)'':
+** Let ''g = -1 mod n''
+* Else:
+** Let ''g = 1''
+* Let ''t = int(tweak)''; fail if ''t ≥ n''
+* Let ''Q' = g⋅Q + t⋅G''
+** Fail if ''is_infinite(Q')''
+* Let ''gacc' = g⋅gacc mod n''
+* Let ''tacc' = t + g⋅tacc mod n''
+* Return ''keyagg_ctx' = (Q', gacc', tacc')''
+
+
+=== Nonce Generation ===
+
+
+Algorithm ''NonceGen(sk, pk, aggpk, m, extra_in)'':
+* Inputs:
+** The secret signing key ''sk'': a 32-byte array (optional argument)
+** The individual public key ''pk'': a 33-byte array (see [[#signing-with-tweaked-individual-keys|Signing with Tweaked Individual Keys]] for the reason that this argument is mandatory)
+** The x-only aggregate public key ''aggpk'': a 32-byte array (optional argument)
+** The message ''m'': a byte array (optional argument)In theory, the allowed message size is restricted because SHA256 accepts byte strings only up to size of 2^61-1 bytes (and because of the 8-byte length encoding).
+** The auxiliary input ''extra_in'': a byte array with ''0 ≤ len(extra_in) ≤ 232-1'' (optional argument)
+* Let ''rand' '' be a 32-byte array freshly drawn uniformly at random
+* If the optional argument ''sk'' is present:
+** Let ''rand'' be the byte-wise xor of ''sk'' and ''hashMuSig/aux(rand')''The random data is hashed (with a unique tag) as a precaution against situations where the randomness may be correlated with the secret signing key itself. It is xored with the secret key (rather than combined with it in a hash) to reduce the number of operations exposed to the actual secret key.
+* Else:
+** Let ''rand = rand' ''
+* If the optional argument ''aggpk'' is not present:
+** Let ''aggpk = empty_bytestring''
+* If the optional argument ''m'' is not present:
+** Let ''m_prefixed = bytes(1, 0)''
+* Else:
+** Let ''m_prefixed = bytes(1, 1) || bytes(8, len(m)) || m''
+* If the optional argument ''extra_in'' is not present:
+** Let ''extra_in = empty_bytestring''
+* Let ''ki = int(hashMuSig/nonce(rand || bytes(1, len(pk)) || pk || bytes(1, len(aggpk)) || aggpk || m_prefixed || bytes(4, len(extra_in)) || extra_in || bytes(1, i - 1))) mod n'' for ''i = 1,2''
+* Fail if ''k1 = 0'' or ''k2 = 0''
+* Let ''R⁎,1 = k1⋅G, R⁎,2 = k2⋅G''
+* Let ''pubnonce = cbytes(R⁎,1) || cbytes(R⁎,2)''
+* Let ''secnonce = bytes(32, k1) || bytes(32, k2) || pk''The algorithms as specified here assume that the ''secnonce'' is stored as a 97-byte array using the serialization ''secnonce = bytes(32, k1) || bytes(32, k2) || pk''. The same format is used in the reference implementation and in the test vectors. However, since the ''secnonce'' is (obviously) not meant to be sent over the wire, compatibility between implementations is not a concern, and this method of storing the ''secnonce'' is merely a suggestion.
+The ''secnonce'' is effectively a local data structure of the signer which comprises the value triple ''(k1, k2, pk)'', and implementations may choose any suitable method to carry it from ''NonceGen'' (first communication round) to ''Sign'' (second communication round). In particular, implementations may choose to hide the ''secnonce'' in internal state without exposing it in an API explicitly, e.g., in an effort to prevent callers from reusing a ''secnonce'' accidentally.
+* Return ''(secnonce, pubnonce)''
+
+
+=== Nonce Aggregation ===
+
+
+Algorithm ''NonceAgg(pubnonce1..u)'':
+* Inputs:
+** The number ''u'' of ''pubnonces'' with ''0 < u < 2^32''
+** The public nonces ''pubnonce1..u'': ''u'' 66-byte arrays
+* For ''j = 1 .. 2'':
+** For ''i = 1 .. u'':
+*** Let ''Ri,j = cpoint(pubnoncei[(j-1)*33:j*33])''; fail if that fails and blame signer ''i'' for invalid ''pubnonce''.
+** Let ''Rj = R1,j + R2,j + ... + Ru,j''
+* Return ''aggnonce = cbytes_ext(R1) || cbytes_ext(R2)''
+
+
+=== Session Context ===
+
+The Session Context is a data structure consisting of the following elements:
+* The aggregate public nonce ''aggnonce'': a 66-byte array
+* The number ''u'' of individual public keys with ''0 < u < 2^32''
+* The individual public keys ''pk1..u'': ''u'' 33-byte arrays
+* The number ''v'' of tweaks with ''0 ≤ v < 2^32''
+* The tweaks ''tweak1..v'': ''v'' 32-byte arrays
+* The tweak modes ''is_xonly_t1..v'' : ''v'' booleans
+* The message ''m'': a byte array
+
+We write "Let ''(aggnonce, u, pk1..u, v, tweak1..v, is_xonly_t1..v, m) = session_ctx''" to assign names to the elements of a Session Context.
+
+
+Algorithm ''GetSessionValues(session_ctx)'':
+* Let ''(aggnonce, u, pk1..u, v, tweak1..v, is_xonly_t1..v, m) = session_ctx''
+* Let ''keyagg_ctx0 = KeyAgg(pk1..u)''; fail if that fails
+* For ''i = 1 .. v'':
+** Let ''keyagg_ctxi = ApplyTweak(keyagg_ctxi-1, tweaki, is_xonly_ti)''; fail if that fails
+* Let ''(Q, gacc, tacc) = keyagg_ctxv''
+* Let ''b = int(hashMuSig/noncecoef(aggnonce || xbytes(Q) || m)) mod n''
+* Let ''R1 = cpoint_ext(aggnonce[0:33]), R2 = cpoint_ext(aggnonce[33:66])''; fail if that fails and blame nonce aggregator for invalid ''aggnonce''.
+* Let ''R' = R1 + b⋅R2''
+* If ''is_infinite(R'):
+** Let final nonce ''R = G'' (see [[#dealing-with-infinity-in-nonce-aggregation|Dealing with Infinity in Nonce Aggregation]])
+* Else:
+** Let final nonce ''R = R' ''
+* Let ''e = int(hashBIP0340/challenge(xbytes(R) || xbytes(Q) || m)) mod n''
+* Return ''(Q, gacc, tacc, b, R, e)''
+
+
+
+Algorithm ''GetSessionKeyAggCoeff(session_ctx, P)'':
+* Let ''(_, u, pk1..u, _, _, _, _) = session_ctx''
+* Let ''pk = cbytes(P)''
+* Fail if ''pk'' not in ''pk1..u''
+* Return ''KeyAggCoeff(pk1..u, pk)''
+
+
+=== Signing ===
+
+
+Algorithm ''Sign(secnonce, sk, session_ctx)'':
+* Inputs:
+** The secret nonce ''secnonce'' that has never been used as input to ''Sign'' before: a 97-byte array
+** The secret key ''sk'': a 32-byte array
+** The ''session_ctx'': a [[#session-context|Session Context]] data structure
+* Let ''(Q, gacc, _, b, R, e) = GetSessionValues(session_ctx)''; fail if that fails
+* Let ''k1' = int(secnonce[0:32]), k2' = int(secnonce[32:64])''
+* Fail if ''ki' = 0'' or ''ki' ≥ n'' for ''i = 1..2''
+* Let ''k1 = k1', k2 = k2' '' if ''has_even_y(R)'', otherwise let ''k1 = n - k1', k2 = n - k2' ''
+* Let ''d' = int(sk)''
+* Fail if ''d' = 0'' or ''d' ≥ n''
+* Let ''P = d'⋅G''
+* Let ''pk = cbytes(P)''
+* Fail if ''pk ≠ secnonce[64:97]''
+* Let ''a = GetSessionKeyAggCoeff(session_ctx, P)''; fail if that failsFailing ''Sign'' when ''GetSessionKeyAggCoeff(session_ctx, P)'' fails is not necessary for unforgeability. It merely indicates to the caller that the scheme is not being used correctly.
+* Let ''g = 1'' if ''has_even_y(Q)'', otherwise let ''g = -1 mod n''
+* Let ''d = g⋅gacc⋅d' mod n'' (See [[#negation-of-the-secret-key-when-signing|Negation Of The Secret Key When Signing]])
+* Let ''s = (k1 + b⋅k2 + e⋅a⋅d) mod n''
+* Let ''psig = bytes(32, s)''
+* Let ''pubnonce = cbytes(k1'⋅G) || cbytes(k2'⋅G)''
+* If ''PartialSigVerifyInternal(psig, pubnonce, pk, session_ctx)'' (see below) returns failure, failVerifying the signature before leaving the signer prevents random or adversarially provoked computation errors. This prevents publishing invalid signatures which may leak information about the secret key. It is recommended but can be omitted if the computation cost is prohibitive.
+* Return partial signature ''psig''
+
+
+=== Partial Signature Verification ===
+
+
+Algorithm ''PartialSigVerify(psig, pubnonce1..u, pk1..u, tweak1..v, is_xonly_t1..v, m, i)'':
+* Inputs:
+** The partial signature ''psig'': a 32-byte array
+** The number ''u'' of public nonces and individual public keys with ''0 < u < 2^32''
+** The public nonces ''pubnonce1..u'': ''u'' 66-byte arrays
+** The individual public keys ''pk1..u'': ''u'' 33-byte arrays
+** The number ''v'' of tweaks with ''0 ≤ v < 2^32''
+** The tweaks ''tweak1..v'': ''v'' 32-byte arrays
+** The tweak modes ''is_xonly_t1..v'' : ''v'' booleans
+** The message ''m'': a byte array
+** The index of the signer ''i'' in the of public nonces and individual public keys with ''0 < i ≤ u''
+* Let ''aggnonce = NonceAgg(pubnonce1..u)''; fail if that fails
+* Let ''session_ctx = (aggnonce, u, pk1..u, v, tweak1..v, is_xonly_t1..v, m)''
+* Run ''PartialSigVerifyInternal(psig, pubnoncei, pki, session_ctx)''
+* Return success iff no failure occurred before reaching this point.
+
+
+
+Internal Algorithm ''PartialSigVerifyInternal(psig, pubnonce, pk, session_ctx)'':
+* Let ''(Q, gacc, _, b, R, e) = GetSessionValues(session_ctx)''; fail if that fails
+* Let ''s = int(psig)''; fail if ''s ≥ n''
+* Let ''R⁎,1 = cpoint(pubnonce[0:33]), R⁎,2 = cpoint(pubnonce[33:66])''
+* Let ''Re⁎' = R⁎,1 + b⋅R⁎,2''
+* Let effective nonce ''Re⁎ = Re⁎' '' if ''has_even_y(R)'', otherwise let ''Re⁎ = -Re⁎' ''
+* Let ''P = cpoint(pk)''; fail if that fails
+* Let ''a = GetSessionKeyAggCoeff(session_ctx, P)''''GetSessionKeyAggCoeff(session_ctx, P)'' cannot fail when called from ''PartialSigVerifyInternal''.
+* Let ''g = 1'' if ''has_even_y(Q)'', otherwise let ''g = -1 mod n''
+* Let ''g' = g⋅gacc mod n'' (See [[#negation-of-the-individual-public-key-when-partially-verifying|Negation Of The Individual Public Key When Partially Verifying]])
+* Fail if ''s⋅G ≠ Re⁎ + e⋅a⋅g'⋅P''
+* Return success iff no failure occurred before reaching this point.
+
+
+=== Partial Signature Aggregation ===
+
+
+Algorithm ''PartialSigAgg(psig1..u, session_ctx)'':
+* Inputs:
+** The number ''u'' of signatures with ''0 < u < 2^32''
+** The partial signatures ''psig1..u'': ''u'' 32-byte arrays
+** The ''session_ctx'': a [[#session-context|Session Context]] data structure
+* Let ''(Q, _, tacc, _, _, R, e) = GetSessionValues(session_ctx)''; fail if that fails
+* For ''i = 1 .. u'':
+** Let ''si = int(psigi)''; fail if ''si ≥ n'' and blame signer ''i'' for invalid partial signature.
+* Let ''g = 1'' if ''has_even_y(Q)'', otherwise let ''g = -1 mod n''
+* Let ''s = s1 + ... + su + e⋅g⋅tacc mod n''
+* Return ''sig = ''xbytes(R) || bytes(32, s)''
+
+
+=== Test Vectors and Reference Code ===
+
+We provide a naive, highly inefficient, and non-constant time [[bip-0327/reference.py|pure Python 3 reference implementation of the key aggregation, partial signing, and partial signature verification algorithms]].
+
+Standalone JSON test vectors are also available in the [[bip-0327|same directory]], to facilitate porting the test vectors into other implementations.
+
+The reference implementation is for demonstration purposes only and not to be used in production environments.
+
+== Remarks on Security and Correctness ==
+
+=== Signing with Tweaked Individual Keys ===
+
+The scheme in this proposal has been designed to be secure
+even if signers tweak their individual secret keys with tweaks known to the adversary (e.g., as in BIP32 unhardened derivation)
+before providing the corresponding individual public keys as input to key aggregation.
+In particular, the scheme as specified above requires each signer to provide a final individual public key ''pk'' already to ''NonceGen'',
+which writes it into the ''secnonce'' array
+so that it can be checked against ''IndividualPubkey(sk)'' in the ''Sign'' algorithm.
+The purpose of this check in ''Sign'' is to ensure that ''pk'',
+and thus the secret key ''sk'' that will be provided to ''Sign'',
+is determined before the signer sends out the ''pubnonce''.
+
+If the check in ''Sign'' was omitted,
+and a signer supported signing with at least two different secret keys ''sk1'' and ''sk2''
+which have been obtained via tweaking another secret key with tweaks known to the adversary,
+then the adversary could, after having seen the ''pubnonce'',
+influence whether ''sk1'' or ''sk2'' is provided to ''Sign''.
+This degree of freedom may allow the adversary to perform a generalized birthday attack and thereby forge a signature
+(see [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/021000.html bitcoin-dev mailing list post] and [https://github.com/jonasnick/musig2-tweaking writeup] for details).
+
+Checking ''pk'' against ''IndividualPubkey(sk)'' is a simple way to ensure
+that the secret key provided to ''Sign'' is fully determined already when ''NonceGen'' is invoked.
+This removes the adversary's ability to influence the secret key after having seen the ''pubnonce''
+and thus rules out the attack.Ensuring that the secret key provided to ''Sign'' is fully determined already when ''NonceGen'' is invoked is a simple policy to rule out the attack,
+but more flexible polices are conceivable.
+In fact, if the signer uses nothing but the message to be signed and the list of the individual public keys of all signers to decide which secret key to use,
+then it is not a problem that the adversary can influence this decision after having seen the ''pubnonce''.
+More formally, consider modified algorithms ''NonceGen' '' and ''Sign' '', where ''NonceGen' '' does not take the individual public key of the signer as input and does not store it in pubnonce, and Sign' does not check read the individual public key from pubnonce and does not check it against the secret key taken as input.
+Then it suffices that for each invocation of ''NonceGen' '' with output ''(secnonce, pubnonce)'',
+a function ''fsk'' is determined before sending out ''pubnonce'',
+where ''fsk'' maps a pair consisting of a list of individual public keys and a message to a secret key,
+such that the secret key ''sk'' and the session context ''session_ctx = (_, _, pk1..u, _, _, _, m)''
+provided to the corresponding invocation of ''Sign'(secnonce, sk, session_ctx)'',
+adhere to the condition ''fsk(pk1..u, m) = sk''.
+However, this requirement is complex and hard to enforce in implementations.
+The algorithms ''NonceGen'' and ''Sign'' specified in this BIP are effectively restricted to constant functions ''fsk(_, _) = sk''.
+In other words, their usage ensure that the secret key ''sk'' of the signers is determined entirely when invoking ''NonceGen'',
+which is enforced easily by letting ''NonceGen'' take the corresponding individual public key ''pk'' as input and checking ''pk'' against ''IndividualPubKey(sk)'' in ''Sign''.
+Note that the scheme as given in the [https://eprint.iacr.org/2020/1261 MuSig2 paper] does not perform the check in ''Sign''.
+However, the security model in the paper does not cover tweaking at all and assumes a single fixed secret key.
+
+=== Modifications to Nonce Generation ===
+
+Implementers must avoid modifying the ''NonceGen'' algorithm without being fully aware of the implications.
+We provide two modifications to ''NonceGen'' that are secure when applied correctly and may be useful in special circumstances, summarized in the following table.
+
+{| class="wikitable" style="margin:auto"
+! !! needs secure randomness !! needs secure counter !! needs to keep state securely !! needs aggregate nonce of all other signers (only possible for one signer)
+|-
+! NonceGen || ✓ || || ✓ ||
+|-
+! CounterNonceGen || || ✓ || ✓ ||
+|-
+! DeterministicSign || || || || ✓
+|}
+
+First, on systems where obtaining uniformly random values is much harder than maintaining a global atomic counter, it can be beneficial to modify ''NonceGen''.
+The resulting algorithm ''CounterNonceGen'' does not draw ''rand' '' uniformly at random but instead sets ''rand' '' to the value of an atomic counter that is incremented whenever it is read.
+With this modification, the secret signing key ''sk'' of the signer generating the nonce is '''not''' an optional argument and must be provided to ''NonceGen''.
+The security of the resulting scheme then depends on the requirement that reading the counter must never yield the same counter value in two ''NonceGen'' invocations with the same ''sk''.
+
+Second, if there is a unique signer who is supposed to send the ''pubnonce'' last, it is possible to modify nonce generation for this single signer to not require high-quality randomness.
+Such a nonce generation algorithm ''DeterministicSign'' is specified below.
+Note that the only optional argument is ''rand'', which can be omitted if randomness is entirely unavailable.
+''DeterministicSign'' requires the argument ''aggothernonce'' which should be set to the output of ''NonceAgg'' run on the ''pubnonce'' value of '''all''' other signers (but can be provided by an untrusted party).
+Hence, using ''DeterministicSign'' is only possible for the last signer to generate a nonce and makes the signer stateless, similar to the stateless signer described in the [[#nonce-generation|Nonce Generation]] section.
+
+==== Deterministic and Stateless Signing for a Single Signer ====
+
+
+Algorithm ''DeterministicSign(sk, aggothernonce, pk1..u, tweak1..v, is_xonly_t1..v, m, rand)'':
+* Inputs:
+** The secret signing key ''sk'': a 32-byte array
+** The aggregate public nonce ''aggothernonce'' (see [[#modifications-to-nonce-generation|above]]): a 66-byte array
+** The number ''u'' of individual public keys with ''0 < u < 2^32''
+** The individual public keys ''pk1..u'': ''u'' 32-byte arrays
+** The number ''v'' of tweaks with ''0 ≤ v < 2^32''
+** The tweaks ''tweak1..v'': ''v'' 32-byte arrays
+** The tweak methods ''is_xonly_t1..v'': ''v'' booleans
+** The message ''m'': a byte array
+** The auxiliary randomness ''rand'': a 32-byte array (optional argument)
+* If the optional argument ''rand'' is present:
+** Let ''sk' '' be the byte-wise xor of ''sk'' and ''hashMuSig/aux(rand)''
+* Else:
+** Let ''sk' = sk''
+* Let ''keyagg_ctx0 = KeyAgg(pk1..u)''; fail if that fails
+* For ''i = 1 .. v'':
+** Let ''keyagg_ctxi = ApplyTweak(keyagg_ctxi-1, tweaki, is_xonly_ti)''; fail if that fails
+* Let ''aggpk = GetXonlyPubkey(keyagg_ctxv)''
+* Let ''ki = int(hashMuSig/deterministic/nonce(sk' || aggothernonce || aggpk || bytes(8, len(m)) || m || bytes(1, i - 1))) mod n'' for ''i = 1,2''
+* Fail if ''k1 = 0'' or ''k2 = 0''
+* Let ''R⁎,1 = k1⋅G, R⁎,2 = k2⋅G''
+* Let ''pubnonce = cbytes(R⁎,2) || cbytes(R⁎,2)''
+* Let ''d = int(sk)''
+* Fail if ''d = 0'' or ''d ≥ n''
+* Let ''pk = cbytes(d⋅G)''
+* Let ''secnonce = bytes(32, k1) || bytes(32, k2) || pk''
+* Let ''aggnonce = NonceAgg((pubnonce, aggothernonce))''; fail if that fails and blame nonce aggregator for invalid ''aggothernonce''.
+* Let ''session_ctx = (aggnonce, u, pk1..u, v, tweak1..v, is_xonly_t1..v, m)''
+* Return ''(pubnonce, Sign(secnonce, sk, session_ctx))''
+
+
+=== Tweaking Definition ===
+
+Two modes of tweaking the aggregate public key are supported. They correspond to the following algorithms:
+
+
+Algorithm ''ApplyPlainTweak(P, t)'':
+* Inputs:
+** ''P'': a point
+** The tweak ''t'': an integer with ''0 ≤ t < n ''
+* Return ''P + t⋅G''
+
+
+==Abstract==
+
+This document specifies how BIP 32 extended public keys can be constructed from a BIP 327 MuSig2
+aggregate public key and how such keys should be used for key derivation.
+
+==Copyright==
+
+This BIP is licensed under the Creative Commons CC0 1.0 Universal license.
+
+==Motivation==
+
+Multiple signers can create a single aggregate public key with MuSig2 that is indistinguishable
+from a random public key. The cosigners need a method for generating additional aggregate pubkeys
+to follow the best practice of using a new address for every payment.
+
+The obvious method is for the cosigners to generate multiple public keys and produce a
+new aggregate pubkey every time one is needed. This is similar to how multisig using Bitcoin script
+works where all of the cosigners share their extended public keys and do derivation to produce
+the multisig script. The same could be done with MuSig2 and instead of producing a multisig script,
+the result would be a MuSig2 aggregate pubkey.
+
+However, it is much simpler to be able to derive from a single extended public key instead of having
+to derive from many extended public keys and aggregate them. As MuSig2 produces a normal looking
+public key, the aggregate public can be used in this way. This reduces the storage and computation
+requirements for generating new aggregate pubkeys.
+
+==Specification==
+
+A synthetic xpub can be created from a BIP 327 MuSig2 plain aggregate public key by setting
+the depth to 0, the child number to 0, and attaching a chaincode with the byte string
+868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965'''Where does this
+constant chaincode come from?''' It is the SHA256 of the text MuSig2MuSig2MuSig2.
+This fixed chaincode should be used by all such synthetic xpubs following this specification.
+Unhardened child public keys can be derived from the synthetic xpub as with any other xpub. Since
+the aggregate public key is all that is necessary to produce the synthetic xpub, any aggregate
+public key that will be used in this way shares the same privacy concerns as typical xpubs.
+
+Furthermore, as there is no aggregate private key, only unhardened derivation from the aggregate
+public key is possible.
+
+When signing, all signers must compute the tweaks used in the BIP 32 derivation for the child key
+being signed for. The IL value computed in ''CKDpub'' is the tweak used at each
+derivation step. These are provided in the session context, each with a tweak mode of plain
+(''is_xonly_t = false''). When the ''Sign'' algorithm is used, the tweaks will be applied to the
+partial signatures.
+
+==Test Vectors==
+
+* Aggregate pubkey 0354240c76b8f2999143301a99c7f721ee57eee0bce401df3afeaa9ae218c70f23
+** Synthetic xpub xpub661MyMwAqRbcFt6tk3uaczE1y6EvM1TqXvawXcYmFEWijEM4PDBnuCXwwXEKGEouzXE6QLLRxjatMcLLzJ5LV5Nib1BN7vJg6yp45yHHRbm
+** Keys:
+*** 03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9
+*** 02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9
+* Aggregate pubkey 0290539eede565f5d054f32cc0c220126889ed1e5d193baf15aef344fe59d4610c
+** Synthetic xpub xpub661MyMwAqRbcFt6tk3uaczE1y6EvM1TqXvawXcYmFEWijEM4PDBnuCXwwVk5TFJk8Tw5WAdV3DhrGfbFA216sE9BsQQiSFTdudkETnKdg8k
+** Keys:
+*** 02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9
+*** 03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659
+*** 023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66
+* Aggregate pubkey 022479f134cdb266141dab1a023cbba30a870f8995b95a91fc8464e56a7d41f8ea
+** Synthetic xpub xpub661MyMwAqRbcFt6tk3uaczE1y6EvM1TqXvawXcYmFEWijEM4PDBnuCXwwUvaZYpysLX4wN59tjwU5pBuDjNrPEJbfxjLwn7ruzbXTcUTHkZ
+** Keys:
+*** 02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659
+*** 023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66
+*** 02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9
+*** 03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9
+
+==Backwards Compatibility==
+
+Once a synthetic xpub is created, it is fully backwards compatible with BIP 32 - only unhardened
+derivation can be done, and the signers will be able to produce a signature for any derived children.
+
+==Rationale==
+
+
+
+==Reference Implementation==
+
+A Python reference implementation is available in this BIP's [[bip-0328|Auxiliary Files]].
+
+==Acknowledgements==
+
+Thanks to Pieter Wuille, Andrew Poelstra, Sanket Kanjalkar, Salvatore Ingala, and all others who
+participated in discussions on this topic.
diff --git a/bip-0328/_base58.py b/bip-0328/_base58.py
new file mode 100644
index 0000000000..438163e400
--- /dev/null
+++ b/bip-0328/_base58.py
@@ -0,0 +1,176 @@
+"""
+Base 58 conversion utilities
+****************************
+"""
+
+#
+# base58.py
+# Original source: git://github.com/joric/brutus.git
+# which was forked from git://github.com/samrushing/caesure.git
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from binascii import hexlify, unhexlify
+from typing import List
+
+from _common import hash256
+
+
+b58_digits: str = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
+
+
+def encode(b: bytes) -> str:
+ """
+ Encode bytes to a base58-encoded string
+
+ :param b: Bytes to encode
+ :return: Base58 encoded string of ``b``
+ """
+
+ # Convert big-endian bytes to integer
+ n: int = int('0x0' + hexlify(b).decode('utf8'), 16)
+
+ # Divide that integer into base58
+ temp: List[str] = []
+ while n > 0:
+ n, r = divmod(n, 58)
+ temp.append(b58_digits[r])
+ res: str = ''.join(temp[::-1])
+
+ # Encode leading zeros as base58 zeros
+ czero: int = 0
+ pad: int = 0
+ for c in b:
+ if c == czero:
+ pad += 1
+ else:
+ break
+ return b58_digits[0] * pad + res
+
+def decode(s: str) -> bytes:
+ """
+ Decode a base58-encoding string, returning bytes
+
+ :param s: Base58 string to decode
+ :return: Bytes encoded by ``s``
+ """
+ if not s:
+ return b''
+
+ # Convert the string to an integer
+ n: int = 0
+ for c in s:
+ n *= 58
+ if c not in b58_digits:
+ raise Exception('Character %r is not a valid base58 character' % c)
+ digit = b58_digits.index(c)
+ n += digit
+
+ # Convert the integer to bytes
+ h: str = '%x' % n
+ if len(h) % 2:
+ h = '0' + h
+ res = unhexlify(h.encode('utf8'))
+
+ # Add padding back.
+ pad = 0
+ for c in s[:-1]:
+ if c == b58_digits[0]:
+ pad += 1
+ else:
+ break
+ return b'\x00' * pad + res
+
+def decode_check(s: str) -> bytes:
+ """
+ Decode a Base58Check encoded string, returning bytes
+
+ :param s: Base58 string to decode
+ :return: Bytes encoded by ``s``
+ """
+ data = decode(s)
+ payload = data[:-4]
+ checksum = data[-4:]
+ calc_checksum = hash256(payload)
+ if checksum != calc_checksum[:4]:
+ raise ValueError("Invalid checksum")
+ return payload
+
+def encode_check(b: bytes) -> str:
+ checksum = hash256(b)[0:4]
+ data = b + checksum
+ return encode(data)
+
+def get_xpub_fingerprint(s: str) -> bytes:
+ """
+ Get the parent fingerprint from an extended public key
+
+ :param s: The extended pubkey
+ :return: The parent fingerprint bytes
+ """
+ data = decode(s)
+ fingerprint = data[5:9]
+ return fingerprint
+
+def get_xpub_fingerprint_hex(xpub: str) -> str:
+ """
+ Get the parent fingerprint as a hex string from an extended public key
+
+ :param xpub: The extended pubkey
+ :return: The parent fingerprint as a hex string
+ """
+ data = decode(xpub)
+ fingerprint = data[5:9]
+ return hexlify(fingerprint).decode()
+
+def to_address(b: bytes, version: bytes) -> str:
+ """
+ Base58 Check Encode the data with the version number.
+ Used to encode legacy style addresses.
+
+ :param b: The data to encode
+ :param version: The version number to encode with
+ :return: The Base58 Check Encoded string
+ """
+ data = version + b
+ checksum = hash256(data)[0:4]
+ data += checksum
+ return encode(data)
+
+def xpub_to_pub_hex(xpub: str) -> str:
+ """
+ Get the public key as a string from the extended public key.
+
+ :param xpub: The extended pubkey
+ :return: The pubkey hex string
+ """
+ data = decode(xpub)
+ pubkey = data[-37:-4]
+ return hexlify(pubkey).decode()
+
+
+def xpub_to_xonly_pub_hex(xpub: str) -> str:
+ """
+ Get the public key as a string from the extended public key.
+
+ :param xpub: The extended pubkey
+ :return: The pubkey hex string
+ """
+ data = decode(xpub)
+ pubkey = data[-36:-4]
+ return hexlify(pubkey).decode()
+
+
+def xpub_main_2_test(xpub: str) -> str:
+ """
+ Convert an extended pubkey from mainnet version to testnet version.
+
+ :param xpub: The extended pubkey
+ :return: The extended pubkey re-encoded using testnet version bytes
+ """
+ data = decode(xpub)
+ test_data = b'\x04\x35\x87\xCF' + data[4:-4]
+ checksum = hash256(test_data)[0:4]
+ return encode(test_data + checksum)
diff --git a/bip-0328/_bip327.py b/bip-0328/_bip327.py
new file mode 120000
index 0000000000..a19956364f
--- /dev/null
+++ b/bip-0328/_bip327.py
@@ -0,0 +1 @@
+../bip-0327/reference.py
\ No newline at end of file
diff --git a/bip-0328/_common.py b/bip-0328/_common.py
new file mode 100644
index 0000000000..9b01bad1b6
--- /dev/null
+++ b/bip-0328/_common.py
@@ -0,0 +1,47 @@
+"""
+Common Classes and Utilities
+****************************
+"""
+
+import hashlib
+
+def sha256(s: bytes) -> bytes:
+ """
+ Perform a single SHA256 hash.
+
+ :param s: Bytes to hash
+ :return: The hash
+ """
+ return hashlib.new('sha256', s).digest()
+
+
+def ripemd160(s: bytes) -> bytes:
+ """
+ Perform a single RIPEMD160 hash.
+
+ :param s: Bytes to hash
+ :return: The hash
+ """
+ return hashlib.new('ripemd160', s).digest()
+
+
+def hash256(s: bytes) -> bytes:
+ """
+ Perform a double SHA256 hash.
+ A SHA256 is performed on the input, and then a second
+ SHA256 is performed on the result of the first SHA256
+
+ :param s: Bytes to hash
+ :return: The hash
+ """
+ return sha256(sha256(s))
+
+
+def hash160(s: bytes) -> bytes:
+ """
+ perform a single SHA256 hash followed by a single RIPEMD160 hash on the result of the SHA256 hash.
+
+ :param s: Bytes to hash
+ :return: The hash
+ """
+ return ripemd160(sha256(s))
diff --git a/bip-0328/_xpub.py b/bip-0328/_xpub.py
new file mode 100644
index 0000000000..12031e388b
--- /dev/null
+++ b/bip-0328/_xpub.py
@@ -0,0 +1,244 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020 The HWI developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+"""
+Key Classes and Utilities
+*************************
+
+Classes and utilities for working with extended public keys, key origins, and other key related things.
+"""
+
+import _base58 as base58
+from _common import (
+ hash256,
+ hash160,
+)
+import binascii
+import hmac
+import hashlib
+import struct
+from typing import (
+ Dict,
+ Optional,
+ Sequence,
+ Tuple,
+)
+
+
+HARDENED_FLAG = 1 << 31
+
+p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
+n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
+G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
+
+Point = Optional[Tuple[int, int]]
+
+def H_(x: int) -> int:
+ """
+ Shortcut function that "hardens" a number in a BIP44 path.
+ """
+ return x | HARDENED_FLAG
+
+def is_hardened(i: int) -> bool:
+ """
+ Returns whether an index is hardened
+ """
+ return i & HARDENED_FLAG != 0
+
+
+def point_add(p1: Point, p2: Point) -> Point:
+ if (p1 is None):
+ return p2
+ if (p2 is None):
+ return p1
+ if (p1[0] == p2[0] and p1[1] != p2[1]):
+ return None
+ if (p1 == p2):
+ lam = (3 * p1[0] * p1[0] * pow(2 * p1[1], p - 2, p)) % p
+ else:
+ lam = ((p2[1] - p1[1]) * pow(p2[0] - p1[0], p - 2, p)) % p
+ x3 = (lam * lam - p1[0] - p2[0]) % p
+ return (x3, (lam * (p1[0] - x3) - p1[1]) % p)
+
+
+def point_mul(p: Point, n: int) -> Point:
+ r = None
+ for i in range(256):
+ if ((n >> i) & 1):
+ r = point_add(r, p)
+ p = point_add(p, p)
+ return r
+
+
+def deserialize_point(b: bytes) -> Point:
+ x = int.from_bytes(b[1:], byteorder="big")
+ y = pow((x * x * x + 7) % p, (p + 1) // 4, p)
+ if (y & 1 != b[0] & 1):
+ y = p - y
+ return (x, y)
+
+
+def bytes_to_point(point_bytes: bytes) -> Point:
+ header = point_bytes[0]
+ if header == 4:
+ x = point_bytes = point_bytes[1:33]
+ y = point_bytes = point_bytes[33:65]
+ return (int(binascii.hexlify(x), 16), int(binascii.hexlify(y), 16))
+ return deserialize_point(point_bytes)
+
+def point_to_bytes(p: Point) -> bytes:
+ if p is None:
+ raise ValueError("Cannot convert None to bytes")
+ return (b'\x03' if p[1] & 1 else b'\x02') + p[0].to_bytes(32, byteorder="big")
+
+
+# An extended public key (xpub) or private key (xprv). Just a data container for now.
+# Only handles deserialization of extended keys into component data to be handled by something else
+class ExtendedKey(object):
+ """
+ A BIP 32 extended public key.
+ """
+
+ MAINNET_PUBLIC = b'\x04\x88\xB2\x1E'
+ MAINNET_PRIVATE = b'\x04\x88\xAD\xE4'
+ TESTNET_PUBLIC = b'\x04\x35\x87\xCF'
+ TESTNET_PRIVATE = b'\x04\x35\x83\x94'
+
+ def __init__(self, version: bytes, depth: int, parent_fingerprint: bytes, child_num: int, chaincode: bytes, privkey: Optional[bytes], pubkey: bytes) -> None:
+ """
+ :param version: The version bytes for this xpub
+ :param depth: The depth of this xpub as defined in BIP 32
+ :param parent_fingerprint: The 4 byte fingerprint of the parent xpub as defined in BIP 32
+ :param child_num: The number of this xpub as defined in BIP 32
+ :param chaincode: The chaincode of this xpub as defined in BIP 32
+ :param privkey: The private key for this xpub if available
+ :param pubkey: The public key for this xpub
+ """
+ self.version: bytes = version
+ self.is_testnet: bool = version == ExtendedKey.TESTNET_PUBLIC or version == ExtendedKey.TESTNET_PRIVATE
+ self.is_private: bool = version == ExtendedKey.MAINNET_PRIVATE or version == ExtendedKey.TESTNET_PRIVATE
+ self.depth: int = depth
+ self.parent_fingerprint: bytes = parent_fingerprint
+ self.child_num: int = child_num
+ self.chaincode: bytes = chaincode
+ self.pubkey: bytes = pubkey
+ self.privkey: Optional[bytes] = privkey
+
+ @classmethod
+ def deserialize(cls, xpub: str) -> 'ExtendedKey':
+ """
+ Create an :class:`~ExtendedKey` from a Base58 check encoded xpub
+
+ :param xpub: The Base58 check encoded xpub
+ """
+ data = base58.decode(xpub)[:-4] # Decoded xpub without checksum
+ return cls.from_bytes(data)
+
+ @classmethod
+ def from_bytes(cls, data: bytes) -> 'ExtendedKey':
+ """
+ Create an :class:`~ExtendedKey` from a serialized xpub
+
+ :param xpub: The serialized xpub
+ """
+
+ version = data[0:4]
+ if version not in [ExtendedKey.MAINNET_PRIVATE, ExtendedKey.MAINNET_PUBLIC, ExtendedKey.TESTNET_PRIVATE, ExtendedKey.TESTNET_PUBLIC]:
+ raise Exception(f"Extended key magic of {version.hex()} is invalid")
+ is_private = version == ExtendedKey.MAINNET_PRIVATE or version == ExtendedKey.TESTNET_PRIVATE
+ depth = data[4]
+ parent_fingerprint = data[5:9]
+ child_num = struct.unpack('>I', data[9:13])[0]
+ chaincode = data[13:45]
+
+ if is_private:
+ privkey = data[46:]
+ pubkey = point_to_bytes(point_mul(G, int.from_bytes(privkey, byteorder="big")))
+ return cls(version, depth, parent_fingerprint, child_num, chaincode, privkey, pubkey)
+ else:
+ pubkey = data[45:78]
+ return cls(version, depth, parent_fingerprint, child_num, chaincode, None, pubkey)
+
+ def serialize(self) -> bytes:
+ """
+ Serialize the ExtendedKey with the serialization format described in BIP 32.
+ Does not create an xpub string, but the bytes serialized here can be Base58 check encoded into one.
+
+ :return: BIP 32 serialized extended key
+ """
+ r = self.version + struct.pack('B', self.depth) + self.parent_fingerprint + struct.pack('>I', self.child_num) + self.chaincode
+ if self.is_private:
+ if self.privkey is None:
+ raise ValueError("Somehow we are private but don't have a privkey")
+ r += b"\x00" + self.privkey
+ else:
+ r += self.pubkey
+ return r
+
+ def to_string(self) -> str:
+ """
+ Serialize the ExtendedKey as a Base58 check encoded xpub string
+
+ :return: Base58 check encoded xpub
+ """
+ data = self.serialize()
+ checksum = hash256(data)[0:4]
+ return base58.encode(data + checksum)
+
+ def get_printable_dict(self) -> Dict[str, object]:
+ """
+ Get the attributes of this ExtendedKey as a dictionary that can be printed
+
+ :return: Dictionary containing ExtendedKey information that can be printed
+ """
+ d: Dict[str, object] = {}
+ d['testnet'] = self.is_testnet
+ d['private'] = self.is_private
+ d['depth'] = self.depth
+ d['parent_fingerprint'] = binascii.hexlify(self.parent_fingerprint).decode()
+ d['child_num'] = self.child_num
+ d['chaincode'] = binascii.hexlify(self.chaincode).decode()
+ if self.is_private and isinstance(self.privkey, bytes):
+ d['privkey'] = binascii.hexlify(self.privkey).decode()
+ d['pubkey'] = binascii.hexlify(self.pubkey).decode()
+ return d
+
+ def derive_pub(self, i: int) -> 'ExtendedKey':
+ """
+ Derive the public key at the given child index.
+
+ :param i: The child index of the pubkey to derive
+ """
+ if is_hardened(i):
+ raise ValueError("Index cannot be larger than 2^31")
+
+ # Data to HMAC. Same as CKDpriv() for public child key.
+ data = self.pubkey + struct.pack(">L", i)
+
+ # Get HMAC of data
+ Ihmac = hmac.new(self.chaincode, data, hashlib.sha512).digest()
+ Il = Ihmac[:32]
+ Ir = Ihmac[32:]
+
+ # Construct curve point Il*G+K
+ Il_int = int(binascii.hexlify(Il), 16)
+ child_pubkey = point_add(point_mul(G, Il_int), bytes_to_point(self.pubkey))
+
+ # Construct and return a new BIP32Key
+ pubkey = point_to_bytes(child_pubkey)
+ chaincode = Ir
+ fingerprint = hash160(self.pubkey)[0:4]
+ return ExtendedKey(ExtendedKey.TESTNET_PUBLIC if self.is_testnet else ExtendedKey.MAINNET_PUBLIC, self.depth + 1, fingerprint, i, chaincode, None, pubkey)
+
+ def derive_pub_path(self, path: Sequence[int]) -> 'ExtendedKey':
+ """
+ Derive the public key at the given path
+
+ :param path: Sequence of integers for the path of the pubkey to derive
+ """
+ key = self
+ for i in path:
+ key = key.derive_pub(i)
+ return key
diff --git a/bip-0328/reference.py b/bip-0328/reference.py
new file mode 100644
index 0000000000..d7e493e2ea
--- /dev/null
+++ b/bip-0328/reference.py
@@ -0,0 +1,31 @@
+#! /usr/bin/env python3
+
+import json
+import os
+import sys
+
+from _base58 import xpub_to_pub_hex
+from _bip327 import cbytes, key_agg
+from _xpub import ExtendedKey
+
+CHAINCODE = bytes.fromhex("868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965")
+
+def aggregate_to_xpub(aggregate: bytes) -> ExtendedKey:
+ return ExtendedKey(ExtendedKey.MAINNET_PUBLIC, 0, b"\x00\x00\x00\x00", 0, CHAINCODE, None, aggregate)
+
+def test_aggregate_to_xpub():
+ with open(os.path.join(sys.path[0], "vectors.json"), "r") as f:
+ test_data = json.load(f)
+
+ for test_case in test_data:
+ keys = [bytes.fromhex(k) for k in test_case["keys"]]
+
+ agg_ctx = key_agg(keys)
+ pub = cbytes(agg_ctx.Q)
+ assert pub.hex() == test_case["aggregate_pubkey"]
+
+ xpub = aggregate_to_xpub(pub)
+ assert xpub.to_string() == test_case["xpub"]
+
+if __name__ == "__main__":
+ test_aggregate_to_xpub()
diff --git a/bip-0328/vectors.json b/bip-0328/vectors.json
new file mode 100644
index 0000000000..d42c2674f9
--- /dev/null
+++ b/bip-0328/vectors.json
@@ -0,0 +1,29 @@
+[
+ {
+ "aggregate_pubkey": "0354240c76b8f2999143301a99c7f721ee57eee0bce401df3afeaa9ae218c70f23",
+ "keys": [
+ "03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9",
+ "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9"
+ ],
+ "xpub": "xpub661MyMwAqRbcFt6tk3uaczE1y6EvM1TqXvawXcYmFEWijEM4PDBnuCXwwXEKGEouzXE6QLLRxjatMcLLzJ5LV5Nib1BN7vJg6yp45yHHRbm"
+ },
+ {
+ "aggregate_pubkey": "0290539eede565f5d054f32cc0c220126889ed1e5d193baf15aef344fe59d4610c",
+ "keys": [
+ "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9",
+ "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659",
+ "023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66"
+ ],
+ "xpub": "xpub661MyMwAqRbcFt6tk3uaczE1y6EvM1TqXvawXcYmFEWijEM4PDBnuCXwwVk5TFJk8Tw5WAdV3DhrGfbFA216sE9BsQQiSFTdudkETnKdg8k"
+ },
+ {
+ "aggregate_pubkey": "022479f134cdb266141dab1a023cbba30a870f8995b95a91fc8464e56a7d41f8ea",
+ "keys": [
+ "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659",
+ "023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66",
+ "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9",
+ "03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9"
+ ],
+ "xpub": "xpub661MyMwAqRbcFt6tk3uaczE1y6EvM1TqXvawXcYmFEWijEM4PDBnuCXwwUvaZYpysLX4wN59tjwU5pBuDjNrPEJbfxjLwn7ruzbXTcUTHkZ"
+ }
+]
diff --git a/bip-0329.mediawiki b/bip-0329.mediawiki
new file mode 100644
index 0000000000..5934eeae76
--- /dev/null
+++ b/bip-0329.mediawiki
@@ -0,0 +1,194 @@
+
+
+==Abstract==
+
+This document specifies a format for the export of labels that may be attached to various common types of records in a wallet.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+The export and import of funds across different Bitcoin wallet applications is well defined through standards such as BIP39, BIP32, BIP44 etc.
+These standards are well supported and allow users to move easily between different wallets.
+There is, however, no defined standard to transfer any labels the user may have applied to the transactions, addresses, public keys, inputs, outputs or xpubs in their wallet.
+The UTXO model that Bitcoin uses makes these labels particularly valuable as they may indicate the source of funds, whether received externally or as a result of change from a prior transaction.
+In both cases, care must be taken when spending to avoid undesirable leaks of private information.
+
+Labels provide valuable guidance in this regard, and have even become mandatory when spending in several Bitcoin wallets.
+Allowing users to import and export their labels in a standardized way ensures that they do not experience lock-in to a particular wallet application.
+In addition, many wallets allow unspent outputs to be frozen or made unspendable within the wallet. Since this wallet-related metadata is similar to labels and not captured elsewhere, it is also included in this format.
+
+==Rationale==
+
+While there is currently no widely accepted format for exporting and importing labels, there are existing formats in use.
+SLIP-0015[https://github.com/satoshilabs/slips/blob/master/slip-0015.md SLIP-0015] defines a format for exporting address and output labels, but requires encryption using a private key associated with the wallet seed, and thus cannot be used independently by coordinator wallets which cannot access private keys.
+The Electrum wallet imports and exports address and transaction labels in a JSON format which could be used with other record types, but the format used is not self describing making record type identification difficult.
+
+==Specification==
+
+In order to be lightweight, human readable and well structured, this BIP uses a JSON format.
+Further, the JSON Lines format is used (also called newline-delimited JSON)[https://jsonlines.org/ jsonlines.org].
+This allows a document to be split, streamed, or incrementally added to, and limits the potential for formatting errors to invalidate an entire import.
+It is also a convenient format for command-line processing, which is often line-oriented.
+
+Further to the JSON Lines specification, an export of labels from a wallet must be a UTF-8 encoded text file, containing one record per line consisting of a valid JSON object.
+Lines are separated by \n. Multiline values are not permitted.
+Each JSON object must contain 3 or 4 key/value pairs, defined as follows:
+
+{| class="wikitable"
+|-
+! Key
+! Description
+|-
+| type
+| One of tx, addr, pubkey, input, output or xpub
+|-
+| ref
+| Reference to the transaction, address, public key, input, output or extended public key
+|-
+| label
+| The label applied to the reference
+|-
+| origin
+| Optional key origin information referencing the wallet associated with the label
+|-
+| spendable
+| One of true or false, denoting if an output should be spendable by the wallet
+|}
+
+The reference is defined for each type as follows:
+
+{| class="wikitable"
+|-
+! Type
+! Description
+! Example
+|-
+| tx
+| Transaction id in hexadecimal format
+| f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd
+|-
+| addr
+| Address in base58 or bech32 format
+| bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c
+|-
+| pubkey
+| 32, 33 or 65 byte public key in hexadecimal format
+| 0283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448
+|-
+| input
+| Transaction id and input index separated by a colon
+| f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:0
+|-
+| output
+| Transaction id and output index separated by a colon
+| f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:1
+|-
+| xpub
+| Extended public key as defined by BIP32
+| xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8Nq...
+|}
+
+Each JSON object must contain both type and ref properties. The label, origin and spendable properties are optional. If the label or spendable properties are omitted, the importing wallet should not alter these values. The spendable property should only appear where type is output.
+
+If present, the optional origin property must contain an abbreviated output descriptor (as defined by BIP380[https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki BIP-0380]) describing a BIP32 compatible originating wallet, including all key origin information but excluding any actual keys, any child path elements, or a checksum.
+This property should be used to disambiguate transaction labels from different wallets contained in the same export, particularly when exporting multiple accounts derived from the same seed.
+
+Care should be taken when exporting due to the privacy sensitive nature of the data.
+Encryption in transit over untrusted networks is highly recommended, and encryption at rest should also be considered.
+Unencrypted exports should be deleted as soon as possible.
+For security reasons no private key types are defined.
+
+==Importing==
+
+* An importing wallet may ignore records it does not store, and truncate labels if necessary. A suggested default for maximum label length is 255 characters, and an importing wallet should consider warning the user if truncation is applied.
+* Wallets importing public key records may derive addresses from them to match against known wallet addresses.
+* Wallets importing extended public keys may match them against signers, for example in a multisig setup.
+
+==Backwards Compatibility==
+
+The nature of this format makes it naturally extensible to handle other record types.
+However, importing wallets complying to this specification should ignore types not defined here.
+
+==Test Vectors==
+
+The following fragment represents a wallet label export:
+
+
+==Additional Fields==
+
+If the goal is solely to move labels between cooperating wallets,
+then the above values are the minimum needed. However, wallet data
+exports can serve other purposes. Many values associated with
+addresses, transactions and outputs are already on hand for the
+wallet generating the export, and yet would be hard or impossible
+for importing tools to reconstruct.
+
+All of the following values are optional for the exporter to provide,
+but should be given if they are readily available.
+
+=== Transactions ===
+
+* height: An integer giving the block height where this fully confirmed transaction can be found. For transactions that are confirmed by less than 6 blocks, omit this field or provide a value of zero. (Background: Until it is fully confirmed, the "height" of a transaction is in flux and may vary due to chain reorgs. However, the consumer of the labels, may not know the current block height, so it cannot know if the height is "real" (firm, fixed) or just transitory. Therefore, it is important to omit the height unless the generating wallet considers the transaction to be confirmed.)
+
+* time: ISO-8601 formatted timestamp of the block given by the "height" field, preferably in UTC, although ISO-8601 can represent local times. Example: 2025-01-23T11:40:35Z.
+
+* fee: Integer giving the number of Satoshis that went to the miner for this transaction.
+
+* value: Signed integer giving the number of Satoshis that came into the wallet by this transaction. Will be negative when sats leave the wallet. Could be zero if it is a consolidation transaction that moves from old UTXO to new.
+
+* rate: Exchange rate at time of transaction. This is the value of a Bitcoin, expressed in another currency, at the time of the transaction, based on user preferences for data source. Multiple currencies can be given. Keys are ISO 4217 currency codes where possible. Example: "rate": { "USD": 105620.00 }
+
+=== Address, Inputs, and Outputs ===
+
+* keypath: The data needed to build full descriptor down to the specific address. This extends origin with the final two components that are unhardened (in the typical case, assuming BIP-84). Provide string /1/123 for wpkh([d34db33f/84'/0'/0'/1/123]). If the first character is not /, then it should be interpreted as a full descriptor, independent of origin (if any).
+
+=== Inputs and Outputs ===
+
+* value: Integer with the number of Satoshis (nValue) of the input or output.
+
+* fmv: Fair market value of the input/output relative to some other currency, typically fiat. The value should be a mapping, from currency code to decimal number. Example: "fmv": { "USD": 1233.45 }. Most situations will have only a single currency value, and it represents the real price of the goods/services expressed in some fiat currency. This is not an exchange *rate*, but an absolute value. By dividing by the value (above), it is possible to calculate an effective change rate for the transaction.
+
+* height and time: Same definition as defined in Transactions.
+
+=== Address ===
+
+* heights: a list of block heights that contain any activity related to this address, include outputs that deposit to the address, and transactions that spend UTXOs of this address. Omit heights for transactions that are not fully confirmed. An empty array indicates the address is unused for confirmed transactions.
+
+== Comment on Types in JSON ==
+
+JSON can serialize a number of basic types, including string, integer
+and boolean (true/false). Decimal values (123.45) can
+also be serialized, but some parsing libraries may interpret them as floating
+point values, which is generally not what we want in financial applications.
+When hand-crafting JSON data, be careful not to write "false" (with quotes),
+since that is a string with 5 characters and not a boolean.
+
+==Reference Implementation==
+
+* [https://github.com/Labelbase/python-bip329 Python-BIP329 package]
+
+==References==
+
+
diff --git a/bip-0330.mediawiki b/bip-0330.mediawiki
index 581b6aef9d..996f74e15f 100644
--- a/bip-0330.mediawiki
+++ b/bip-0330.mediawiki
@@ -29,19 +29,24 @@ Increasing the connectivity of the network makes the network more robust to part
[https://arxiv.org/pdf/1905.10518.pdf Erlay] is an example of a high-level transaction relay protocol which employs set reconciliation for bandwidth efficiency.
+Note that what we are going to describe here is a modified version from the protocol (it is different from what is presented in the paper).
+
Erlay uses both flooding (announcing using INV messages to all peers) and reconciliation to announce transactions.
-Flooding is expensive, so Erlay seeks to use it sparingly and in strategic locations - only well-connected publicly reachable nodes flood transactions to other publicly reachable nodes via outbound connections.
-Since every unreachable node is directly connected to several reachable nodes, this policy ensures that a transaction is quickly propagated to be within one hop from most of the nodes in the network.
+Flooding is expensive, so Erlay seeks to use it only when necessary to facilitate rapid relay over a small subset of connections.
+
+Efficient set reconciliation is meant to deliver transactions to those nodes which didn't receive a transaction via flooding, and also just make sure remaining connections are in sync (directly connected pairs of nodes are aware they have nothing to learn from each other).
+
+Efficient set reconciliation works as follows:
+1) every node keeps a reconciliation set for each peer, in which transactions are placed which would have been announced using INV messages absent this protocol
+2) once in a while every node chooses a peer from its reconciliation queue to reconcile with, resulting in both sides learning the transactions known to the other side
+3) after every reconciliation round, the corresponding reconciliation set is cleared
-All transactions not propagated through flooding are propagated through efficient set reconciliation.
-To do this, every node keeps a reconciliation set for each peer, in which transactions are placed which would have been announced using INV messages absent this protocol. Every 2 seconds every node chooses a peer from its outbound connections in a predetermined order to reconcile with, resulting in both sides learning the transactions known to the other side. After every reconciliation round, the corresponding reconciliation set is cleared.
-A more detailed description of a set reconciliation round and other implementation details can be found in the paper.
+A more detailed description of a set reconciliation round can be found below.
Erlay allows us to:
-* save 40% of the bandwidth consumed by a node, given typical network connectivity as of July 2019.
-* achieve similar latency
+* save a significant portion of the bandwidth consumed by a node
* increase network connectivity for almost no bandwidth or latency cost
-* improves privacy as a side-effect
+* keep transaction propagation latency at the same level
This document proposes a P2P-layer extension which is required to enable efficient reconciliation-based protocols (like Erlay) for transaction relay.
@@ -52,13 +57,11 @@ This document proposes a P2P-layer extension which is required to enable efficie
Several new data structures are introduced to the P2P protocol first, to aid with efficient transaction relay.
====32-bit short transaction IDs====
-
-During reconciliation, significantly abbreviated transaction IDs are used of just 32 bits in size. To prevent attackers from constructing sets of transactions that cause network-wide collisions, the short ID computation is salted on a per-link basis using 64 bits of entropy contributed by both communication partners.
-
+=
Short IDs are computed as follows:
-* Let ''salt1'' and ''salt2'' be the entropy contributed by both sides; see the "sendrecon" message further for details how they are exchanged.
+* Let ''salt1'' and ''salt2'' be the entropy contributed by both sides; see the "sendtxrcncl" message further for details how they are exchanged.
* Sort the two salts such that ''salt1 ≤ salt2'' (which side sent what doesn't matter).
-* Compute ''h = SHA256("Tx Relay Salting" || salt1 || salt2)'', where the two salts are encoded in 64-bit little-endian byte order.
+* Compute ''h = TaggedHash("Tx Relay Salting", salt1, salt2)'', where the two salts are encoded in 64-bit little-endian byte order, and TaggedHash is specified by [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP-340].
* Let ''k0'' be the 64-bit integer obtained by interpreting the first 8 bytes of ''h'' in little-endian byte order.
* Let ''k1'' be the 64-bit integer obtained by interpreting the second 8 bytes of ''h'' in little-endian byte order.
* Let ''s = SipHash-2-4((k0,k1),wtxid)'', where ''wtxid'' is the transaction hash including witness data as defined by BIP141.
@@ -104,69 +107,67 @@ def create_sketch(shortids, capacity):
The [https://github.com/sipa/minisketch/ minisketch] library implements the construction, merging, and decoding of these sketches efficiently.
-====Truncated transaction IDs====
-
-For announcing and relaying transaction outside of reconciliation, we need an unambiguous, unsalted way to refer to transactions to deduplicate transaction requests. As we're introducing a new scheme anyway, this is a good opportunity to switch to wtxid-based requests rather than txid-based ones. While using full 256-bit wtxids is possible, this is overkill as they contribute significantly to the total bandwidth as well. Instead, we truncate the wtxid to just their first 128 bits. These are referred to as truncated IDs.
-
===Intended Protocol Flow===
Set reconciliation primarily consists of the transmission and decoding of a reconciliation set sketch upon request.
-[[File:bip-0330/recon_scheme_merged.png|framed|center|Set reconciliation protocol flow]]
+Since sketches are based on the WTXIDs, the negotiation and support of Erlay should be enabled only if both peers signal [https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki BIP-339] support.
-====Bisection====
+[[File:bip-0330/recon_scheme_merged.png|framed|center|Protocol flow]]
-If a node is unable to reconstruct the set difference from the received sketch, the node then makes an additional reconciliation request, similar to the initial one, but this request is applied to only a fraction of possible transactions (e.g., in the range 0x0–0x8). Because of the linearity of sketches, a sketch of a subset of transactions would allow the node to compute a sketch for the remainder, which saves bandwidth.
+====Sketch extension====
-[[File:bip-0330/bisection.png|framed|300px|center|Bisection]]
+If a node is unable to reconstruct the set difference from the received sketch, the node then makes a request for sketch extension. The peer would then send an extension, which is a sketch of a higher capacity (allowing to decode more differences) over the same transactions minus the sketch part which was already sent initially (to save bandwidth).
+To allow this optimization, the initiator is supposed to locally store a sketch received initially.
+This optimization is possible because extending a sketch is just concatenating new elements to an array.
===New messages===
-Several new protocol messages are added: sendrecon, reqreconcil, sketch, reqbisec, reconcildiff, invtx, gettx. This section describes their serialization, contents, and semantics.
+Several new protocol messages are added: sendtxrcncl, reqrecon, sketch, reqsketchext, reconcildiff. This section describes their serialization, contents, and semantics.
In what follows, all integers are serialized in little-endian byte order. Boolean values are encoded as a single byte that must be 0 or 1 exactly. Arrays are serialized with the CompactSize prefix that encodes their length, as is common in other P2P messages.
-====sendrecon====
-The sendrecon message announces support for the reconciliation protocol. It is expected to be only sent once, and ignored by nodes that don't support it.
+====sendtxrcncl====
+The sendtxrcncl message announces support for the reconciliation protocol. It is expected to be only sent once, and ignored by nodes that don't support it.
+
+Should be sent before "verack" and accompanied by "wtxidrelay" (in any order).
+
+If "sendtxrcncl" was sent after "verack", the sender should be disconnected.
+
+If "sendtxrcncl" was sent before "verack", but by "verack" the "wtxidrelay" message was not received,
+"sendtxrcncl" should be ignored. The connection should proceed normally, but as if reconciliation
+was not supported.
+
+Must not be sent if peer specified no support for transaction relay (fRelay=0) in "version".
+Otherwise, the sender should be disconnected.
Its payload consists of:
{|class="wikitable"
! Data type !! Name !! Description
|-
-| bool || sender || Indicates whether the sender will send "reqreconcil" message
-|-
-| bool || responder || Indicates whether the sender will respond to "reqreconcil" messages.
-|-
-| uint32 || version || Sender must set this to 1 currently, otherwise receiver should ignore the message.
+| uint32 || version || Sender must set this to 1 currently, otherwise receiver should ignore the message. v1 is the lowest protocol version, everything below that is a protocol violation.
|-
| uint64 || salt || The salt used in the short transaction ID computation.
|}
-"reqreconcil" messages can only be sent if the sender has sent a "sendrecon" message with sender=true, and the receiver has sent a "sendrecon" message with responder=true.
+After both peers have confirmed support by sending "sendtxrcncl", the initiator of the P2P connection assumes the role of reconciliation initiator (will send "reqrecon" messages) and the other peer assumes the role of reconciliation responder (will respond to "reqrecon" messages).
+"reqrecon" messages can only be sent by the reconciliation initiator.
-====reqreconcil====
-The reqreconcil message initiates a reconciliation round.
+====reqrecon====
+The reqrecon message initiates a reconciliation round.
{|class="wikitable"
! Data type !! Name !! Description
|-
| uint16 || set_size || Size of the sender's reconciliation set, used to estimate set difference.
|-
-| uint8 || q || Coefficient used to estimate set difference. Multiplied by PRECISION=2^6 and rounded up by the sender and divided by PRECISION by the receiver.
+| uint16 || q || Coefficient used to estimate set difference. Multiplied by PRECISION=(2^15) - 1 and rounded up by the sender and divided by PRECISION by the receiver.
|}
-Upon receipt of a "reqreconcil" message, the receiver:
-* Constructs and sends a "sketch" message (see below), with a sketch of capacity computed as ''|set_size - local_set_size| + q * (set_size + local_set_size) + c'', where ''local_set_size'' represents size of the receiver's reconciliation set.
+Upon receipt of a "reqrecon" message, the receiver:
+* Constructs and sends a "sketch" message (see below), with a sketch of certain ''capacity=f(set_size, local_set_size, q)'' (the exact function is suggested below), where ''local_set_size'' represents size of the receiver's reconciliation set.
* Makes a snapshot of their current reconciliation set, and clears the set itself. The snapshot is kept until a "reconcildiff" message is received by the node.
-It is suggested to use ''c=1'' to avoid sending empty sketches and reduce the overhead caused by under-estimations.
-
-Intuitively, ''q'' represents the discrepancy in sets: the closer the sets are, the lower optimal ''q'' is.
-As suggested by Erlay, ''q'' should be derived as an optimal ''q'' value for the previous reconciliation with a given peer, once the actual set sizes and set difference are known. Alternatively, ''q=0.1'' should be used as a default value.
-For example, if in previous round ''set_size=30'' and ''local_set_size=20'', and the *actual* difference was ''4'', then a node should compute ''q'' as following:
-''q=(|30-20| - 1) / (30+20)=0.18''
-The derivation of ''q'' can be changed according to the version of the protocol.
-
-No new "reqreconcil" message can be sent until a "reconcildiff" message is sent.
+No new "reqrecon" message can be sent until a "reconcildiff" message is sent.
====sketch====
The sketch message is used to communicate a sketch required to perform set reconciliation.
@@ -177,21 +178,29 @@ The sketch message is used to communicate a sketch required to perform set recon
| byte[] || skdata || The sketch of the sender's reconciliation snapshot
|}
-Upon receipt of a "sketch" message, a node computes the set difference by combining the receiver sketch with a sketch computed locally for a corresponding reconciliation set. If this is the 2nd time for this round a "sketch" message was received, the bisection approach is used, and by combining the new sketch with the previous one, two difference sketches are obtained, one for the first half and one for the second half of the short id range. The receiving node then tries to decode this sketch (or sketches), and based on the result:
-* If decoding fails, a "reconcildiff" message is sent with the failure flag set (success=false). If this was the first "sketch" in the round, a "reqbisec" message may be sent instead.
-* If decoding succeeds, a "reconcildiff" message is sent with the truncated IDs of all locally known transactions that appear in the decode result, and the short IDs of the unrecognized ones.
+The sketch message may be received in two cases.
-The receiver also makes snapshot of their current reconciliation set, and clears the set itself. The snapshot is kept until a "reconcildiff" message is sent by the node.
+1. Initial sketch. Upon receipt of a "sketch" message, a node computes the difference sketch by combining the received sketch with a sketch computed locally for a corresponding reconciliation set. The receiving node then tries to decode the difference sketch and based on the result:
+* If the decoding failed, the receiving node requests an extension sketch by sending a "reqsketchext" message. Alternatively, the node may terminate the reconciliation right away by sending a "reconcildiff" message is sent with the failure flag set (success=false).
+* If the decoding succeeded, a "reconcildiff" message with success=true.
+The receiver also makes snapshot of their current reconciliation set, and clears the set itself. The snapshot is kept until a "reconcildiff" message is sent by the node. It is needed to enable sketch extension.
-====reqbisec====
-The reqbisec message is used to signal that set reconciliation has failed and an extra sketch is needed to find set difference.
+2. Sketch extension. By combining the sketch extension with the initially received sketch, an extended sketch is obtained. The receiving node then computes the extended difference sketch by combining the received extended sketch with an extended sketch computed locally over a corresponding reconciliation set snapshot. The receiving node then tries to decode the extended difference sketch and based on the result:
+* If the decoding failed, the receiving node terminates the reconciliation right away by sending a "reconcildiff" message is sent with the failure flag set (success=false).
+* If the decoding succeeded, a "reconcildiff" message with success=true.
+
+In either cases, a "reconcildiff" with success=false should also be accompanied with announcing all transactions from the reconciliation set (or set snapshot if failed after extension) as a fallback to flooding.
+A "reconcildiff" with success=true should contain unknown short IDs of the transactions from the decoded difference, corresponding to the transactions missing on the sender's side. Known short IDs from the difference correspond to what the receiver of the message is missing, and they should be announced via an "inv" message.
+
+====reqsketchext====
+The reqsketchext message is used by reconciliation initiator to signal that initial set reconciliation has failed and a sketch extension is needed to find set difference.
It has an empty payload.
-Upon receipt of a "reqbisec" message, a node responds to it with a "sketch" message, which contains a sketch of a subset of corresponding reconciliation set snapshot (stored when "reqreconcil" message for the current round was processed) (values in range ''[0..(2^31)]'').
+Upon receipt of a "reqsketchext" message, a node responds to it with a "sketch" message, which contains a sketch extension: a sketch (of the same transactions sketched initially) of higher capacity without the part sent initially.
====reconcildiff====
-The reconcildiff message is used to announce transactions which are found to be missing during set reconciliation on the sender's side.
+The reconcildiff message is used by reconciliation initiator to announce transactions which are found to be missing during set reconciliation on the sender's side.
{|class="wikitable"
! Data type !! Name !! Description
@@ -201,57 +210,46 @@ The reconcildiff message is used to announce transactions which are found to be
| uint32[] || ask_shortids || The short IDs that the sender did not have.
|}
-Upon receipt a "reconcildiff" message with ''success=1'', a node sends a "invtx" message for the transactions requested by 32-bit IDs (first vector) containing their 128-bit truncated IDs (with parent transactions occuring before their dependencies), and can request announced transactions (second vector) it does not have via a "gettx" message.
-Otherwise if ''success=0'', receiver should request bisection via ''reqbisec'' (if failure happened for the first time).
-If failure happened for the second time, receiver should announce the transactions from the reconciliation set via an "invtx" message, excluding the transactions announced from the sender.
+Upon receipt a "reconcildiff" message with ''success=1'' (reconciliation success), a node sends an "inv" message for the transactions requested by 32-bit IDs (first vector) containing their wtxids (with parent transactions occurring before their dependencies).
+If ''success=0'' (reconciliation failure), receiver should announce all transactions from the reconciliation set via an "inv" message.
+In both cases, transactions the sender of the message thinks the receiver is missing are announced via an "inv" message.
+The regular "inv" deduplication should apply.
The snapshot of the corresponding reconciliation set is cleared by the sender and the receiver of the message.
-The sender should also send their own "invtx" message along with the reconcildiff message to announce transactions which are missing on the receiver's side.
-
-====invtx====
-The invtx message is used to announce transactions (both along with reconcildiff message and as a response to the reconcildiff message). It is the truncated ID analogue of "inv" (which cannot be used because it has 256-bit elements).
-
-{|class="wikitable"
-! Data type !! Name !! Description
-|-
-| uint128[] || inv_truncids || The truncated IDs of transactions the sender believes the receiver does not have.
-|}
-
-Upon receipt a "invtx" message, a node requests announced transactions it does not have.
-The snapshot of the corresponding reconciliation set is cleared by the sender of the message.
-
-====gettx====
-The gettx message is used to request transactions by 128-bit truncated IDs. It is the truncated ID analogue of "getdata".
-
-{|class="wikitable"
-! Data type !! Name !! Description
-|-
-| uint128[] || ask_truncids || The truncated IDs of transactions the sender wants the full transaction data for.
-|}
-
-Upon receipt a "gettx" message, a node sends "tx" messages for the requested transactions.
+The sender should also send their own "inv" message along with the reconcildiff message to announce transactions which are missing on the receiver's side.
==Local state==
This BIP suggests a stateful protocol and it requires storing several variables at every node to operate properly.
+====Reconciliation salt====
+When negotiating reconciliation support, peers send each other their contribution to the reconciliation salt (see how we construct short IDs above). These salts (or just the resulting salt) should be stored on both sides of the connection.
+
====Reconciliation sets====
-Every node stores a set of 128-bit truncated IDs for every peer which supports transaction reconciliation, representing the transactions which would have been sent according to the regular flooding protocol.
+Every node stores a set of wtxids for every peer which supports transaction reconciliation, representing the transactions which would have been sent according to the regular flooding protocol.
Incoming transactions are added to sets when those transactions are received (if they satisfy the policies such as minimum fee set by a peer).
A reconciliation set is moved to the corresponding set snapshot after the transmission of the initial sketch.
====Reconciliation set snapshot====
-After the transmitting of the initial sketch (either sending or receiving of reconcildiff message), every node should store the snapshot of the current reconciliation set, and clear the set.
-This is important to make bisection more stable during the reconciliation round (bisection should be applied to the snapshot).
-The snapshot is also used to efficiently lookup the transactions requested by short ID.
+After transmitting the initial sketch (either sending or receiving of the reconcildiff message), every node should store the snapshot of the current reconciliation set, and clear the set.
+This is important to make sketch extension more stable (extension should be computed over the set snapshot). Otherwise, extension would contain transactions received after sending out the initial sketch.
The snapshot is cleared after the end of the reconciliation round (sending or receiving of the reconcildiff message).
-====q-coefficient====
-The q value should be stored to make efficient difference estimation. It is shared across peers and changed after every reconciliation.
-q-coefficient represents the discrepancy in sets: the closer the sets are, the lower optimal ''q'' is.
-In future implementations, q could vary across different peers or become static.
+====Sketch capacity estimation and q-coefficient====
+
+Earlier we suggested that upon receiving a reconciliation request, a node should estimate the sketch capacity it should send: ''capacity=f(set_size, local_set_size, q)''.
+
+We suggest the following function: ''capacity=|set_size - local_set_size| + q * min(set_size, local_set_size) + c''.
+
+Intuitively, ''q'' represents the discrepancy in sets: the closer the sets are, the lower optimal ''q'' is.
+Per the Erlay paper, ''q'' should be derived as an optimal ''q'' value for the previous reconciliation with a given peer, once the actual set sizes and set difference are known.
+For example, if in previous round ''set_size=30'' and ''local_set_size=20'', and the *actual* difference was ''12'', then a node should compute ''q'' as following:
+''q=(12 - |30-20|) / min(30, 20)=0.1''
+
+The derivation of ''q'' can be changed according to the version of the protocol. For example, a static value could be chosen for simplicity. However, we suggest that ''q'' remains a parameter sent in every reconciliation request to enable future compatibility with more sophisticated (non-static) choices of this parameter.
+As for the ''c'' parameter, it is suggested to use ''c=1'' to avoid sending empty sketches and reduce the overhead caused by under-estimations.
==Backward compatibility==
@@ -261,32 +259,36 @@ Clients which do not implement this protocol remain fully compatible after this
==Rationale==
-====Why using PinSketch for set reconciliation?====
+====Why use PinSketch for set reconciliation?====
PinSketch is more bandwidth efficient than IBLT, especially for the small differences in sets we expect to operate over.
PinSketch is as bandwidth efficient as CPISync, but PinSketch has quadratic decoding complexity, while CPISync have cubic decoding complexity. This makes PinSketch significantly faster.
-====Why using 32-bit short transaction IDs?====
+====Why use 32-bit short transaction IDs?====
To use Minisketch in practice, transaction IDs should be shortened (ideally, not more than 64 bits per element).
-Small number of bits per transaction also allows to save extra bandwidth and make operations over sketches faster.
+A small number of bits per transaction also allows saving extra bandwidth and make operations over sketches faster.
According to our estimates, 32 bits provides low collision rate in a non-adversarial model (which is enabled by using independent salts per-link).
-====Why using 128-bit short IDs?====
+====Why use sketch extensions instead of bisection?====
+
+Bisection is an alternative to sketch extensions, per which a second sketch with the same initial capacity is computed over half of the txID space.
+Due to the linearity of sketches, transmitting just this one allows a reconciliation initiator to compute the sketch of the same capacity of another half. Two sketches allow the initiator to reconstruct twice as many differences as was allowed by an initial sketch.
+
+In practice this allows the initiator to amortize the bandwidth overhead of initial reconciliation failure, similarly to extension sketches, making the overhead negligible.
+
+The main benefit of sketch extensions is a much simpler implementation. Implementing bisection is hard (see [https://github.com/naumenkogs/bitcoin/commit/b5c92a41e4cc0599504cf838d20212f1a403e573 implementation]) because, in the end, we have to operate with two sketches and handle scenarios where one sketch decoded and another sketch failed.
-To avoid problems caused by the delays in the network, our protocol requires extra round of announcing unsalted transaction IDs. [https://arxiv.org/pdf/1905.10518.pdf Erlay] protocol on top of this work also requires announcing unsalted transaction IDs for flooding.
-Both of these measures allow to deduplicate transaction announcements across the peers.
-However, using full 256-bit IDs to uniquely identify transactions seems to be an overkill.
-128 is the highest power of 2 which provides good enough collision-resistance in an adversarial model, and trivially saves a significant portion of the bandwidth related to these announcements.
+It becomes even more difficult if in the future we decide to allow more than one extension/bisection. Bisection in this case have to be recursive (and spawn 4/8/16/... sketches), while for extensions we always end up with one extended sketch.
-====Why using bisection instead of extending the sketch?====
+Sketch extensions are also more flexible: extending a sketch of capacity 10 with 4 more means just computing a sketch of capacity 14 and sending the extension, while for bisection increasing the capacity to something different than 10*2/10*4/10*8/... is sophisticated implementation-wise.
-Unlike extended sketches, bisection does not require operating over sketches of higher order.
-This allows to avoid the high computational cost caused by quadratic decoding complexity.
+The only advantage of bisection is that it doesn't require computing sketches of higher capacities (exponential cost). We believe that since
+the protocol is currently designed to operate in the conditions where sketches usually have at most the capacity of 20, this efficiency is not crucial.
==Implementation==
-TODO
+https://github.com/bitcoin/bitcoin/pull/21515
==Acknowledgments==
diff --git a/bip-0330/bisection.png b/bip-0330/bisection.png
deleted file mode 100644
index 70f37e8853..0000000000
Binary files a/bip-0330/bisection.png and /dev/null differ
diff --git a/bip-0330/minisketch.py b/bip-0330/minisketch.py
index f64286fd8b..5e3977935d 100755
--- a/bip-0330/minisketch.py
+++ b/bip-0330/minisketch.py
@@ -120,7 +120,7 @@ def find_roots_inner(p, a):
return []
elif len(p) == 2:
return [p[0]]
- # Otherwise, split p in left*right using paramater a_vals[0].
+ # Otherwise, split p in left*right using parameter a_vals[0].
t = poly_monic(poly_trace(p, a))
left = poly_gcd(list(p), t)
right = poly_divmod(list(left), p)
diff --git a/bip-0330/recon_scheme_merged.png b/bip-0330/recon_scheme_merged.png
index 11d155927d..546b4170c4 100644
Binary files a/bip-0330/recon_scheme_merged.png and b/bip-0330/recon_scheme_merged.png differ
diff --git a/bip-0331.mediawiki b/bip-0331.mediawiki
new file mode 100644
index 0000000000..472540c0bb
--- /dev/null
+++ b/bip-0331.mediawiki
@@ -0,0 +1,430 @@
+
+
+==Abstract==
+
+Peer-to-peer protocol messages enabling nodes to request and relay the unconfirmed ancestor package
+of a given transaction, and to request and relay transactions in batches.
+
+==Motivation==
+
+===Propagate High Feerate Transactions===
+
+Since v0.13, Bitcoin Core has used ancestor packages instead of individual transactions to evaluate
+the incentive compatibility of transactions in the mempool
+[https://github.com/bitcoin/bitcoin/pull/7594 Add tracking of ancestor packages] and
+selecting them for inclusion in blocks
+[https://github.com/bitcoin/bitcoin/pull/7600 Select transactions using feerate-with-ancestors].
+Incentive-compatible mempool and miner policies help create a fair, fee-based market for block
+space. While miners maximize transaction fees in order to earn higher block rewards, non-mining
+users participating in transaction relay reap many benefits from employing policies that result in a
+mempool with similar contents, including faster compact block relay and more accurate fee
+estimation. Additionally, users may take advantage of mempool and miner policy to bump the priority
+of their transactions by attaching high-fee descendants (Child Pays for Parent or CPFP).
+
+Only individually considering transactions for submission to the mempool creates a limitation in
+the node's ability to determine which transactions to include in the mempool, since it cannot take
+into account descendants until all the transactions are in the mempool. Similarly, it cannot use a
+transaction's descendants when considering which of two conflicting transactions to keep (Replace by
+Fee or RBF).
+
+When a user's transaction does not meet a mempool's minimum feerate and they cannot create a
+replacement transaction directly, their transaction will simply be rejected by this mempool or
+evicted if already included. They also cannot attach a descendant to pay for replacing a conflicting
+transaction; it would be rejected for spending inputs that do not exist.
+
+This limitation harms users' ability to fee-bump their transactions. Further, it presents security and complexity
+issues in contracting protocols which rely on presigned, time-sensitive transactions'''Examples of time-sensitive pre-signed transactions in L2 protocols.'''
+* [https://github.com/lightning/bolts/blob/master/03-transactions.md#htlc-timeout-and-htlc-success-transactions HTCL-Timeout in LN Penalty]
+* [https://github.com/revault/practical-revault/blob/master/transactions.md#cancel_tx Unvault Cancel in Revault]
+* [https://github.com/discreetlogcontracts/dlcspecs/blob/master/Transactions.md#refund-transaction Refund Transaction in Discreet Log Contracts]
+* [https://gist.github.com/instagibbs/60264606e181451e977e439a49f69fe1 Updates in Eltoo]
+* [https://github.com/ElementsProject/peerswap/blob/master/docs/peer-protocol.md#claim-transaction Claim Transactions in PeerSwap]
+ to prevent cheating.
+In other words, a key security assumption of many contracting protocols is that all parties can
+propagate and confirm transactions in a timely manner. Increasing attention has been brought to
+"pinning attacks," a type of censorship in which the attacker uses mempool policy restrictions to
+prevent a transaction from being relayed or getting mined.
+'''Concerns for pinning attacks in L2 protocols'''
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020458.html Greg Sanders, "Bringing a nuke to a knife fight: Transaction introspection to stop RBF pinning"]
+* [https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-April/002639.html Matt Corallo, "RBF Pinning with Counterparties and Competing Interest"]
+* [https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-June/002758.html Antoine Riard, "Pinning : The Good, The Bad, The Ugly"]
+* [https://github.com/t-bast/lightning-docs/blob/master/pinning-attacks.md Bastien Teinturier, "Pinning Attacks"]
+* [https://gist.github.com/instagibbs/60264606e181451e977e439a49f69fe1 Greg Sanders, "Eltoo Pinning"]
+
+
+These transactions must meet a certain confirmation target to be effective, but their feerates
+are negotiated well ahead of broadcast time. If the forecast feerate was too low and no
+fee-bumping options are available, attackers can steal money from their counterparties. Always
+overestimating fees may sidestep this issue (but only while mempool traffic is low and
+predictable), but this solution is not guaranteed to work and wastes users' money. For some attacks,
+the available defenses require nodes to have a bird's-eye view of Bitcoin nodes' mempools, which is
+an unreasonable security requirement.
+
+Part of the solution is to enable nodes to consider packages of transactions as a unit, e.g. one or
+more low-fee ancestor transactions with a high-fee descendant, instead of separately. A package-aware
+mempool policy can help determine if it would actually be economically rational to accept a
+transaction to the mempool if it doesn't meet fee requirements individually. Network-wide adoption
+of these policies would create a more purely-feerate-based market for block space and allow
+contracting protocols to adjust fees (and therefore mining priority) at broadcast time.
+
+Theoretically, developing a safe and incentive-compatible package mempool acceptance policy is
+sufficient to solve this issue. Nodes could opportunistically accept packages (e.g. by trying
+combinations of transactions rejected from their mempools), but this practice would likely be
+inefficient at best and open new Denial of Service attacks at worst. As such, this proposal
+suggests adding new p2p messages enabling nodes to request and share package-validation-related
+information with one another, resulting in a more efficient and reliable way to propagate packages.
+
+===Handle Orphans Better===
+
+Txid-based transaction relay is problematic since a transaction's witness may be malleated without
+changing its txid; a node cannot use txid to deduplicate transactions it has already downloaded
+or validated. Ideally, two nodes that both support BIP339 wtxid-based transaction relay shouldn't
+ever need to use txid-based transaction relay.
+
+A single use case of txid-based relay remains: handling "orphan" transactions that spend output(s)
+from an unconfirmed transaction the receiving node is unaware of. Orphan transactions are very
+common for new nodes that have just completed Initial Block Download and do not have an up-to-date
+mempool. Nodes also download transactions from multiple peers. If the peer from which a child
+transaction was requested responds faster than the peer from which its parent was requested, that
+child is seen as an orphan transaction.
+
+Nodes may handle orphans by storing them in a cache and requesting any missing parent(s) by txid
+(prevouts specify txid, not wtxid). These parents may end up being orphans as well, if they also
+spend unconfirmed inputs that the node is unaware of. This method of handling orphans is problematic
+for two reasons: it requires nodes to allocate memory for unvalidated data received on the p2p
+network and it relies on txid-based relay between two wtxid-relay peers.
+
+This proposal makes orphan resolution more efficient and no longer require txid-based relay.
+
+==Definitions==
+
+Given any two transactions Tx0 and Tx1 where Tx1 spends an output of Tx0, Tx0 is a '''parent''' of
+Tx1 and Tx1 is a '''child''' of Tx0.
+
+A transaction's '''ancestors''' include, recursively, its parents, the parents of its parents, etc.
+A transaction's '''descendants''' include, recursively, its children, the children of its children,
+etc. A transaction's parent is its ancestor, but an ancestor is not necessarily a parent.
+
+A '''package''' is a list of transactions, representable by a connected Directed Acyclic
+Graph (a directed edge exists between a transaction that spends the output of another transaction).
+In this proposal, a package is limited to unconfirmed transactions.
+
+An '''ancestor package''' consists of an unconfirmed transaction with all of its unconfirmed
+ancestors.
+
+In a '''topologically sorted''' package, each parent appears somewhere in the list before its child.
+
+==Specification==
+
+Ancestor Package Relay includes two parts: a package information round and a transaction data
+download round.
+The package information round is used to help a receiver learn what transactions are in a package and
+decide whether they want to download them. The transaction data round is used to help a node download
+multiple transactions in one message instead of as separate messages.
+'''Why are package information and transaction data rounds both necessary?'''
+
+Several alternative designs were considered. One should measure alternative solutions based on the
+resources used to communicate (not necessarily trustworthy) information: We would like to minimize
+network bandwidth, avoid downloading a transaction more than once, avoid downloading transactions
+that are eventually rejected, and minimize storage allocated for not-yet-validated transactions.
+
+
+
+'''No Package Information Round:''' One proposal is to just use the child's wtxid to refer to the
+package and always send the entire package together, skipping the package information round.
+However, this protocol would make it very likely for honest nodes to redownload duplicate
+transactions. See the following example, where the high-feerate ancestors were already downloaded
+and accepted individually.
+
+[[File:./bip-0331/no_package_info.png|600px]]
+
+
+'''Package Information Only:''' Just having package information gives enough information for the
+receiver to accept the packages. That is, rather than using "getpkgtxns" and "pkgtxns" messages,
+send "getdata" and download the transactions individually. While this option is a potential fallback
+if batched transaction download fails for some reason, it shouldn't be used as the default because
+it always requires storage of unvalidated transactions.
+[[File:./bip-0331/package_info_only.png|1000px]]
+
+
+Package relay is negotiated between two peers during the version handshake using a "sendpackages"
+message. The versions field within "sendpackages" is interpreted as a bitfield; peers may relay
+multiple versions of packages. Package relay requires both peers to support wtxid-based relay
+because package transactions are referenced by their wtxids.
+'''Why do we need multiple versions? Why can't we just support arbitrary packages?'''
+Attempting to support arbitrary packages in mempool validation may result in very complex logic, new
+Denial of Service attack vectors, and policy limitations that could be leveraged to censor
+transactions (aka "pinning attacks"). This protocol is extensible to support other types of
+packages based on future desired use cases. Future package information messages may describe
+different types of packages and/or contain more information than a list of wtxids, e.g. feerate or
+relationships between transactions.
+'''Why use a bitfield instead of a numbering system?'''
+It should be possible to support some subset of the existing package types.
+
+[[File:./bip-0331/version_negotiation.png|400px]]
+
+Nodes indicate support for batched transaction data round ("getpkgtxns", "pkgtxns", and
+"MSG_PKGTXNS") using the PKG_RELAY_PKGTXNS = (1 << 0) bit in their "sendpackages"
+messages during version handshake. They indicate support for the ancestor package information
+round ("ancpkginfo", "MSG_ANCPKGINFO") using the PKG_RELAY_ANC = (1 << 1) bit in their
+"sendpackages" messages during version handshake.
+
+===Protocol Flow Examples===
+
+This package relay protocol satisfies both use cases (orphan transaction handling and high-feerate
+transaction paying for low-feerate ancestors).
+
+====Orphan Transaction Handling====
+
+Upon receiving an orphan transaction, a node may request ancestor package information delineating
+the wtxids of the transaction's unconfirmed ancestors. This is done without using txid-based relay.
+The package information can be used to request transaction data. As these transactions are dependent
+upon one another to be valid, the transactions can be requested and sent as a batch.
+
+Contrast this protocol with legacy orphan handling, which requires requesting the missing
+transactions by their txids and may require new round trips for each generation of missing parents.
+[[File:./bip-0331/orphan_handling_flow.png|1000px]]
+
+====Fee-Bumped Transactions====
+
+Too-low-feerate transactions (i.e. below the node's minimum mempool feerate) with high-feerate
+descendants can also be relayed this way. If the peers are using BIP133 fee filters and a
+low-feerate transaction is below the node's fee filter, the sender will not announce it. The
+high-feerate transaction will be sent by the sender, and received and handled as an orphan by the
+receiver, the transactions are validated as a package, and so the protocol naturally works for this
+use case.
+
+This does not mean BIP133 is required for package relay to work, provided that nodes do not
+immediately reject transactions previously found to be too low feerate. If the low-feerate
+transaction was sent and rejected, the receiver should later re-request and accept it after learning
+that it is the ancestor of another transaction, and that they meet the receiver's mempool policy
+requirements when validated together.
+
+[[File:./bip-0331/package_cpfp_flow.png|600px]]
+
+This protocol is receiver-initiated only; nodes do not proactively announce packages to their peers.
+'''Why no sender-initiated protocol?''' Sender-initiated package
+relay can, theoretically, save a round trip by notifying the receiver ahead of time that they will
+probably need to request and validate a group of transactions together in order for them to be
+accepted. As with any proactive communication, there is a chance that the receiver already knows
+this information, so this network bandwidth may be wasted. Shortened latency is less significant
+than wasted bandwidth.
+
+The logic used to decide when to announce a package proactively determines whether it is a net
+increase or decrease for overall bandwidth usage. However, it is difficult to design anything to
+save bandwidth without any idea of what its bandwidth usage actually looks like in practice. No
+historical data is available, as one of the primary goals of this protocol is to enable
+currently-rejected transactions to propagate. After deploying receiver-initiated package relay, we
+can observe its usage and then introduce a sender-initiated package relay protocol informed by data
+collected from the p2p network.
+
+===Combined Hash===
+
+A "combined hash" serves as a unique "package id" for some list of transactions and helps provide a
+meaningful but short "notfound" response to "getpkgtxns."
+
+The combined hash of a package of transactions is equal to the sha256 hash of each transaction's
+wtxid concatenated in lexicographical order.
+
+===New Messages===
+
+Four new protocol messages and two inv types are added.
+
+====sendpackages====
+
+{|
+| Field Name || Type || Size || Purpose
+|-
+|versions || uint64_t || 8 || Bit field that is 64 bits wide, denoting the package versions supported by the sender.
+|-
+|}
+
+# The "sendpackages" message has the structure defined above, with pchCommand == "sendpackages".
+
+# During version handshake, nodes should send one "sendpackages" message indicating they support package relay, with the versions field indicating which versions they support.
+
+# The "sendpackages" message MUST be sent before sending a "verack" message. If a "sendpackages" message is received after "verack", the sender may be disconnected.
+
+# Upon successful connection ("verack" sent by both peers), a node may relay packages with the peer if they did not set "fRelay" to false in the "version" message, both peers sent "wtxidrelay", and both peers sent "sendpackages" for matching version bit(s). Unknown bits (including versions==0) should be ignored. Peers should relay packages corresponding to versions that both sent "sendpackages" for.'''Is it ok to send "sendpackages" to a peer that specified fRelay=false in their "version" message?'''
+Yes, this is allowed in order to reduce the number of negotiation steps. This means nodes can
+announce features without first checking what the other peer has sent, and then apply negotiation
+logic at the end based on what was sent and received. See [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020510.html this discussion].
+
+
+====ancpkginfo====
+{|
+| Field Name || Type || Size || Purpose
+|-
+|txns_length||CompactSize||1 or 3 bytes|| The number of transactions provided.
+|-
+|txns||List of wtxids||txns_length * 32|| The wtxids of each transaction in the package.
+|}
+
+# The "ancpkginfo" message has the structure defined above, with pchCommand == "ancpkginfo".
+
+# The "txns" field should contain a list of wtxids which constitute the ancestor package of the last wtxid. For the receiver's convenience, the sender should - but is not required to - sort the wtxids in topological order. The topological sort can be achieved by sorting the transactions by mempool acceptance order (if parents are always accepted before children). Apart from the last wtxid which is used to learn which transaction the message corresponds to, there is no enforced ordering. Nodes should not disconnect or punish a peer who provides a list not sorted in topological order.'''Why not include feerate information to help the receiver decide whether these transactions are worth downloading?'''
+A simple feerate is typically insufficient; the receiver must also know the dependency
+relationships between transactions and their respective sizes.
+'''Should a peer be punished if they provide incorrect package info, e.g. a list of unrelated transactions?'''
+Ideally, there should be a way to enforce that peers are providing correct information to each
+other. However, two peers may have different views of what a transaction's unconfirmed ancestors
+are based on their chainstate. For example, during a reorg or when two blocks are found at the same
+time, one peer may see a transaction as confirmed while the other peer does not.
+As such, it is impossible to accurately enforce this without also knowing the peer's chainstate.
+It was [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020493.html originally proposed]
+to include a block hash in "ancpkginfo" to avoid unwarranted disconnections. However, it does not
+make much sense to stop or delay transaction data requests due to mismatched chainstates, and the
+chainstate may change again between package information and transaction data rounds. Instead,
+differences in chainstate should be handled at the validation level. The node has already spent
+network bandwidth downloading these transactions; it should make a best effort to validate them.
+See [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-June/020558.html discussion].
+'''Why not require topological order?'''
+It is not possible to determine whether a list of transactions is topologically sorted without first
+establishing that the list contains a full ancestor package. It is not possible to determine whether
+a list of transactions contains a full ancestor package without knowing what the chainstate is.
+
+
+# Upon receipt of a "ancpkginfo" message, the node may use it to request the transactions it does not already have (e.g. using "getpkgtxns" or "tx").
+
+# Upon receipt of a malformed "ancpkginfo" message, the sender may be disconnected. An "ancpkginfo" message is malformed if it contains duplicate wtxids or conflicting transactions (spending the same inputs). The receiver may learn that a package info was malformed after downloading the transactions.
+
+# A node MUST NOT send a "ancpkginfo" message that has not been requested by the recipient. Upon receipt of an unsolicited "ancpkginfo", a node may disconnect the sender.
+
+# This message must only be used if both peers set PKG_RELAY_ANC in their "sendpackages" message. If an "ancpkginfo" message is received from a peer with which this type of package relay was not negotiated, no response should be sent and the sender may be disconnected.
+
+====MSG_ANCPKGINFO====
+
+# A new inv type (MSG_ANCPKGINFO == 0x7) is added, for use only in getdata requests pertaining to ancestor packages.
+
+# As a getdata request type, it indicates that the sender wants an "ancpkginfo" containing all of the unconfirmed ancestors of a transaction, referenced by wtxid.
+
+# Upon receipt of a "getdata(MSG_ANCPKGINFO)" request, the node should respond with an "ancpkginfo" message corresponding to the transaction's unconfirmed ancestor package, or with "notfound". The wtxid of the requested transaction must be the last item in the "ancpkginfo" response list, as the last item is used to determine which transaction the "ancpkginfo" pertains to.
+
+# The inv type must only be used in a "getdata" message. An "inv(MSG_ANCPKGINFO)" must never be sent. If an "inv(MSG_ANCPKGINFO)" is received, the sender may be disconnected.
+
+# This inv type must only be used if both peers set PKG_RELAY_ANC in their "sendpackages" message. If a "getdata" message with type MSG_ANCPKGINFO is received from a peer with which this type of package relay was not negotiated, no response should be sent and the sender may be disconnected.
+
+====getpkgtxns====
+
+{|
+| Field Name || Type || Size || Purpose
+|-
+|txns_length||CompactSize||1 or 3 bytes|| The number of transactions requested.
+|-
+|txns||List of wtxids||txns_length * 32|| The wtxids of each transaction in the package.
+|}
+
+# The "getpkgtxns" message has the structure defined above, with pchCommand == "getpkgtxns".
+
+# A "getpkgtxns" message should be used to request some list of transactions specified by witness transaction id. It indicates that the node wants to receive either all the specified transactions or none of them. This message is intended to allow nodes to avoid downloading and storing transactions that cannot be validated without each other. The list of transactions does not need to correspond to a previously-received ancpkginfo message.
+
+# Upon receipt of a "getpkgtxns" message, a node should respond with either a "pkgtxns" containing all of the requested transactions in the same order specified in the "getpkgtxns" request or one "notfound" message of type MSG_PKGTXNS and combined hash of all of the wtxids in the "getpkgtxns" request (only one "notfound" message and nothing else), indicating one or more of the transactions is unavailable.
+
+# A "getpkgtxns" message must contain at most 100 wtxids. Upon receipt of a "getpkgtxns" message with more than 100 wtxids, a node may ignore the message (to avoid calculating the combined hash) and disconnect the sender.
+
+# This message must only be used if both peers set PKG_RELAY_PKGTXNS in their "sendpackages" message. If a "getpkgtxns" message is received from a peer with which this type of package relay was not negotiated, no response should be sent and the sender may be disconnected.
+
+====pkgtxns====
+
+{|
+| Field Name || Type || Size || Purpose
+|-
+|txns_length||CompactSize||1 or 3 bytes|| The number of transactions provided.
+|-
+|txns||List of transactions||variable|| The transactions in the package.
+|}
+
+# The "pkgtxns" message has the structure defined above, with pchCommand == "pkgtxns".
+
+# A "pkgtxns" message should contain the transaction data requested using "getpkgtxns".
+
+# A "pkgtxns" message should only be sent to a peer that requested the package using "getpkgtxns". If a node receives an unsolicited package, it may choose to validate the transactions or not, and the sender may be disconnected.
+
+# This message must only be used if both peers set PKG_RELAY_PKGTXNS in their "sendpackages" message. If a "pkgtxns" message is received from a peer with which this type of package relay was not negotiated, no response should be sent and the sender may be disconnected.
+
+====MSG_PKGTXNS====
+
+# A new inv type (MSG_PKGTXNS == 0x6) is added, for use only in "notfound" messages pertaining to package transactions.
+
+# As a "notfound" type, it indicates that the sender is unable to send all the transactions requested in a prior "getpkgtxns" message. The hash used is equal to the combined hash of the wtxids in the getpkgtxns request.
+
+# This inv type should only be used in "notfound" messages, i.e. "inv(MSG_PKGTXNS)" and "getdata(MSG_PKGTXNS)" must never be sent. Upon receipt of an "inv" or "getdata" message of this type, the sender may be disconnected.
+
+# This inv type must only be used if both peers set PKG_RELAY_PKGTXNS in their "sendpackages" message.
+
+==Compatibility==
+
+Older clients remain fully compatible and interoperable after this change. Clients implementing this
+protocol will only attempt to send and request packages if agreed upon during the version handshake.
+'''Will package relay cause non-package relay nodes to waste bandwidth on low-feerate transactions?'''
+If a node supports package relay, it may accept low-feerate transactions (e.g. paying zero fees)
+into its mempool, but non-package relay nodes would most likely reject them. To mitigate bandwidth
+waste, a package relay node should not announce descendants of below-fee-filter transactions to
+non-package relay peers.
+
+'''Is Package Erlay possible?'''
+A client using BIP330 reconciliation-based transaction relay (Erlay) is able to use package relay
+without interference. After reconciliation, any transaction with unconfirmed ancestors may have
+those ancestors resolved using ancestor package relay.
+[[File:./bip-0331/package_erlay.png|700px]]
+
+
+==Extensibility==
+
+This protocol can be extended to include more types of package information in the future, while
+continuing to use the same messages for transaction data download. One would define a new package
+information message (named "*pkginfo" in the diagram below), allocate its corresponding inv
+type (named "*PKGINFO" in the diagram below), and specify how to signal support using the
+versions field of "sendpackages" (an additional bit named "PKG_RELAY_*" in the diagram below). A
+future version of package relay may allow a sender-initiated dialogue by specifying that the package
+info type inv type can be used in an "inv" message.
+
+[[File:./bip-0331/sender_init_future_version.png|700px]]
+
+==Implementation==
+
+Sample implementation for Bitcoin Core: https://github.com/bitcoin/bitcoin/pull/27742
+
+A prerequisite for implementing a safe
+package relay protocol is a mempool acceptance policy that safely validates packages of
+transactions.
+'''Package Mempool Acceptance Policy'''
+Accepting packages from peers should not significantly increase a node's DoS attack surface;
+processing packages should not permit waste or exhaustion of the node and network's resources.
+Additionally, a sensible mempool acceptance policy should result in the most incentive-compatible
+subset of the package in the mempool in order to avoid adding more pinning attacks or censorship
+vectors. For example, It should not be assumed that packages are CPFPs. An ancestor package may
+include a high-feerate parent and low-feerate child; the policy may choose to accept the parent but
+not the child. If one or more transactions are policy-invalid, other transactions that are not
+dependent upon them should still be considered.
+
+
+==Acknowledgements==
+
+Thank you to Suhas Daftuar, John Newbery, Anthony Towns, Martin Zumsande, and others for input on the design.
+
+Thank you to Will Clark, Sergi Delgado, Fabian Jahr, John Newbery, Greg Sanders, Stéphan Vuylsteke, Pieter Wuille, and others for input on this document.
+
+Much of this work is inspired by ideas and code by Suhas Daftuar and Antoine Riard.
+'''Prior Work on Package Relay'''
+* [https://gist.github.com/sdaftuar/8756699bfcad4d3806ba9f3396d4e66a Strawman Proposal]
+* [https://github.com/bitcoin/bitcoin/issues/14895 Package relay design questions]
+* [https://github.com/bitcoin/bitcoin/pull/16401 Add package acceptance logic to mempool]
+* [https://github.com/bitcoin/bitcoin/pull/19621 [RFC] Package-relay: sender-initiated]
+
+
+==References and Rationale==
+
+
+
diff --git a/bip-0331/no_package_info.png b/bip-0331/no_package_info.png
new file mode 100644
index 0000000000..54b20f97dd
Binary files /dev/null and b/bip-0331/no_package_info.png differ
diff --git a/bip-0331/orphan_handling_flow.png b/bip-0331/orphan_handling_flow.png
new file mode 100644
index 0000000000..4588de84b1
Binary files /dev/null and b/bip-0331/orphan_handling_flow.png differ
diff --git a/bip-0331/package_cpfp_flow.png b/bip-0331/package_cpfp_flow.png
new file mode 100644
index 0000000000..6b48c5da65
Binary files /dev/null and b/bip-0331/package_cpfp_flow.png differ
diff --git a/bip-0331/package_erlay.png b/bip-0331/package_erlay.png
new file mode 100644
index 0000000000..fd3661ff5d
Binary files /dev/null and b/bip-0331/package_erlay.png differ
diff --git a/bip-0331/package_info_only.png b/bip-0331/package_info_only.png
new file mode 100644
index 0000000000..2bd0272606
Binary files /dev/null and b/bip-0331/package_info_only.png differ
diff --git a/bip-0331/sender_init_future_version.png b/bip-0331/sender_init_future_version.png
new file mode 100644
index 0000000000..d4a21050ec
Binary files /dev/null and b/bip-0331/sender_init_future_version.png differ
diff --git a/bip-0331/version_negotiation.png b/bip-0331/version_negotiation.png
new file mode 100644
index 0000000000..5b2f48cb60
Binary files /dev/null and b/bip-0331/version_negotiation.png differ
diff --git a/bip-0337.mediawiki b/bip-0337.mediawiki
new file mode 100644
index 0000000000..e87c5bc2c4
--- /dev/null
+++ b/bip-0337.mediawiki
@@ -0,0 +1,301 @@
+
+
+== Introduction ==
+
+=== Abstract ===
+This document proposes a serialization scheme for compressing Bitcoin transactions. The compressed Bitcoin transactions can reach a serialized size of less than 50% of the original serialized transaction. One method for compressing involves reducing the transaction outpoints in a potentially lossy way. Therefore, it is an optional path for compression. Compressing the outpoints is necessary for compressed transactions to reach less than 70% of the original size.
+
+=== Motivation ===
+Typical Bitcoin transactions usually contain a large amount of white space and padding due to specific fields that are often one of a minimal number of possibilities. We can use this fact and a few similar methods to create an encoding for 90% of Bitcoin transactions that are roughly 25-50% smaller.
+
+There exists a working-in-progress app that allows the use of steganography to encode data in images to be passed around via various social media groups. When used in conjunction with this compression scheme and an elligator squared encryption, this would allow for a very secure and private form of broadcasting bitcoin transactions.
+
+=== Rationale ===
+
+The four main methods to achieve a lower transaction size are:
+
+1. Packing transaction metadata before it and each of its inputs and outputs to determine the following data structure.
+
+2. Replacing 32-bit numeric values with either variable-length integers (VarInts) or compact integers (CompactSizes).
+
+3. Using compressed signatures and public key recovery upon decompression.
+
+4. Replacing the 36-byte Outpoint txid/vout pair with a block height and index.
+
+
+=== Backwards Compatibility ===
+
+There are no concerns with backwards compatibility.
+
+=== Specification ===
+
+==== Primitives ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| CompactSize || 1-5 Bytes || For 0-253, encode the value directly in one byte. For 254-65535, encode 254 followed by two little-endian bytes. For 65536-(2^32-1), encode 255 followed by four little-endian bytes.
+|-
+| CompactSize Flag || 2 Bits || 1, 2, or 3 indicate literal values. 0 indicates that a CompactSize encoding of the value will follow.
+|-
+| VarInt || 1+ Bytes || 7-bit little-endian encoding, with each 7-bit word encoded in a byte. The highest bit of each byte is one if more bytes follow, and 0 for the last byte.
+|-
+| VLP-Bytestream || 2+ Bytes || A VarInt Length Prefixed Bytestream. It uses the prefixed VarInt to determine the length of the following byte stream.
+|}
+
+==== General Schema ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Transaction metadata || 1 Bytes || Information on the structure of the transaction. See [[#transaction-metadata|Transaction Metadata]]
+|-
+| Version || 0-5 Bytes || If present according to the metadata field, a CompactSize encoding of the transaction version.
+|-
+| Input Count || 0-5 Bytes || If present according to the metadata field, a CompactSize encoding of the transaction input count.
+|-
+| Output Count || 0-5 Bytes || If present according to the metadata field, a CompactSize encoding of the transaction output count.
+|-
+| LockTime || 0-5 Bytes || If present according to the metadata field, a CompactSize encoding of the transaction LockTime.
+|-
+| Minimum Blockheight || 1-5 Bytes || If present according to the metadata field, a VarInt encoding of the minimum block height for transaction compressed inputs and LockTime.
+|-
+| Input Metadata+Output Metadata || 1+ Bytes || An encoding containing the metadata for all the inputs followed by all the outputs of the transaction. For each input, see [[#input-metadata|Input Metadata]], and for each output, see [[#output-metadata|Output Metadata]].
+|-
+| Input Data || 66+ Bytes || See [[#input-data|Input Data]].
+|-
+| Output Data || 3+ Bytes || See [[#output-data|Output Data]].
+|}
+
+
+==== Transaction Metadata ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Version || 2 Bits || A CompactSize flag for the transaction version.
+|-
+| Input Count || 2 Bits || A CompactSize flag for the transaction input count.
+|-
+| Output Count || 2 Bits || A CompactSize flag for the transaction output count.
+|-
+| LockTime || 1 Bit || A boolean to indicate if the transaction has a LockTime.
+|-
+| Minimum Blockheight || 1 Bit || A boolean to indicate if the transaction minimum block height is greater than zero.
+|}
+
+
+==== Input Metadata ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Compressed Signature || 1 Bit || A Boolean do determine if this input's signature is compressed. The signature is only compressed for P2TR on a key spend and for P2SH when it is a wrapped P2SH-WPKH.
+|-
+| Standard Hash || 1 Bit || A Boolean to determine if this input's signature hash type is standard (0x00 for Taproot, 0x01 for Legacy/Segwit).
+|-
+| Standard Sequence || 2 Bits || A CompactSize flag for this input's sequence. Encode literal values as follows: 1 = 0x00000000, 2 = 0xFFFFFFFE, 3 = 0xFFFFFFFF.
+|-
+| Compressed OutPoint || 1 bit || A Boolean to determine if the input's outpoint is compressed.
+|}
+
+
+==== Output Metadata ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Encoded Script Type || 3 Bits || [[#script-type-encoding|Encoded Script Type]].
+|}
+
+
+==== Script Type Encoding ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Script Type !! Value
+|-
+| Uncompressed Custom Script || 0b000
+|-
+| Uncompressed P2PK || 0b001
+|-
+| Compressed P2PK || 0b010
+|-
+| P2PKH || 0b011
+|-
+| P2SH || 0b100
+|-
+| P2WPKH || 0b101
+|-
+| P2WSH || 0b110
+|-
+| P2TR || 0b111
+|}
+
+
+==== Input Data ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Outpoint || 2-37 Bytes || The Outpoint Txid/Vout are determined to be compressed or otherwise by the "Compressed Outpoint" Boolean in the input metadata. For each compressed outpoint see [[#compressed-outpoint|Compressed Outpoint]]. For each uncompressed signature see [[#uncompressed-outpoint|Uncompressed Outpoint]].
+|-
+| Signature || 64+ Bytes || The Signature is determined to be compressed or otherwise by the output script of the previous transaction. For each compressed signature see [[#compressed-signature|Compressed Signature]]. For each uncompressed signature see [[#uncompressed-signature|Uncompressed Signature]].
+|-
+| Sequence || 0-5 Bytes || If present due to a non-standard sequence, a VarInt encoding of the sequence.
+|}
+
+
+==== Compressed Outpoint ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Txid Block Height || 1-5 Bytes || A VarInt containing the offset from Minimum Blockheight for this Txid.
+|-
+| Txid Block Index || 1-5 Bytes || A VarInt containing the flattened index from the Txid block height for the Vout.
+|}
+
+
+==== Uncompressed Outpoint ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Txid || 32 Bytes || Contains the 32 Byte Txid.
+|-
+| Vout || 1-5 Bytes || A CompactSize Containing the Vout of the Txid.
+|}
+
+
+
+==== Compressed Signature ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Signature || 64 Bytes || Contains the 64 Byte signature.
+|-
+| Pubkey Hash || 0-20 Bytes || If input is P2SH-P2WPKH contains the 20 byte hash of the public key.
+|-
+| Hash Type || 0-1 Bytes || An Optional Byte containing the Hash Type if it was non-standard.
+|}
+
+
+==== Uncompressed Signature ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Signature || 2+ Bytes || A VLP-Bytestream containing the signature.
+|}
+
+
+==== Output Data ====
+
+{| class="wikitable" style="margin:auto"
+|-
+! Name !! Width !! Description
+|-
+| Output Script || 2+ Bytes || A VLP-Bytestream containing the output script.
+|-
+| Amount || 1-9 Bytes || A VarInt containing the output amount.
+|}
+
+==== Ideal Transaction ====
+
+The compression scheme was designed to be optimal for a "typical" transaction, spending a few close-in-age inputs and having one or two outputs. Here are size
+values for such a transaction, which demonstrate the effectiveness of the compression.
+
+{| class="wikitable" style="margin:auto"
+|-
+! Field !! Requirements !! Savings Up To
+|-
+| Version || Less than four || 30 Bits
+|-
+| Input Count || Less than four || 30 Bits
+|-
+| Output Count || Less than four || 30 Bits
+|-
+| LockTime || 0 || 30 Bits
+|-
+| Input Sequence || 0x00, 0xFFFFFFFE, or 0xFFFFFFFF || 62 Bits For Each Input
+|-
+| Input Txid || Compressed Outpoint || 23 - 31 Bytes For Each Input
+|-
+| Input Vout || Compressed Outpoint || (-1) - 3 Bytes For Each Input
+|-
+| Input Signature || Non-custom Script Signing || 40 - 72 Bytes For Each Legacy Input
+|-
+| Input Hash Type || 0x00 for Taproot, 0x01 for Legacy || 7 Bits For Each Input
+|-
+| Output Script || Non-custom Scripts || 2 - 5 Bytes For Each Output
+|-
+| Output Amount || No Restrictions || (-1) - 7 Bytes For Each Output
+|}
+
+=== Reference Implementation ===
+
+This reference implementation adds two new RPC endpoints, compressrawtransaction and decompressrawtransaction. The first accepts a raw hex-encoded transaction and returns a compact hex-encoded transaction; also included in the output is a list of warnings to help ensure there are no unexpected uncompressed values. The second accepts a compact hex transaction and returns the uncompressed raw hex-encoded transaction.
+
+https://github.com/bitcoin/bitcoin/pull/29134
+
+=== Test Vectors ===
+
+==== Taproot ====
+
+===== Uncompressed =====
+020000000001017ad1d0cc314504ec06f1b5c786c50cf3cda30bd5be88cf08ead571b0ce7481fb0000000000fdffffff0188130000000000001600142da377ed4978fefa043a58489912f8e28e16226201408ce65b3170d3fbc68e3b6980650514dc53565f915d14351f83050ff50c8609495b7aa96271c3c99cdac1a92b1b45e77a4a870251fc1673596793adf2494565e500000000
+
+===== Compressed =====
+96b1ec7f968001b0218ce65b3170d3fbc68e3b6980650514dc53565f915d14351f83050ff50c8609495b7aa96271c3c99cdac1a92b1b45e77a4a870251fc1673596793adf2494565e58efefefe7d2da377ed4978fefa043a58489912f8e28e162262a608
+
+==== P2WPKH ====
+
+===== Uncompressed =====
+0200000000010144bcf05ab48b8789268a7ca07133241ad654c0739ac7165015b2d669eadb10ea0000000000fdffffff0188130000000000001600142da377ed4978fefa043a58489912f8e28e16226202473044022043ab639a98dfbc704f16a35bf25b8b72acb4cb928fd772285f1fcf63725caa85022001c9ff354504e7024708bce61f30370c8db13da8170cef4e8e4c4cdad0f71bfe0121030072484c24705512bfb1f7f866d95f808d81d343e552bc418113e1b9a1da0eb400000000
+
+===== Compressed =====
+96b1ec71968001932643ab639a98dfbc704f16a35bf25b8b72acb4cb928fd772285f1fcf63725caa8501c9ff354504e7024708bce61f30370c8db13da8170cef4e8e4c4cdad0f71bfe8efefefe7d2da377ed4978fefa043a58489912f8e28e162262a608
+
+==== P2SH-P2WPKH ====
+
+===== Uncompressed =====
+0200000000010192fb2e4332b43dc9a73febba67f3b7d97ba890673cb08efde2911330f77bbdfc00000000171600147a1979232206857167b401fdac1ffbf33f8204fffdffffff0188130000000000001600142da377ed4978fefa043a58489912f8e28e16226202473044022041eb682e63c25b85a5a400b11d41cf4b9c25f309090a5f3e0b69dc15426da90402205644ddc3d5179bab49cce4bf69ebfaeab1afa34331c1a0a70be2927d2836b0e8012103c483f1b1bd24dd23b3255a68d87ef9281f9d080fd707032ccb81c1cc56c5b00200000000
+
+===== Compressed =====
+96b1ec7c9e8001981641eb682e63c25b85a5a400b11d41cf4b9c25f309090a5f3e0b69dc15426da9045644ddc3d5179bab49cce4bf69ebfaeab1afa34331c1a0a70be2927d2836b0e87a1979232206857167b401fdac1ffbf33f8204ff8efefefe7d2da377ed4978fefa043a58489912f8e28e162262a608
+
+==== P2PKH ====
+
+===== Uncompressed =====
+02000000015f5be26862482fe2fcc900f06ef26ee256fb205bc4773e5a402d0c1b88b82043000000006a473044022031a20f5d9212023b510599c9d53d082f8e07faaa2d51482e078f8e398cb50d770220635abd99220ad713a081c4f20b83cb3f491ed8bd032cb151a3521ed144164d9c0121027977f1b6357cead2df0a0a19570088a1eb9115468b2dfa01439493807d8f1294fdffffff0188130000000000001600142da377ed4978fefa043a58489912f8e28e16226200000000
+
+===== Compressed =====
+96b1ec7c968001981431a20f5d9212023b510599c9d53d082f8e07faaa2d51482e078f8e398cb50d77635abd99220ad713a081c4f20b83cb3f491ed8bd032cb151a3521ed144164d9c8efefefe7d2da377ed4978fefa043a58489912f8e28e162262a608
+
+
+== Acknowledgements ==
+Thank you to Andrew Poelstra, who helped invent and develop the ideas in the proposal and the code for reference implementation.
diff --git a/bip-0338.mediawiki b/bip-0338.mediawiki
index 4e2c220519..908aef63de 100644
--- a/bip-0338.mediawiki
+++ b/bip-0338.mediawiki
@@ -5,7 +5,7 @@
Author: Suhas Daftuar
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0338
- Status: Draft
+ Status: Withdrawn
Type: Standards Track
Created: 2020-09-03
License: BSD-2-Clause
@@ -64,11 +64,14 @@ in the number of block-relay-only connections that can be made on the network.
# A new disabletx message is added, which is defined as an empty message with message type set to "disabletx".
# The protocol version of nodes implementing this BIP must be set to 70017 or higher.
# If a node sets the transaction relay field in the version message to a peer to false, then the disabletx message MAY also be sent in response to a version message from that peer if the peer's protocol version is >= 70017. If sent, the disabletx message MUST be sent prior to sending a verack.
+# A node MUST NOT send the disabletx message if the transaction relay field in the version message is omitted or set to true.
# A node that has sent or received a disabletx message to/from a peer MUST NOT send any of these messages to the peer:
## inv messages for transactions
+## notfound messages for transactions
## getdata messages for transactions
## getdata messages for merkleblock (BIP 37)
## filteradd/filterload/filterclear (BIP 37)
+## feefilter (BIP 133)
## mempool (BIP 35)
## tx message
# It is RECOMMENDED that a node that has sent or received a disabletx message to/from a peer not send any of these messages to the peer:
diff --git a/bip-0339.mediawiki b/bip-0339.mediawiki
index 806ba1cf7c..7fb6bc4eed 100644
--- a/bip-0339.mediawiki
+++ b/bip-0339.mediawiki
@@ -5,7 +5,7 @@
Author: Suhas Daftuar
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0339
- Status: Draft
+ Status: Final
Type: Standards Track
Created: 2020-02-03
License: BSD-2-Clause
diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki
index b5a47d3276..97c9fa9b9a 100644
--- a/bip-0340.mediawiki
+++ b/bip-0340.mediawiki
@@ -6,9 +6,12 @@
Tim Ruffing
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0340
- Status: Draft
+ Status: Final
Type: Standards Track
License: BSD-2-Clause
+ License-Code: BSD-2-Clause
+ MIT
+ CC0-1.0
Created: 2020-01-19
Post-History: 2018-07-06: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-July/016203.html [bitcoin-dev] Schnorr signatures BIP
@@ -58,11 +61,11 @@ encodings and operations.
# Signatures are pairs ''(e, s)'' that satisfy ''e = hash(s⋅G - e⋅P || m)''. This variant avoids minor complexity introduced by the encoding of the point ''R'' in the signature (see paragraphs "Encoding R and public key point P" and "Implicit Y coordinates" further below in this subsection). Moreover, revealing ''e'' instead of ''R'' allows for potentially shorter signatures: Whereas an encoding of ''R'' inherently needs about 32 bytes, the hash ''e'' can be tuned to be shorter than 32 bytes, and [http://www.neven.org/papers/schnorr.pdf a short hash of only 16 bytes suffices to provide SUF-CMA security at the target security level of 128 bits]. However, a major drawback of this optimization is that finding collisions in a short hash function is easy. This complicates the implementation of secure signing protocols in scenarios in which a group of mutually distrusting signers work together to produce a single joint signature (see Applications below). In these scenarios, which are not captured by the SUF-CMA model due its assumption of a single honest signer, a promising attack strategy for malicious co-signers is to find a collision in the hash function in order to obtain a valid signature on a message that an honest co-signer did not intend to sign.
# Signatures are pairs ''(R, s)'' that satisfy ''s⋅G = R + hash(R || m)⋅P''. This supports batch verification, as there are no elliptic curve operations inside the hashes. Batch verification enables significant speedups.The speedup that results from batch verification can be demonstrated with the cryptography library [https://github.com/jonasnick/secp256k1/blob/schnorrsig-batch-verify/doc/speedup-batch.md libsecp256k1].
-Since we would like to avoid the fragility that comes with short hashes, the ''e'' variant does not provide significant advantages. We choose the ''R''-option, which supports batch verification.
+Since we would like to avoid the fragility that comes with short hashes, the ''e'' variant does not provide significant advantages. We choose the ''R''-option, which supports batch verification.
'''Key prefixing''' Using the verification rule above directly makes Schnorr signatures vulnerable to "related-key attacks" in which a third party can convert a signature ''(R, s)'' for public key ''P'' into a signature ''(R, s + a⋅hash(R || m))'' for public key ''P + a⋅G'' and the same message ''m'', for any given additive tweak ''a'' to the signing key. This would render signatures insecure when keys are generated using [[bip-0032.mediawiki#public-parent-key--public-child-key|BIP32's unhardened derivation]] and other methods that rely on additive tweaks to existing keys such as Taproot.
-To protect against these attacks, we choose ''key prefixed''A limitation of committing to the public key (rather than to a short hash of it, or not at all) is that it removes the ability for public key recovery or verifying signatures against a short public key hash. These constructions are generally incompatible with batch verification. Schnorr signatures which means that the public key is prefixed to the message in the challenge hash input. This changes the equation to ''s⋅G = R + hash(R || P || m)⋅P''. [https://eprint.iacr.org/2015/1135.pdf It can be shown] that key prefixing protects against related-key attacks with additive tweaks. In general, key prefixing increases robustness in multi-user settings, e.g., it seems to be a requirement for proving the MuSig multisignature scheme secure (see Applications below).
+To protect against these attacks, we choose ''key prefixed''A limitation of committing to the public key (rather than to a short hash of it, or not at all) is that it removes the ability for public key recovery or verifying signatures against a short public key hash. These constructions are generally incompatible with batch verification. Schnorr signatures which means that the public key is prefixed to the message in the challenge hash input. This changes the equation to ''s⋅G = R + hash(R || P || m)⋅P''. [https://eprint.iacr.org/2015/1135.pdf It can be shown] that key prefixing protects against related-key attacks with additive tweaks. In general, key prefixing increases robustness in multi-user settings, e.g., it seems to be a requirement for proving multiparty signing protocols (such as MuSig, MuSig2, and FROST) secure (see Applications below).
We note that key prefixing is not strictly necessary for transaction signatures as used in Bitcoin currently, because signed transactions indirectly commit to the public keys already, i.e., ''m'' contains a commitment to ''pk''. However, this indirect commitment should not be relied upon because it may change with proposals such as SIGHASH_NOINPUT ([[bip-0118.mediawiki|BIP118]]), and would render the signature scheme unsuitable for other purposes than signing transactions, e.g., [https://bitcoin.org/en/developer-reference#signmessage signing ordinary messages].
@@ -86,7 +89,7 @@ Despite halving the size of the set of valid public keys, implicit Y coordinates
For example, without tagged hashing a BIP340 signature could also be valid for a signature scheme where the only difference is that the arguments to the hash function are reordered. Worse, if the BIP340 nonce derivation function was copied or independently created, then the nonce could be accidentally reused in the other scheme leaking the secret key.
-This proposal suggests to include the tag by prefixing the hashed data with ''SHA256(tag) || SHA256(tag)''. Because this is a 64-byte long context-specific constant and the ''SHA256'' block size is also 64 bytes, optimized implementations are possible (identical to SHA256 itself, but with a modified initial state). Using SHA256 of the tag name itself is reasonably simple and efficient for implementations that don't choose to use the optimization.
+This proposal suggests to include the tag by prefixing the hashed data with ''SHA256(tag) || SHA256(tag)''. Because this is a 64-byte long context-specific constant and the ''SHA256'' block size is also 64 bytes, optimized implementations are possible (identical to SHA256 itself, but with a modified initial state). Using SHA256 of the tag name itself is reasonably simple and efficient for implementations that don't choose to use the optimization. In general, tags can be arbitrary byte arrays, but are suggested to be textual descriptions in UTF-8 encoding.
'''Final scheme''' As a result, our final scheme ends up using public key ''pk'' which is the X coordinate of a point ''P'' on the curve whose Y coordinate is even and signatures ''(r,s)'' where ''r'' is the X coordinate of a point ''R'' whose Y coordinate is even. The signature satisfies ''s⋅G = R + tagged_hash(r || pk || m)⋅P''.
@@ -109,13 +112,14 @@ The following conventions are used, with constants as defined for [https://www.s
** The function ''bytes(P)'', where ''P'' is a point, returns ''bytes(x(P))''.
** The function ''int(x)'', where ''x'' is a 32-byte array, returns the 256-bit unsigned integer whose most significant byte first encoding is ''x''.
** The function ''has_even_y(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''y(P) mod 2 = 0''.
-** The function ''lift_x(x)'', where ''x'' is an integer in range ''0..p-1'', returns the point ''P'' for which ''x(P) = x''
- Given a candidate X coordinate ''x'' in the range ''0..p-1'', there exist either exactly two or exactly zero valid Y coordinates. If no valid Y coordinate exists, then ''x'' is not a valid X coordinate either, i.e., no point ''P'' exists for which ''x(P) = x''. The valid Y coordinates for a given candidate ''x'' are the square roots of ''c = x3 + 7 mod p'' and they can be computed as ''y = ±c(p+1)/4 mod p'' (see [https://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus Quadratic residue]) if they exist, which can be checked by squaring and comparing with ''c''. and ''has_even_y(P)'', or fails if no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode:
+** The function ''lift_x(x)'', where ''x'' is a 256-bit unsigned integer, returns the point ''P'' for which ''x(P) = x''
+ Given a candidate X coordinate ''x'' in the range ''0..p-1'', there exist either exactly two or exactly zero valid Y coordinates. If no valid Y coordinate exists, then ''x'' is not a valid X coordinate either, i.e., no point ''P'' exists for which ''x(P) = x''. The valid Y coordinates for a given candidate ''x'' are the square roots of ''c = x3 + 7 mod p'' and they can be computed as ''y = ±c(p+1)/4 mod p'' (see [https://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus Quadratic residue]) if they exist, which can be checked by squaring and comparing with ''c''. and ''has_even_y(P)'', or fails if ''x'' is greater than ''p-1'' or no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode:
+*** Fail if ''x ≥ p''.
*** Let ''c = x3 + 7 mod p''.
*** Let ''y = c(p+1)/4 mod p''.
*** Fail if ''c ≠ y2 mod p''.
*** Return the unique point ''P'' such that ''x(P) = x'' and ''y(P) = y'' if ''y mod 2 = 0'' or ''y(P) = p-y'' otherwise.
-** The function ''hashtag(x)'' where ''tag'' is a UTF-8 encoded tag name and ''x'' is a byte array returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)''.
+** The function ''hashname(x)'' where ''x'' is a byte array returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)'', where ''tag'' is the UTF-8 encoding of ''name''.
==== Public Key Generation ====
@@ -137,7 +141,7 @@ As an alternative to generating keys randomly, it is also possible and safe to r
Input:
* The secret key ''sk'': a 32-byte array
-* The message ''m'': a 32-byte array
+* The message ''m'': a byte array
* Auxiliary random data ''a'': a 32-byte array
The algorithm ''Sign(sk, m)'' is defined as:
@@ -160,20 +164,20 @@ The auxiliary random data should be set to fresh randomness generated at signing
==== Alternative Signing ====
-It should be noted that various alternative signing algorithms can be used to produce equally valid signatures. The 32-byte ''rand'' value may be generated in other ways, producing a different but still valid signature (in other words, this is not a ''unique'' signature scheme). '''No matter which method is used to generate the ''rand'' value, the value must be a fresh uniformly random 32-byte string which is not even partially predictable for the attacker.''' For nonces without randomness this implies that the same inputs must not be presented in another context. This can be most reliably accomplished by not reusing the same private key across different signing schemes. For example, if the ''rand'' value was computed as per RFC6979 and the same secret key is used in deterministic ECDSA with RFC6979, the signatures can leak the secret key through nonce reuse.
+It should be noted that various alternative signing algorithms can be used to produce equally valid signatures. The 32-byte ''rand'' value may be generated in other ways, producing a different but still valid signature (in other words, this is not a ''unique'' signature scheme). '''No matter which method is used to generate the ''rand'' value, the value must be a fresh uniformly random 32-byte string which is not even partially predictable for the attacker.''' For nonces without randomness, this implies that the same inputs must not be presented in another context. This can be most reliably accomplished by not reusing the same private key across different signing schemes. For example, if the ''rand'' value was computed as per RFC6979 and the same secret key is used in deterministic ECDSA with RFC6979, the signatures can leak the secret key through nonce reuse.
-'''Nonce exfiltration protection''' It is possible to strengthen the nonce generation algorithm using a second device. In this case, the second device contributes randomness which the actual signer provably incorporates into its nonce. This prevents certain attacks where the signer device is compromised and intentionally tries to leak the secret key through its nonce selection.
+'''Nonce exfiltration protection''' It is possible to strengthen the nonce generation algorithm using a second device. In this case, the second device contributes randomness which the actual signer provably incorporates into its nonce. This prevents certain attacks where the signer's device is compromised and intentionally tries to leak the secret key through its nonce selection.
-'''Multisignatures''' This signature scheme is compatible with various types of multisignature and threshold schemes such as [https://eprint.iacr.org/2018/068 MuSig], where a single public key requires holders of multiple secret keys to participate in signing (see Applications below).
+'''Multisignatures''' This signature scheme is compatible with various types of multisignature and threshold schemes such as [https://eprint.iacr.org/2020/1261.pdf MuSig2], where a single public key requires holders of multiple secret keys to participate in signing (see Applications below).
'''It is important to note that multisignature signing schemes in general are insecure with the ''rand'' generation from the default signing algorithm above (or any other deterministic method).'''
-'''Precomputed public key data''' For many uses the compressed 33-byte encoding of the public key corresponding to the secret key may already be known, making it easy to evaluate ''has_even_y(P)'' and ''bytes(P)''. As such, having signers supply this directly may be more efficient than recalculating the public key from the secret key. However, if this optimization is used and additionally the signature verification at the end of the signing algorithm is dropped for increased efficiency, signers must ensure the public key is correctly calculated and not taken from untrusted sources.
+'''Precomputed public key data''' For many uses, the compressed 33-byte encoding of the public key corresponding to the secret key may already be known, making it easy to evaluate ''has_even_y(P)'' and ''bytes(P)''. As such, having signers supply this directly may be more efficient than recalculating the public key from the secret key. However, if this optimization is used and additionally the signature verification at the end of the signing algorithm is dropped for increased efficiency, signers must ensure the public key is correctly calculated and not taken from untrusted sources.
==== Verification ====
Input:
* The public key ''pk'': a 32-byte array
-* The message ''m'': a 32-byte array
+* The message ''m'': a byte array
* A signature ''sig'': a 64-byte array
The algorithm ''Verify(pk, m, sig)'' is defined as:
@@ -196,7 +200,7 @@ Note that the correctness of verification relies on the fact that ''lift_x'' alw
Input:
* The number ''u'' of signatures
* The public keys ''pk1..u'': ''u'' 32-byte arrays
-* The messages ''m1..u'': ''u'' 32-byte arrays
+* The messages ''m1..u'': ''u'' byte arrays
* The signatures ''sig1..u'': ''u'' 64-byte arrays
The algorithm ''BatchVerify(pk1..u, m1..u, sig1..u)'' is defined as:
@@ -212,6 +216,50 @@ The algorithm ''BatchVerify(pk1..u, m1..u, sig1..uIn theory, the message size is restricted due to the fact that SHA256 accepts byte strings only up to size of 2^61-1 bytes.
+It is understood that implementations may reject messages which are too large in their environment or application context,
+e.g., messages which exceed predefined buffers or would otherwise cause resource exhaustion.
+
+Earlier revisions of this BIP required messages to be exactly 32 bytes.
+This restriction puts a burden on callers
+who typically need to perform pre-hashing of the actual input message by feeding it through SHA256 (or another collision-resistant cryptographic hash function)
+to create a 32-byte digest which can be passed to signing or verification
+(as for example done in [[bip-0341.mediawiki|BIP341]].)
+
+Since pre-hashing may not always be desirable,
+e.g., when actual messages are shorter than 32 bytes,Another reason to omit pre-hashing is to protect against certain types of cryptanalytic advances against the hash function used for pre-hashing: If pre-hashing is used, an attacker that can find collisions in the pre-hashing function can necessarily forge signatures under chosen-message attacks. If pre-hashing is not used, an attacker that can find collisions in SHA256 (as used inside the signature scheme) may not be able to forge signatures. However, this seeming advantage is mostly irrelevant in the context of Bitcoin, which already relies on collision resistance of SHA256 in other places, e.g., for transaction hashes.
+the restriction to 32-byte messages has been lifted.
+We note that pre-hashing is recommended for performance reasons in applications that deal with large messages.
+If large messages are not pre-hashed,
+the algorithms of the signature scheme will perform more hashing internally.
+In particular, the signing algorithm needs two sequential hashing passes over the message,
+which means that the full message must necessarily be kept in memory during signing,
+and large messages entail a runtime penalty.Typically, messages of 56 bytes or longer enjoy a performance benefit from pre-hashing, assuming the speed of SHA256 inside the signing algorithm matches that of the pre-hashing done by the calling application.
+
+==== Domain Separation ====
+
+It is good cryptographic practice to use a key pair only for a single purpose.
+Nevertheless, there may be situations in which it may be desirable to use the same key pair in multiple contexts,
+i.e., to sign different types of messages within the same application
+or even messages in entirely different applications
+(e.g., a secret key may be used to sign Bitcoin transactions as well plain text messages).
+
+As a consequence, applications should ensure that a signed application message intended for one context is never deemed valid in a different context
+(e.g., a signed plain text message should never be misinterpreted as a signed Bitcoin transaction, because this could cause unintended loss of funds).
+This is called "domain separation" and it is typically realized by partitioning the message space.
+Even if key pairs are intended to be used only within a single context,
+domain separation is a good idea because it makes it easy to add more contexts later.
+
+As a best practice, we recommend applications to use exactly one of the following methods to pre-process application messages before passing it to the signature scheme:
+* Either, pre-hash the application message using ''hashname'', where ''name'' identifies the context uniquely (e.g., "foo-app/signed-bar"),
+* or prefix the actual message with a 33-byte string that identifies the context uniquely (e.g., the UTF-8 encoding of "foo-app/signed-bar", padded with null bytes to 33 bytes).
+
+As the two pre-processing methods yield different message sizes (32 bytes vs. at least 33 bytes), there is no risk of collision between them.
+
== Applications ==
There are several interesting applications beyond simple signatures.
@@ -219,9 +267,9 @@ While recent academic papers claim that they are also possible with ECDSA, conse
=== Multisignatures and Threshold Signatures ===
-By means of an interactive scheme such as [https://eprint.iacr.org/2018/068 MuSig], participants can aggregate their public keys into a single public key which they can jointly sign for. This allows ''n''-of-''n'' multisignatures which, from a verifier's perspective, are no different from ordinary signatures, giving improved privacy and efficiency versus ''CHECKMULTISIG'' or other means.
+By means of an interactive scheme such as [https://eprint.iacr.org/2020/1261.pdf MuSig2] ([[bip-0327.mediawiki|BIP327]]), participants can aggregate their public keys into a single public key which they can jointly sign for. This allows ''n''-of-''n'' multisignatures which, from a verifier's perspective, are no different from ordinary signatures, giving improved privacy and efficiency versus ''CHECKMULTISIG'' or other means.
-Moreover, Schnorr signatures are compatible with [https://web.archive.org/web/20031003232851/http://www.research.ibm.com/security/dkg.ps distributed key generation], which enables interactive threshold signatures schemes, e.g., the schemes described by [http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps Stinson and Strobl (2001)] or [https://web.archive.org/web/20060911151529/http://theory.lcs.mit.edu/~stasio/Papers/gjkr03.pdf Gennaro, Jarecki and Krawczyk (2003)]. These protocols make it possible to realize ''k''-of-''n'' threshold signatures, which ensure that any subset of size ''k'' of the set of ''n'' signers can sign but no subset of size less than ''k'' can produce a valid Schnorr signature. However, the practicality of the existing schemes is limited: most schemes in the literature have been proven secure only for the case ''k-1 < n/2'', are not secure when used concurrently in multiple sessions, or require a reliable broadcast mechanism to be secure. Further research is necessary to improve this situation.
+Moreover, Schnorr signatures are compatible with [https://en.wikipedia.org/wiki/Distributed_key_generation distributed key generation], which enables interactive threshold signatures schemes, e.g., the schemes by [http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps Stinson and Strobl (2001)], by [https://link.springer.com/content/pdf/10.1007/s00145-006-0347-3.pdf Gennaro, Jarecki, Krawczyk, and Rabin (2007)], or the [https://eprint.iacr.org/2020/852.pdf FROST] scheme including its variants such as [https://eprint.iacr.org/2023/899.pdf FROST3]. These protocols make it possible to realize ''k''-of-''n'' threshold signatures, which ensure that any subset of size ''k'' of the set of ''n'' signers can sign but no subset of size less than ''k'' can produce a valid Schnorr signature.
=== Adaptor Signatures ===
@@ -233,15 +281,27 @@ Adaptor signatures, beyond the efficiency and privacy benefits of encoding scrip
=== Blind Signatures ===
-A blind signature protocol is an interactive protocol that enables a signer to sign a message at the behest of another party without learning any information about the signed message or the signature. Schnorr signatures admit a very [https://www.math.uni-frankfurt.de/~dmst/research/papers/schnorr.blind_sigs_attack.2001.pdf simple blind signature scheme] which is however insecure because it's vulnerable to [https://www.iacr.org/archive/crypto2002/24420288/24420288.pdf Wagner's attack]. A known mitigation is to let the signer abort a signing session with a certain probability, and the resulting scheme can be [https://eprint.iacr.org/2019/877 proven secure under non-standard cryptographic assumptions].
+A blind signature protocol is an interactive protocol that enables a signer to sign a message at the behest of another party without learning any information about the signed message or the signature. Schnorr signatures admit a very [http://publikationen.ub.uni-frankfurt.de/files/4292/schnorr.blind_sigs_attack.2001.pdf simple blind signature scheme] which is however insecure because it's vulnerable to [https://www.iacr.org/archive/crypto2002/24420288/24420288.pdf Wagner's attack]. Known mitigations are to let the signer abort a signing session with a certain probability, which can be [https://eprint.iacr.org/2019/877 proven secure under non-standard cryptographic assumptions], or [https://eprint.iacr.org/2022/1676.pdf to use zero-knowledge proofs].
Blind Schnorr signatures could for example be used in [https://github.com/ElementsProject/scriptless-scripts/blob/master/md/partially-blind-swap.md Partially Blind Atomic Swaps], a construction to enable transferring of coins, mediated by an untrusted escrow agent, without connecting the transactors in the public blockchain transaction graph.
== Test Vectors and Reference Code ==
-For development and testing purposes, we provide a [[bip-0340/test-vectors.csv|collection of test vectors in CSV format]] and a naive, highly inefficient, and non-constant time [[bip-0340/reference.py|pure Python 3.7 reference implementation of the signing and verification algorithm]].
+For development and testing purposes, we provide a [[bip-0340/test-vectors.csv|collection of test vectors in CSV format]],
+a naive, highly inefficient, and non-constant time [[bip-0340/reference.py|pure Python 3.7 reference implementation of the signing and verification algorithm]]
+as well as the [[bip-0340/test-vectors.py|script used to generate the test vectors]]
+under the BSD-2-Clause License, or the MIT License, or CC0 1.0, at your choice.
The reference implementation is for demonstration purposes only and not to be used in production environments.
+== Changelog ==
+
+To help implementers understand updates to this BIP, we keep a list of substantial changes.
+
+* 2022-08: Fix function signature of lift_x in reference code
+* 2023-04: Allow messages of arbitrary size
+* 2024-05: Update "Applications" section with more recent references
+* 2025-04: Change license of test vectors and code
+
== Footnotes ==
diff --git a/bip-0340/LICENSE b/bip-0340/LICENSE
new file mode 100644
index 0000000000..6ad8fcfb47
--- /dev/null
+++ b/bip-0340/LICENSE
@@ -0,0 +1,11 @@
+BSD-2-Clause OR MIT OR CC0-1.0
+
+The contents of this directory are provided under one of the following sets of
+terms, at your choice:
+
+ - The BSD-2-Clause License
+ https://opensource.org/license/BSD-2-Clause
+ - The MIT License
+ https://opensource.org/license/MIT
+ - CC0 1.0
+ https://creativecommons.org/publicdomain/zero/1.0/
diff --git a/bip-0340/reference.py b/bip-0340/reference.py
index 5b38c0a68e..b327e0a228 100644
--- a/bip-0340/reference.py
+++ b/bip-0340/reference.py
@@ -68,8 +68,7 @@ def bytes_from_point(P: Point) -> bytes:
def xor_bytes(b0: bytes, b1: bytes) -> bytes:
return bytes(x ^ y for (x, y) in zip(b0, b1))
-def lift_x(b: bytes) -> Optional[Point]:
- x = int_from_bytes(b)
+def lift_x(x: int) -> Optional[Point]:
if x >= p:
return None
y_sq = (pow(x, 3, p) + 7) % p
@@ -97,8 +96,6 @@ def pubkey_gen(seckey: bytes) -> bytes:
return bytes_from_point(P)
def schnorr_sign(msg: bytes, seckey: bytes, aux_rand: bytes) -> bytes:
- if len(msg) != 32:
- raise ValueError('The message must be a 32-byte array.')
d0 = int_from_bytes(seckey)
if not (1 <= d0 <= n - 1):
raise ValueError('The secret key must be an integer in the range 1..n-1.')
@@ -122,13 +119,11 @@ def schnorr_sign(msg: bytes, seckey: bytes, aux_rand: bytes) -> bytes:
return sig
def schnorr_verify(msg: bytes, pubkey: bytes, sig: bytes) -> bool:
- if len(msg) != 32:
- raise ValueError('The message must be a 32-byte array.')
if len(pubkey) != 32:
raise ValueError('The public key must be a 32-byte array.')
if len(sig) != 64:
raise ValueError('The signature must be a 64-byte array.')
- P = lift_x(pubkey)
+ P = lift_x(int_from_bytes(pubkey))
r = int_from_bytes(sig[0:32])
s = int_from_bytes(sig[32:64])
if (P is None) or (r >= p) or (s >= n):
diff --git a/bip-0340/test-vectors.csv b/bip-0340/test-vectors.csv
index a1a63e1283..672339129a 100644
--- a/bip-0340/test-vectors.csv
+++ b/bip-0340/test-vectors.csv
@@ -14,3 +14,7 @@ index,secret key,public key,aux_rand,message,signature,verification result,comme
12,,DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B,FALSE,sig[0:32] is equal to field size
13,,DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141,FALSE,sig[32:64] is equal to curve order
14,,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30,,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E17776969E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B,FALSE,public key is not a valid X coordinate because it exceeds the field size
+15,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,,71535DB165ECD9FBBC046E5FFAEA61186BB6AD436732FCCC25291A55895464CF6069CE26BF03466228F19A3A62DB8A649F2D560FAC652827D1AF0574E427AB63,TRUE,message of size 0 (added 2022-12)
+16,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,11,08A20A0AFEF64124649232E0693C583AB1B9934AE63B4C3511F3AE1134C6A303EA3173BFEA6683BD101FA5AA5DBC1996FE7CACFC5A577D33EC14564CEC2BACBF,TRUE,message of size 1 (added 2022-12)
+17,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,0102030405060708090A0B0C0D0E0F1011,5130F39A4059B43BC7CAC09A19ECE52B5D8699D1A71E3C52DA9AFDB6B50AC370C4A482B77BF960F8681540E25B6771ECE1E5A37FD80E5A51897C5566A97EA5A5,TRUE,message of size 17 (added 2022-12)
+18,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999,403B12B0D8555A344175EA7EC746566303321E5DBFA8BE6F091635163ECA79A8585ED3E3170807E7C03B720FC54C7B23897FCBA0E9D0B4A06894CFD249F22367,TRUE,message of size 100 (added 2022-12)
diff --git a/bip-0340/test-vectors.py b/bip-0340/test-vectors.py
index d1bf6b28bc..8442a713fb 100644
--- a/bip-0340/test-vectors.py
+++ b/bip-0340/test-vectors.py
@@ -24,17 +24,17 @@ def vector0():
assert(y(P) % 2 == 0)
# For historical reasons (pubkey tiebreaker was squareness and not evenness)
- # we should have at least one test vector where the the point reconstructed
+ # we should have at least one test vector where the point reconstructed
# from the public key has a square and one where it has a non-square Y
# coordinate. In this one Y is non-square.
- pubkey_point = lift_x(pubkey)
+ pubkey_point = lift_x(int_from_bytes(pubkey))
assert(not has_square_y(pubkey_point))
# For historical reasons (R tiebreaker was squareness and not evenness)
- # we should have at least one test vector where the the point reconstructed
+ # we should have at least one test vector where the point reconstructed
# from the R.x coordinate has a square and one where it has a non-square Y
# coordinate. In this one Y is non-square.
- R = lift_x(sig[0:32])
+ R = lift_x(int_from_bytes(sig[0:32]))
assert(not has_square_y(R))
return (seckey, pubkey, aux_rand, msg, sig, "TRUE", None)
@@ -47,7 +47,7 @@ def vector1():
sig = schnorr_sign(msg, seckey, aux_rand)
# The point reconstructed from the R.x coordinate has a square Y coordinate.
- R = lift_x(sig[0:32])
+ R = lift_x(int_from_bytes(sig[0:32]))
assert(has_square_y(R))
return (seckey, pubkey_gen(seckey), aux_rand, msg, sig, "TRUE", None)
@@ -60,12 +60,12 @@ def vector2():
# The point reconstructed from the public key has a square Y coordinate.
pubkey = pubkey_gen(seckey)
- pubkey_point = lift_x(pubkey)
+ pubkey_point = lift_x(int_from_bytes(pubkey))
assert(has_square_y(pubkey_point))
# This signature vector would not verify if the implementer checked the
# evenness of the X coordinate of R instead of the Y coordinate.
- R = lift_x(sig[0:32])
+ R = lift_x(int_from_bytes(sig[0:32]))
assert(R[0] % 2 == 1)
return (seckey, pubkey, aux_rand, msg, sig, "TRUE", None)
@@ -99,7 +99,7 @@ def insecure_schnorr_sign_fixed_nonce(msg, seckey0, k):
e = int_from_bytes(tagged_hash("BIP0340/challenge", bytes_from_point(R) + bytes_from_point(P) + msg)) % n
return bytes_from_point(R) + bytes_from_int((k + e * seckey) % n)
-# Creates a singature with a small x(R) by using k = -1/2
+# Creates a signature with a small x(R) by using k = -1/2
def vector4():
one_half = n - 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0
seckey = bytes_from_int(0x763758E5CBEEDEE4F7D3FC86F531C36578933228998226672F13C4F0EBE855EB)
@@ -119,8 +119,9 @@ def vector5():
msg = default_msg
sig = schnorr_sign(msg, seckey, default_aux_rand)
- pubkey = bytes_from_int(0xEEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34)
- assert(lift_x(pubkey) is None)
+ pubkey_int = 0xEEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34
+ pubkey = bytes_from_int(pubkey_int)
+ assert(lift_x(pubkey_int) is None)
return (None, pubkey, None, msg, sig, "FALSE", "public key not on the curve")
@@ -197,9 +198,9 @@ def vector11():
sig = schnorr_sign(msg, seckey, default_aux_rand)
# Replace R's X coordinate with an X coordinate that's not on the curve
- x_not_on_curve = bytes_from_int(0x4A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D)
+ x_not_on_curve = 0x4A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D
assert(lift_x(x_not_on_curve) is None)
- sig = x_not_on_curve + sig[32:64]
+ sig = bytes_from_int(x_not_on_curve) + sig[32:64]
return (None, pubkey_gen(seckey), None, msg, sig, "FALSE", "sig[0:32] is not an X coordinate on the curve")
@@ -242,13 +243,27 @@ def vector14():
sig = schnorr_sign(msg, seckey, default_aux_rand)
pubkey_int = p + 1
pubkey = bytes_from_int(pubkey_int)
- assert(lift_x(pubkey) is None)
+ assert(lift_x(pubkey_int) is None)
# If an implementation would reduce a given public key modulo p then the
# pubkey would be valid
- assert(lift_x(bytes_from_int(pubkey_int % p)) is not None)
+ assert(lift_x(pubkey_int % p) is not None)
return (None, pubkey, None, msg, sig, "FALSE", "public key is not a valid X coordinate because it exceeds the field size")
+def varlen_vector(msg_int):
+ seckey = bytes_from_int(int(16 * "0340", 16))
+ pubkey = pubkey_gen(seckey)
+ aux_rand = bytes_from_int(0)
+ msg = msg_int.to_bytes((msg_int.bit_length() + 7) // 8, "big")
+ sig = schnorr_sign(msg, seckey, aux_rand)
+ comment = "message of size %d (added 2022-12)"
+ return (seckey, pubkey, aux_rand, msg, sig, "TRUE", comment % len(msg))
+
+vector15 = lambda : varlen_vector(0)
+vector16 = lambda : varlen_vector(0x11)
+vector17 = lambda : varlen_vector(0x0102030405060708090A0B0C0D0E0F1011)
+vector18 = lambda : varlen_vector(int(100 * "99", 16))
+
vectors = [
vector0(),
vector1(),
@@ -264,7 +279,11 @@ def vector14():
vector11(),
vector12(),
vector13(),
- vector14()
+ vector14(),
+ vector15(),
+ vector16(),
+ vector17(),
+ vector18(),
]
# Converts the byte strings of a test vector into hex strings
diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki
index 5e47bfc4f7..a367d36ed1 100644
--- a/bip-0341.mediawiki
+++ b/bip-0341.mediawiki
@@ -7,7 +7,7 @@
Anthony Towns
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0341
- Status: Draft
+ Status: Final
Type: Standards Track
Created: 2020-01-19
License: BSD-3-Clause
@@ -41,7 +41,7 @@ As a result we choose this combination of technologies:
* '''Taproot''' on top of that lets us merge the traditionally separate pay-to-pubkey and pay-to-scripthash policies, making all outputs spendable by either a key or (optionally) a script, and indistinguishable from each other. As long as the key-based spending path is used for spending, it is not revealed whether a script path was permitted as well, resulting in space savings and an increase in scripting privacy at spending time.
* Taproot's advantages become apparent under the assumption that most applications involve outputs that could be spent by all parties agreeing. That's where '''Schnorr''' signatures come in, as they permit [https://eprint.iacr.org/2018/068 key aggregation]: a public key can be constructed from multiple participant public keys, and which requires cooperation between all participants to sign for. Such multi-party public keys and signatures are indistinguishable from their single-party equivalents. This means that with taproot most applications can use the key-based spending path, which is both efficient and private. This can be generalized to arbitrary M-of-N policies, as Schnorr signatures support threshold signing, at the cost of more complex setup protocols.
* As Schnorr signatures also permit '''batch validation''', allowing multiple signatures to be validated together more efficiently than validating each one independently, we make sure all parts of the design are compatible with this.
-* Where unused bits appear as a result of the above changes, they are reserved for mechanisms for '''future extensions'''. As a result, every script in the Merkle tree has an associated version such that new script versions can be introduced with a soft fork while remaining compatible with BIP 341. Additionally, future soft forks can make use of the currently unused annex in the witness (see [[bip-0341.mediawiki#Rationale|BIP341]]).
+* Where unused bits appear as a result of the above changes, they are reserved for mechanisms for '''future extensions'''. As a result, every script in the Merkle tree has an associated version such that new script versions can be introduced with a soft fork while remaining compatible with BIP 341. Additionally, future soft forks can make use of the currently unused annex in the witness (see [[bip-0341.mediawiki#rationale|Rationale]]).
* While the core semantics of the '''signature hashing algorithm''' are not changed, a number of improvements are included in this proposal. The new signature hashing algorithm fixes the verification capabilities of offline signing devices by including amount and scriptPubKey in the signature message, avoids unnecessary hashing, uses '''tagged hashes''' and defines a default sighash byte.
* The '''public key is directly included in the output''' in contrast to typical earlier constructions which store a hash of the public key or script in the output. This has the same cost for senders and is more space efficient overall if the key-based spending path is taken. '''Why is the public key directly included in the output?''' While typical earlier constructions store a hash of a script or a public key in the output, this is rather wasteful when a public key is always involved. To guarantee batch verifiability, the public key must be known to every verifier, and thus only revealing its hash as an output would imply adding an additional 32 bytes to the witness. Furthermore, to maintain [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-January/012198.html 128-bit collision security] for outputs, a 256-bit hash would be required anyway, which is comparable in size (and thus in cost for senders) to revealing the public key directly. While the usage of public key hashes is often said to protect against ECDLP breaks or quantum computers, this protection is very weak at best: transactions are not protected while being confirmed, and a very [https://twitter.com/pwuille/status/1108097835365339136 large portion] of the currency's supply is not under such protection regardless. Actual resistance to such systems can be introduced by relying on different cryptographic assumptions, but this proposal focuses on improvements that do not change the security model.
@@ -78,7 +78,7 @@ The following rules only apply when such an output is being spent. Any other out
** If ''t ≥ 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141'' (order of secp256k1), fail.
** Let ''Q = P + int(t)G''.
** If ''q ≠ x(Q)'' or ''c[0] & 1 ≠ y(Q) mod 2'', fail'''Why is it necessary to reveal a bit in a script path spend and check that it matches the parity of the Y coordinate of ''Q''?''' The parity of the Y coordinate is necessary to lift the X coordinate ''q'' to a unique point. While this is not strictly necessary for verifying the taproot commitment as described above, it is necessary to allow batch verification. Alternatively, ''Q'' could be forced to have an even Y coordinate, but that would require retrying with different internal public keys (or different messages) until ''Q'' has that property. There is no downside to adding the parity bit because otherwise the control block bit would be unused..
-** Execute the script, according to the applicable script rules'''What are the applicable script rules in script path spends?''' [[bip-0342.mediawiki|BIP342]] specifies validity rules that apply for leaf version 0xc0, but future proposals can introduce rules for other leaf versions., using the witness stack elements excluding the script ''s'', the control block ''c'', and the annex ''a'' if present, as initial stack.
+** Execute the script, according to the applicable script rules'''What are the applicable script rules in script path spends?''' [[bip-0342.mediawiki|BIP342]] specifies validity rules that apply for leaf version 0xc0, but future proposals can introduce rules for other leaf versions., using the witness stack elements excluding the script ''s'', the control block ''c'', and the annex ''a'' if present, as initial stack. This implies that for the future leaf versions (non-''0xC0'') the execution must succeed.'''Why we need to success on future leaf version validation''' This is required to enable future leaf versions as soft forks.
''q'' is referred to as ''taproot output key'' and ''p'' as ''taproot internal key''.
@@ -88,13 +88,13 @@ We first define a reusable common signature message calculation function, follow
==== Common signature message ====
-The function ''SigMsg(hash_type, ext_flag)'' computes the message being signed as a byte array. It is implicitly also a function of the spending transaction and the outputs it spends, but these are not listed to keep notation simple.
+The function ''SigMsg(hash_type, ext_flag)'' computes the common portion of the message being signed as a byte array. It is implicitly also a function of the spending transaction and the outputs it spends, but these are not listed to keep notation simple.
-The parameter ''hash_type'' is an 8-bit unsigned value. The SIGHASH encodings from the legacy script system are reused, including SIGHASH_ALL, SIGHASH_NONE, SIGHASH_SINGLE, and SIGHASH_ANYONECANPAY, plus the default ''hash_type'' value ''0x00'' which results in signing over the whole transaction just as for SIGHASH_ALL. The following restrictions apply, which cause validation failure if violated:
+The parameter ''hash_type'' is an 8-bit unsigned value. The SIGHASH encodings from the legacy script system are reused, including SIGHASH_ALL, SIGHASH_NONE, SIGHASH_SINGLE, and SIGHASH_ANYONECANPAY. We define a new ''hashtype'' SIGHASH_DEFAULT (value ''0x00'') which results in signing over the whole transaction just as for SIGHASH_ALL. The following restrictions apply, which cause validation failure if violated:
* Using any undefined ''hash_type'' (not ''0x00'', ''0x01'', ''0x02'', ''0x03'', ''0x81'', ''0x82'', or ''0x83'''''Why reject unknown ''hash_type'' values?''' By doing so, it is easier to reason about the worst case amount of signature hashing an implementation with adequate caching must perform.).
* Using SIGHASH_SINGLE without a "corresponding output" (an output with the same index as the input being verified).
-The parameter ''ext_flag'' is an integer in range 0-127, and is used for indicating (in the message) that extensions are added at the end of the message'''What extensions use the ''ext_flag'' mechanism?''' [[bip-0342.mediawiki|BIP342]] reuses the same common signature message algorithm, but adds BIP342-specific data at the end, which is indicated using ''ext_flag = 1''..
+The parameter ''ext_flag'' is an integer in range 0-127, and is used for indicating (in the message) that extensions are appended to the output of ''SigMsg()'''''What extensions use the ''ext_flag'' mechanism?''' [[bip-0342.mediawiki#common-signature-message-extension|BIP342]] reuses the same common signature message algorithm, but adds BIP342-specific data at the end, which is indicated using ''ext_flag = 1''..
If the parameters take acceptable values, the message is the concatenation of the following data, in order (with byte size of each item listed in parentheses). Numerical values in 2, 4, or 8-byte are encoded in little-endian.
@@ -105,8 +105,8 @@ If the parameters take acceptable values, the message is the concatenation of th
** ''nLockTime'' (4): the ''nLockTime'' of the transaction.
** If the ''hash_type & 0x80'' does not equal SIGHASH_ANYONECANPAY:
*** ''sha_prevouts'' (32): the SHA256 of the serialization of all input outpoints.
-*** ''sha_amounts'' (32): the SHA256 of the serialization of all spent output amounts.
-*** ''sha_scriptpubkeys'' (32): the SHA256 of the serialization of all spent output ''scriptPubKey''s.
+*** ''sha_amounts'' (32): the SHA256 of the serialization of all input amounts.
+*** ''sha_scriptpubkeys'' (32): the SHA256 of all spent outputs' ''scriptPubKeys'', serialized as script inside CTxOut.
*** ''sha_sequences'' (32): the SHA256 of the serialization of all input ''nSequence''.
** If ''hash_type & 3'' does not equal SIGHASH_NONE or SIGHASH_SINGLE:
*** ''sha_outputs'' (32): the SHA256 of the serialization of all outputs in CTxOut format.
@@ -136,9 +136,11 @@ In summary, the semantics of the [[bip-0143.mediawiki|BIP143]] sighash types rem
==== Taproot key path spending signature validation ====
+A Taproot signature is a 64-byte Schnorr signature, as defined in [[bip-0340.mediawiki|BIP340]], with the sighash byte appended in the usual Bitcoin fashion. This sighash byte is optional. If omitted, the resulting signatures are 64 bytes, and a SIGHASH_DEFAULT mode is implied.
+
To validate a signature ''sig'' with public key ''q'':
* If the ''sig'' is 64 bytes long, return ''Verify(q, hashTapSighash(0x00 || SigMsg(0x00, 0)), sig)'''''Why is the input to ''hashTapSighash'' prefixed with 0x00?''' This prefix is called the sighash epoch, and allows reusing the ''hashTapSighash'' tagged hash in future signature algorithms that make invasive changes to how hashing is performed (as opposed to the ''ext_flag'' mechanism that is used for incremental extensions). An alternative is having them use a different tag, but supporting a growing number of tags may become undesirable., where ''Verify'' is defined in [[bip-0340.mediawiki#design|BIP340]].
-* If the ''sig'' is 65 bytes long, return ''sig[64] ≠ 0x00'''Why can the hash_type not be 0x00 in 65-byte signatures?''' Permitting that would enable malleating (by third parties, including miners) 64-byte signatures into 65-byte ones, resulting in a different `wtxid` and a different fee rate than the creator intended and Verify(q, hashTapSighash(0x00 || SigMsg(sig[64], 0)), sig[0:64])''.
+* If the ''sig'' is 65 bytes long, return ''sig[64] ≠ 0x00'''Why can the hash_type not be 0x00 in 65-byte signatures?''' Permitting that would enable malleating (by third parties, including miners) 64-byte signatures into 65-byte ones, resulting in a different `wtxid` and a different fee rate than the creator intended. and Verify(q, hashTapSighash(0x00 || SigMsg(sig[64], 0)), sig[0:64])''.
* Otherwise, fail'''Why permit two signature lengths?''' By making the most common type of hash_type implicit, a byte can often be saved..
== Constructing and spending Taproot outputs ==
@@ -152,7 +154,7 @@ Satisfying any of these conditions is sufficient to spend the output.
'''Initial steps''' The first step is determining what the internal key and the organization of the rest of the scripts should be. The specifics are likely application dependent, but here are some general guidelines:
* When deciding between scripts with conditionals (OP_IF etc.) and splitting them up into multiple scripts (each corresponding to one execution path through the original script), it is generally preferable to pick the latter.
* When a single condition requires signatures with multiple keys, key aggregation techniques like MuSig can be used to combine them into a single key. The details are out of scope for this document, but note that this may complicate the signing procedure.
-* If one or more of the spending conditions consist of just a single key (after aggregation), the most likely one should be made the internal key. If no such condition exists, it may be worthwhile adding one that consists of an aggregation of all keys participating in all scripts combined; effectively adding an "everyone agrees" branch. If that is inacceptable, pick as internal key a point with unknown discrete logarithm. One example of such a point is ''H = lift_x(0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)'' which is [https://github.com/ElementsProject/secp256k1-zkp/blob/11af7015de624b010424273be3d91f117f172c82/src/modules/rangeproof/main_impl.h#L16 constructed] by taking the hash of the standard uncompressed encoding of the [https://www.secg.org/sec2-v2.pdf secp256k1] base point ''G'' as X coordinate. In order to avoid leaking the information that key path spending is not possible it is recommended to pick a fresh integer ''r'' in the range ''0...n-1'' uniformly at random and use ''H + rG'' as internal key. It is possible to prove that this internal key does not have a known discrete logarithm with respect to ''G'' by revealing ''r'' to a verifier who can then reconstruct how the internal key was created.
+* If one or more of the spending conditions consist of just a single key (after aggregation), the most likely one should be made the internal key. If no such condition exists, it may be worthwhile adding one that consists of an aggregation of all keys participating in all scripts combined; effectively adding an "everyone agrees" branch. If that is inacceptable, pick as internal key a "Nothing Up My Sleeve" (NUMS) point, i.e., a point with unknown discrete logarithm. One example of such a point is ''H = lift_x(0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)'' which is [https://github.com/ElementsProject/secp256k1-zkp/blob/11af7015de624b010424273be3d91f117f172c82/src/modules/rangeproof/main_impl.h#L16 constructed] by taking the hash of the standard uncompressed encoding of the [https://www.secg.org/sec2-v2.pdf secp256k1] base point ''G'' as X coordinate. In order to avoid leaking the information that key path spending is not possible it is recommended to pick a fresh integer ''r'' in the range ''0...n-1'' uniformly at random and use ''H + rG'' as internal key. It is possible to prove that this internal key does not have a known discrete logarithm with respect to ''G'' by revealing ''r'' to a verifier who can then reconstruct how the internal key was created.
* If the spending conditions do not require a script path, the output key should commit to an unspendable script path instead of having no script path. This can be achieved by computing the output key point as ''Q = P + int(hashTapTweak(bytes(P)))G''. '''Why should the output key always have a taproot commitment, even if there is no script path?'''
If the taproot output key is an aggregate of keys, there is the possibility for a malicious party to add a script path without being noticed by the other parties.
This allows to bypass the multiparty policy and to steal the coin.
@@ -167,7 +169,7 @@ Alice will not be able to notice the script path, but Mallory can unilaterally s
* The remaining scripts should be organized into the leaves of a binary tree. This can be a balanced tree if each of the conditions these scripts correspond to are equally likely. If probabilities for each condition are known, consider constructing the tree as a Huffman tree.
-'''Computing the output script''' Once the spending conditions are split into an internal key internal_pubkey and a binary tree whose leaves are (leaf_version, script) tuples, the output script can be computed using the Python3 algorithms below. These algorithms take advantage of helper functions from the [bip-0340/referency.py BIP340 reference code] for integer conversion, point multiplication, and tagged hashes.
+'''Computing the output script''' Once the spending conditions are split into an internal key internal_pubkey and a binary tree whose leaves are (leaf_version, script) tuples, the output script can be computed using the Python3 algorithms below. These algorithms take advantage of helper functions from the [[bip-0340/reference.py|BIP340 reference code]] for integer conversion, point multiplication, and tagged hashes.
First, we define taproot_tweak_pubkey for 32-byte [[bip-0340.mediawiki|BIP340]] public key arrays.
The function returns a bit indicating the tweaked public key's Y coordinate as well as the public key byte array.
@@ -175,21 +177,27 @@ The parity bit will be required for spending the output with a script path.
In order to allow spending with the key path, we define taproot_tweak_seckey to compute the secret key for a tweaked public key.
For any byte string h it holds that taproot_tweak_pubkey(pubkey_gen(seckey), h)[1] == pubkey_gen(taproot_tweak_seckey(seckey, h)).
+Note that because tweaks are applied to 32-byte public keys, `taproot_tweak_seckey` may need to negate the secret key before applying the tweak.
+
def taproot_tweak_pubkey(pubkey, h):
t = int_from_bytes(tagged_hash("TapTweak", pubkey + h))
if t >= SECP256K1_ORDER:
raise ValueError
- Q = point_add(lift_x(int_from_bytes(pubkey)), point_mul(G, t))
+ P = lift_x(int_from_bytes(pubkey))
+ if P is None:
+ raise ValueError
+ Q = point_add(P, point_mul(G, t))
return 0 if has_even_y(Q) else 1, bytes_from_int(x(Q))
def taproot_tweak_seckey(seckey0, h):
- P = point_mul(G, int_from_bytes(seckey0))
+ seckey0 = int_from_bytes(seckey0)
+ P = point_mul(G, seckey0)
seckey = seckey0 if has_even_y(P) else SECP256K1_ORDER - seckey0
t = int_from_bytes(tagged_hash("TapTweak", bytes_from_int(x(P)) + h))
if t >= SECP256K1_ORDER:
raise ValueError
- return (seckey + t) % SECP256K1_ORDER
+ return bytes_from_int((seckey + t) % SECP256K1_ORDER)
The following function, taproot_output_script, returns a byte array with the scriptPubKey (see [[bip-0141.mediawiki|BIP141]]).
@@ -242,10 +250,13 @@ TapTweak = tagged_hash("TapTweak", p + ABCDE)
'''Spending using the key path''' A Taproot output can be spent with the secret key corresponding to the internal_pubkey. To do so, a witness stack consists of a single element: a [[bip-0340.mediawiki|BIP340]] signature on the signature hash as defined above, with the secret key tweaked by the same h as in the above snippet. See the code below:
-def taproot_sign_key(script_tree, internal_seckey, hash_type):
- _, h = taproot_tree_helper(script_tree)
+def taproot_sign_key(script_tree, internal_seckey, hash_type, bip340_aux_rand):
+ if script_tree is None:
+ h = bytes()
+ else:
+ _, h = taproot_tree_helper(script_tree)
output_seckey = taproot_tweak_seckey(internal_seckey, h)
- sig = schnorr_sign(sighash(hash_type), output_seckey)
+ sig = schnorr_sign(sighash(hash_type), output_seckey, bip340_aux_rand)
if hash_type != 0:
sig += bytes([hash_type])
return [sig]
@@ -284,7 +295,13 @@ The reason for this is to increase leaf entropy and prevent an observer from lea
== Test vectors ==
-The test vectors used in the [https://github.com/bitcoin/bitcoin/blob/3820090bd619ac85ab35eff376c03136fe4a9f04/src/test/script_tests.cpp#L1718 Bitcoin Core unit test framework] can be found [https://github.com/bitcoin-core/qa-assets/blob/main/unit_test_data/script_assets_test.json?raw=true here].
+Test vectors for wallet operation (scriptPubKey computation, key path spending, control block construction) can be found [[bip-0341/wallet-test-vectors.json|here]].
+It consists of two sets of vectors.
+* The first "scriptPubKey" tests concern computing the scriptPubKey and (mainnet) BIP350 address given an internal public key, and a script tree. The script tree is encoded as null to represent no scripts, a JSON object to represent a leaf node, or a 2-element array to represent an inner node. The control blocks needed for script path spending are also provided for each of the script leaves.
+* The second "keyPathSpending" tests consists of a list of test cases, each of which provides an unsigned transaction and the UTXOs it spends. For each of its BIP341 inputs, the internal private key and the Merkle root it was derived from is given, as well as the expected witness to spend it. All signatures are created with an all-zero (0x0000...0000) BIP340 auxiliary randomness array.
+* In all cases, hexadecimal values represent byte arrays, not numbers. In particular, that means that provided hash values have the hex digits corresponding to the first bytes first. This differs from the convention used for txids and block hashes, where the hex strings represent numbers, resulting in a reversed order.
+
+Validation test vectors used in the [https://github.com/bitcoin/bitcoin/blob/3820090bd619ac85ab35eff376c03136fe4a9f04/src/test/script_tests.cpp#L1718 Bitcoin Core unit test framework] can be found [https://github.com/bitcoin-core/qa-assets/blob/main/unit_test_data/script_assets_test.json?raw=true here].
== Rationale ==
@@ -296,7 +313,7 @@ This BIP is deployed concurrently with [[bip-0342.mediawiki|BIP342]].
For Bitcoin signet, these BIPs are always active.
-For Bitcoin mainnet and testnet3, these BIPs will be deployed by "version bits" with the name "taproot" and bit 2, using [[bip-0009.mediawiki|BIP9]] modified to use a lower threshold, with an additional ''min_activation_height'' parameter and replacing the state transition logic for the DEFINED, STARTED and LOCKED_IN states as follows:
+For Bitcoin mainnet and testnet3, these BIPs are deployed by "version bits" with the name "taproot" and bit 2, using [[bip-0009.mediawiki|BIP9]] modified to use a lower threshold, with an additional ''min_activation_height'' parameter and replacing the state transition logic for the DEFINED, STARTED and LOCKED_IN states as follows:
case DEFINED:
if (GetMedianTimePast(block.parent) >= starttime) {
@@ -326,9 +343,11 @@ For Bitcoin mainnet and testnet3, these BIPs will be deployed by "version bits"
}
return ACTIVE;
-For Bitcoin mainnet, the starttime is epoch timestamp 1619222400 (midnight 24 April 2021 UTC), timeout is epoch timestamp 1628640000 (midnight 11 August 2021 UTC), the threshold is 1815 blocks (90%) instead of 1916 blocks (95%), and the min_activation_height is block 709632 (expected approximately 12 November 2021).
+For Bitcoin mainnet, the starttime is epoch timestamp 1619222400 (midnight 24 April 2021 UTC), timeout is epoch timestamp 1628640000 (midnight 11 August 2021 UTC), the threshold is 1815 blocks (90%) instead of 1916 blocks (95%), and the min_activation_height is block 709632.
+The deployment did activate at height 709632 on Bitcoin mainnet.
For Bitcoin testnet3, the starttime is epoch timestamp 1619222400 (midnight 24 April 2021 UTC), timeout is epoch timestamp 1628640000 (midnight 11 August 2021 UTC), the threshold is 1512 blocks (75%), and the min_activation_height is block 0.
+The deployment did activate at height 2011968 on Bitcoin testnet3.
== Backwards compatibility ==
As a soft fork, older software will continue to operate without modification.
@@ -340,6 +359,6 @@ Depending on the implementation non-upgraded wallets may be able to send to Segw
== Acknowledgements ==
-This document is the result of discussions around script and signature improvements with many people, and had direct contributions from Greg Maxwell and others. It further builds on top of earlier published proposals such as Taproot by Greg Maxwell, and Merkle branch constructions by Russell O'Connor, Johnson Lau, and Mark Friedenbach.
+This document is the result of discussions around script and signature improvements with many people, and had direct contributions from Greg Maxwell and others. It further builds on top of earlier published proposals such as Taproot by Greg Maxwell, and Merkle branch constructions by Russell O'Connor, Johnson Lau, and Mark Friedenbach.
The authors wish the thank Arik Sosman for suggesting to sort Merkle node children before hashes, removing the need to transfer the position in the tree, as well as all those who provided valuable feedback and reviews, including the participants of the [https://github.com/ajtowns/taproot-review structured reviews].
diff --git a/bip-0341/wallet-test-vectors.json b/bip-0341/wallet-test-vectors.json
new file mode 100644
index 0000000000..11261b00ba
--- /dev/null
+++ b/bip-0341/wallet-test-vectors.json
@@ -0,0 +1,452 @@
+{
+ "version": 1,
+ "scriptPubKey": [
+ {
+ "given": {
+ "internalPubkey": "d6889cb081036e0faefa3a35157ad71086b123b2b144b649798b494c300a961d",
+ "scriptTree": null
+ },
+ "intermediary": {
+ "merkleRoot": null,
+ "tweak": "b86e7be8f39bab32a6f2c0443abbc210f0edac0e2c53d501b36b64437d9c6c70",
+ "tweakedPubkey": "53a1f6e454df1aa2776a2814a721372d6258050de330b3c6d10ee8f4e0dda343"
+ },
+ "expected": {
+ "scriptPubKey": "512053a1f6e454df1aa2776a2814a721372d6258050de330b3c6d10ee8f4e0dda343",
+ "bip350Address": "bc1p2wsldez5mud2yam29q22wgfh9439spgduvct83k3pm50fcxa5dps59h4z5"
+ }
+ },
+ {
+ "given": {
+ "internalPubkey": "187791b6f712a8ea41c8ecdd0ee77fab3e85263b37e1ec18a3651926b3a6cf27",
+ "scriptTree": {
+ "id": 0,
+ "script": "20d85a959b0290bf19bb89ed43c916be835475d013da4b362117393e25a48229b8ac",
+ "leafVersion": 192
+ }
+ },
+ "intermediary": {
+ "leafHashes": [
+ "5b75adecf53548f3ec6ad7d78383bf84cc57b55a3127c72b9a2481752dd88b21"
+ ],
+ "merkleRoot": "5b75adecf53548f3ec6ad7d78383bf84cc57b55a3127c72b9a2481752dd88b21",
+ "tweak": "cbd8679ba636c1110ea247542cfbd964131a6be84f873f7f3b62a777528ed001",
+ "tweakedPubkey": "147c9c57132f6e7ecddba9800bb0c4449251c92a1e60371ee77557b6620f3ea3"
+ },
+ "expected": {
+ "scriptPubKey": "5120147c9c57132f6e7ecddba9800bb0c4449251c92a1e60371ee77557b6620f3ea3",
+ "bip350Address": "bc1pz37fc4cn9ah8anwm4xqqhvxygjf9rjf2resrw8h8w4tmvcs0863sa2e586",
+ "scriptPathControlBlocks": [
+ "c1187791b6f712a8ea41c8ecdd0ee77fab3e85263b37e1ec18a3651926b3a6cf27"
+ ]
+ }
+ },
+ {
+ "given": {
+ "internalPubkey": "93478e9488f956df2396be2ce6c5cced75f900dfa18e7dabd2428aae78451820",
+ "scriptTree": {
+ "id": 0,
+ "script": "20b617298552a72ade070667e86ca63b8f5789a9fe8731ef91202a91c9f3459007ac",
+ "leafVersion": 192
+ }
+ },
+ "intermediary": {
+ "leafHashes": [
+ "c525714a7f49c28aedbbba78c005931a81c234b2f6c99a73e4d06082adc8bf2b"
+ ],
+ "merkleRoot": "c525714a7f49c28aedbbba78c005931a81c234b2f6c99a73e4d06082adc8bf2b",
+ "tweak": "6af9e28dbf9d6aaf027696e2598a5b3d056f5fd2355a7fd5a37a0e5008132d30",
+ "tweakedPubkey": "e4d810fd50586274face62b8a807eb9719cef49c04177cc6b76a9a4251d5450e"
+ },
+ "expected": {
+ "scriptPubKey": "5120e4d810fd50586274face62b8a807eb9719cef49c04177cc6b76a9a4251d5450e",
+ "bip350Address": "bc1punvppl2stp38f7kwv2u2spltjuvuaayuqsthe34hd2dyy5w4g58qqfuag5",
+ "scriptPathControlBlocks": [
+ "c093478e9488f956df2396be2ce6c5cced75f900dfa18e7dabd2428aae78451820"
+ ]
+ }
+ },
+ {
+ "given": {
+ "internalPubkey": "ee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf3786592",
+ "scriptTree": [
+ {
+ "id": 0,
+ "script": "20387671353e273264c495656e27e39ba899ea8fee3bb69fb2a680e22093447d48ac",
+ "leafVersion": 192
+ },
+ {
+ "id": 1,
+ "script": "06424950333431",
+ "leafVersion": 250
+ }
+ ]
+ },
+ "intermediary": {
+ "leafHashes": [
+ "8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7",
+ "f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a"
+ ],
+ "merkleRoot": "6c2dc106ab816b73f9d07e3cd1ef2c8c1256f519748e0813e4edd2405d277bef",
+ "tweak": "9e0517edc8259bb3359255400b23ca9507f2a91cd1e4250ba068b4eafceba4a9",
+ "tweakedPubkey": "712447206d7a5238acc7ff53fbe94a3b64539ad291c7cdbc490b7577e4b17df5"
+ },
+ "expected": {
+ "scriptPubKey": "5120712447206d7a5238acc7ff53fbe94a3b64539ad291c7cdbc490b7577e4b17df5",
+ "bip350Address": "bc1pwyjywgrd0ffr3tx8laflh6228dj98xkjj8rum0zfpd6h0e930h6saqxrrm",
+ "scriptPathControlBlocks": [
+ "c0ee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf3786592f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a",
+ "faee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf37865928ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7"
+ ]
+ }
+ },
+ {
+ "given": {
+ "internalPubkey": "f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd8",
+ "scriptTree": [
+ {
+ "id": 0,
+ "script": "2044b178d64c32c4a05cc4f4d1407268f764c940d20ce97abfd44db5c3592b72fdac",
+ "leafVersion": 192
+ },
+ {
+ "id": 1,
+ "script": "07546170726f6f74",
+ "leafVersion": 192
+ }
+ ]
+ },
+ "intermediary": {
+ "leafHashes": [
+ "64512fecdb5afa04f98839b50e6f0cb7b1e539bf6f205f67934083cdcc3c8d89",
+ "2cb2b90daa543b544161530c925f285b06196940d6085ca9474d41dc3822c5cb"
+ ],
+ "merkleRoot": "ab179431c28d3b68fb798957faf5497d69c883c6fb1e1cd9f81483d87bac90cc",
+ "tweak": "639f0281b7ac49e742cd25b7f188657626da1ad169209078e2761cefd91fd65e",
+ "tweakedPubkey": "77e30a5522dd9f894c3f8b8bd4c4b2cf82ca7da8a3ea6a239655c39c050ab220"
+ },
+ "expected": {
+ "scriptPubKey": "512077e30a5522dd9f894c3f8b8bd4c4b2cf82ca7da8a3ea6a239655c39c050ab220",
+ "bip350Address": "bc1pwl3s54fzmk0cjnpl3w9af39je7pv5ldg504x5guk2hpecpg2kgsqaqstjq",
+ "scriptPathControlBlocks": [
+ "c1f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd82cb2b90daa543b544161530c925f285b06196940d6085ca9474d41dc3822c5cb",
+ "c1f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd864512fecdb5afa04f98839b50e6f0cb7b1e539bf6f205f67934083cdcc3c8d89"
+ ]
+ }
+ },
+ {
+ "given": {
+ "internalPubkey": "e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6f",
+ "scriptTree": [
+ {
+ "id": 0,
+ "script": "2072ea6adcf1d371dea8fba1035a09f3d24ed5a059799bae114084130ee5898e69ac",
+ "leafVersion": 192
+ },
+ [
+ {
+ "id": 1,
+ "script": "202352d137f2f3ab38d1eaa976758873377fa5ebb817372c71e2c542313d4abda8ac",
+ "leafVersion": 192
+ },
+ {
+ "id": 2,
+ "script": "207337c0dd4253cb86f2c43a2351aadd82cccb12a172cd120452b9bb8324f2186aac",
+ "leafVersion": 192
+ }
+ ]
+ ]
+ },
+ "intermediary": {
+ "leafHashes": [
+ "2645a02e0aac1fe69d69755733a9b7621b694bb5b5cde2bbfc94066ed62b9817",
+ "ba982a91d4fc552163cb1c0da03676102d5b7a014304c01f0c77b2b8e888de1c",
+ "9e31407bffa15fefbf5090b149d53959ecdf3f62b1246780238c24501d5ceaf6"
+ ],
+ "merkleRoot": "ccbd66c6f7e8fdab47b3a486f59d28262be857f30d4773f2d5ea47f7761ce0e2",
+ "tweak": "b57bfa183d28eeb6ad688ddaabb265b4a41fbf68e5fed2c72c74de70d5a786f4",
+ "tweakedPubkey": "91b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605"
+ },
+ "expected": {
+ "scriptPubKey": "512091b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605",
+ "bip350Address": "bc1pjxmy65eywgafs5tsunw95ruycpqcqnev6ynxp7jaasylcgtcxczs6n332e",
+ "scriptPathControlBlocks": [
+ "c0e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6fffe578e9ea769027e4f5a3de40732f75a88a6353a09d767ddeb66accef85e553",
+ "c0e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6f9e31407bffa15fefbf5090b149d53959ecdf3f62b1246780238c24501d5ceaf62645a02e0aac1fe69d69755733a9b7621b694bb5b5cde2bbfc94066ed62b9817",
+ "c0e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6fba982a91d4fc552163cb1c0da03676102d5b7a014304c01f0c77b2b8e888de1c2645a02e0aac1fe69d69755733a9b7621b694bb5b5cde2bbfc94066ed62b9817"
+ ]
+ }
+ },
+ {
+ "given": {
+ "internalPubkey": "55adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d",
+ "scriptTree": [
+ {
+ "id": 0,
+ "script": "2071981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2ac",
+ "leafVersion": 192
+ },
+ [
+ {
+ "id": 1,
+ "script": "20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac",
+ "leafVersion": 192
+ },
+ {
+ "id": 2,
+ "script": "20c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4cac",
+ "leafVersion": 192
+ }
+ ]
+ ]
+ },
+ "intermediary": {
+ "leafHashes": [
+ "f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d",
+ "737ed1fe30bc42b8022d717b44f0d93516617af64a64753b7a06bf16b26cd711",
+ "d7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7"
+ ],
+ "merkleRoot": "2f6b2c5397b6d68ca18e09a3f05161668ffe93a988582d55c6f07bd5b3329def",
+ "tweak": "6579138e7976dc13b6a92f7bfd5a2fc7684f5ea42419d43368301470f3b74ed9",
+ "tweakedPubkey": "75169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831"
+ },
+ "expected": {
+ "scriptPubKey": "512075169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831",
+ "bip350Address": "bc1pw5tf7sqp4f50zka7629jrr036znzew70zxyvvej3zrpf8jg8hqcssyuewe",
+ "scriptPathControlBlocks": [
+ "c155adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d3cd369a528b326bc9d2133cbd2ac21451acb31681a410434672c8e34fe757e91",
+ "c155adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312dd7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d",
+ "c155adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d737ed1fe30bc42b8022d717b44f0d93516617af64a64753b7a06bf16b26cd711f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d"
+ ]
+ }
+ }
+ ],
+ "keyPathSpending": [
+ {
+ "given": {
+ "rawUnsignedTx": "02000000097de20cbff686da83a54981d2b9bab3586f4ca7e48f57f5b55963115f3b334e9c010000000000000000d7b7cab57b1393ace2d064f4d4a2cb8af6def61273e127517d44759b6dafdd990000000000fffffffff8e1f583384333689228c5d28eac13366be082dc57441760d957275419a418420000000000fffffffff0689180aa63b30cb162a73c6d2a38b7eeda2a83ece74310fda0843ad604853b0100000000feffffffaa5202bdf6d8ccd2ee0f0202afbbb7461d9264a25e5bfd3c5a52ee1239e0ba6c0000000000feffffff956149bdc66faa968eb2be2d2faa29718acbfe3941215893a2a3446d32acd050000000000000000000e664b9773b88c09c32cb70a2a3e4da0ced63b7ba3b22f848531bbb1d5d5f4c94010000000000000000e9aa6b8e6c9de67619e6a3924ae25696bb7b694bb677a632a74ef7eadfd4eabf0000000000ffffffffa778eb6a263dc090464cd125c466b5a99667720b1c110468831d058aa1b82af10100000000ffffffff0200ca9a3b000000001976a91406afd46bcdfd22ef94ac122aa11f241244a37ecc88ac807840cb0000000020ac9a87f5594be208f8532db38cff670c450ed2fea8fcdefcc9a663f78bab962b0065cd1d",
+ "utxosSpent": [
+ {
+ "scriptPubKey": "512053a1f6e454df1aa2776a2814a721372d6258050de330b3c6d10ee8f4e0dda343",
+ "amountSats": 420000000
+ },
+ {
+ "scriptPubKey": "5120147c9c57132f6e7ecddba9800bb0c4449251c92a1e60371ee77557b6620f3ea3",
+ "amountSats": 462000000
+ },
+ {
+ "scriptPubKey": "76a914751e76e8199196d454941c45d1b3a323f1433bd688ac",
+ "amountSats": 294000000
+ },
+ {
+ "scriptPubKey": "5120e4d810fd50586274face62b8a807eb9719cef49c04177cc6b76a9a4251d5450e",
+ "amountSats": 504000000
+ },
+ {
+ "scriptPubKey": "512091b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605",
+ "amountSats": 630000000
+ },
+ {
+ "scriptPubKey": "00147dd65592d0ab2fe0d0257d571abf032cd9db93dc",
+ "amountSats": 378000000
+ },
+ {
+ "scriptPubKey": "512075169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831",
+ "amountSats": 672000000
+ },
+ {
+ "scriptPubKey": "5120712447206d7a5238acc7ff53fbe94a3b64539ad291c7cdbc490b7577e4b17df5",
+ "amountSats": 546000000
+ },
+ {
+ "scriptPubKey": "512077e30a5522dd9f894c3f8b8bd4c4b2cf82ca7da8a3ea6a239655c39c050ab220",
+ "amountSats": 588000000
+ }
+ ]
+ },
+ "intermediary": {
+ "hashAmounts": "58a6964a4f5f8f0b642ded0a8a553be7622a719da71d1f5befcefcdee8e0fde6",
+ "hashOutputs": "a2e6dab7c1f0dcd297c8d61647fd17d821541ea69c3cc37dcbad7f90d4eb4bc5",
+ "hashPrevouts": "e3b33bb4ef3a52ad1fffb555c0d82828eb22737036eaeb02a235d82b909c4c3f",
+ "hashScriptPubkeys": "23ad0f61ad2bca5ba6a7693f50fce988e17c3780bf2b1e720cfbb38fbdd52e21",
+ "hashSequences": "18959c7221ab5ce9e26c3cd67b22c24f8baa54bac281d8e6b05e400e6c3a957e"
+ },
+ "inputSpending": [
+ {
+ "given": {
+ "txinIndex": 0,
+ "internalPrivkey": "6b973d88838f27366ed61c9ad6367663045cb456e28335c109e30717ae0c6baa",
+ "merkleRoot": null,
+ "hashType": 3
+ },
+ "intermediary": {
+ "internalPubkey": "d6889cb081036e0faefa3a35157ad71086b123b2b144b649798b494c300a961d",
+ "tweak": "b86e7be8f39bab32a6f2c0443abbc210f0edac0e2c53d501b36b64437d9c6c70",
+ "tweakedPrivkey": "2405b971772ad26915c8dcdf10f238753a9b837e5f8e6a86fd7c0cce5b7296d9",
+ "sigMsg": "0003020000000065cd1de3b33bb4ef3a52ad1fffb555c0d82828eb22737036eaeb02a235d82b909c4c3f58a6964a4f5f8f0b642ded0a8a553be7622a719da71d1f5befcefcdee8e0fde623ad0f61ad2bca5ba6a7693f50fce988e17c3780bf2b1e720cfbb38fbdd52e2118959c7221ab5ce9e26c3cd67b22c24f8baa54bac281d8e6b05e400e6c3a957e0000000000d0418f0e9a36245b9a50ec87f8bf5be5bcae434337b87139c3a5b1f56e33cba0",
+ "precomputedUsed": [
+ "hashAmounts",
+ "hashPrevouts",
+ "hashScriptPubkeys",
+ "hashSequences"
+ ],
+ "sigHash": "2514a6272f85cfa0f45eb907fcb0d121b808ed37c6ea160a5a9046ed5526d555"
+ },
+ "expected": {
+ "witness": [
+ "ed7c1647cb97379e76892be0cacff57ec4a7102aa24296ca39af7541246d8ff14d38958d4cc1e2e478e4d4a764bbfd835b16d4e314b72937b29833060b87276c03"
+ ]
+ }
+ },
+ {
+ "given": {
+ "txinIndex": 1,
+ "internalPrivkey": "1e4da49f6aaf4e5cd175fe08a32bb5cb4863d963921255f33d3bc31e1343907f",
+ "merkleRoot": "5b75adecf53548f3ec6ad7d78383bf84cc57b55a3127c72b9a2481752dd88b21",
+ "hashType": 131
+ },
+ "intermediary": {
+ "internalPubkey": "187791b6f712a8ea41c8ecdd0ee77fab3e85263b37e1ec18a3651926b3a6cf27",
+ "tweak": "cbd8679ba636c1110ea247542cfbd964131a6be84f873f7f3b62a777528ed001",
+ "tweakedPrivkey": "ea260c3b10e60f6de018455cd0278f2f5b7e454be1999572789e6a9565d26080",
+ "sigMsg": "0083020000000065cd1d00d7b7cab57b1393ace2d064f4d4a2cb8af6def61273e127517d44759b6dafdd9900000000808f891b00000000225120147c9c57132f6e7ecddba9800bb0c4449251c92a1e60371ee77557b6620f3ea3ffffffffffcef8fb4ca7efc5433f591ecfc57391811ce1e186a3793024def5c884cba51d",
+ "precomputedUsed": [],
+ "sigHash": "325a644af47e8a5a2591cda0ab0723978537318f10e6a63d4eed783b96a71a4d"
+ },
+ "expected": {
+ "witness": [
+ "052aedffc554b41f52b521071793a6b88d6dbca9dba94cf34c83696de0c1ec35ca9c5ed4ab28059bd606a4f3a657eec0bb96661d42921b5f50a95ad33675b54f83"
+ ]
+ }
+ },
+ {
+ "given": {
+ "txinIndex": 3,
+ "internalPrivkey": "d3c7af07da2d54f7a7735d3d0fc4f0a73164db638b2f2f7c43f711f6d4aa7e64",
+ "merkleRoot": "c525714a7f49c28aedbbba78c005931a81c234b2f6c99a73e4d06082adc8bf2b",
+ "hashType": 1
+ },
+ "intermediary": {
+ "internalPubkey": "93478e9488f956df2396be2ce6c5cced75f900dfa18e7dabd2428aae78451820",
+ "tweak": "6af9e28dbf9d6aaf027696e2598a5b3d056f5fd2355a7fd5a37a0e5008132d30",
+ "tweakedPrivkey": "97323385e57015b75b0339a549c56a948eb961555973f0951f555ae6039ef00d",
+ "sigMsg": "0001020000000065cd1de3b33bb4ef3a52ad1fffb555c0d82828eb22737036eaeb02a235d82b909c4c3f58a6964a4f5f8f0b642ded0a8a553be7622a719da71d1f5befcefcdee8e0fde623ad0f61ad2bca5ba6a7693f50fce988e17c3780bf2b1e720cfbb38fbdd52e2118959c7221ab5ce9e26c3cd67b22c24f8baa54bac281d8e6b05e400e6c3a957ea2e6dab7c1f0dcd297c8d61647fd17d821541ea69c3cc37dcbad7f90d4eb4bc50003000000",
+ "precomputedUsed": [
+ "hashAmounts",
+ "hashOutputs",
+ "hashPrevouts",
+ "hashScriptPubkeys",
+ "hashSequences"
+ ],
+ "sigHash": "bf013ea93474aa67815b1b6cc441d23b64fa310911d991e713cd34c7f5d46669"
+ },
+ "expected": {
+ "witness": [
+ "ff45f742a876139946a149ab4d9185574b98dc919d2eb6754f8abaa59d18b025637a3aa043b91817739554f4ed2026cf8022dbd83e351ce1fabc272841d2510a01"
+ ]
+ }
+ },
+ {
+ "given": {
+ "txinIndex": 4,
+ "internalPrivkey": "f36bb07a11e469ce941d16b63b11b9b9120a84d9d87cff2c84a8d4affb438f4e",
+ "merkleRoot": "ccbd66c6f7e8fdab47b3a486f59d28262be857f30d4773f2d5ea47f7761ce0e2",
+ "hashType": 0
+ },
+ "intermediary": {
+ "internalPubkey": "e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6f",
+ "tweak": "b57bfa183d28eeb6ad688ddaabb265b4a41fbf68e5fed2c72c74de70d5a786f4",
+ "tweakedPrivkey": "a8e7aa924f0d58854185a490e6c41f6efb7b675c0f3331b7f14b549400b4d501",
+ "sigMsg": "0000020000000065cd1de3b33bb4ef3a52ad1fffb555c0d82828eb22737036eaeb02a235d82b909c4c3f58a6964a4f5f8f0b642ded0a8a553be7622a719da71d1f5befcefcdee8e0fde623ad0f61ad2bca5ba6a7693f50fce988e17c3780bf2b1e720cfbb38fbdd52e2118959c7221ab5ce9e26c3cd67b22c24f8baa54bac281d8e6b05e400e6c3a957ea2e6dab7c1f0dcd297c8d61647fd17d821541ea69c3cc37dcbad7f90d4eb4bc50004000000",
+ "precomputedUsed": [
+ "hashAmounts",
+ "hashOutputs",
+ "hashPrevouts",
+ "hashScriptPubkeys",
+ "hashSequences"
+ ],
+ "sigHash": "4f900a0bae3f1446fd48490c2958b5a023228f01661cda3496a11da502a7f7ef"
+ },
+ "expected": {
+ "witness": [
+ "b4010dd48a617db09926f729e79c33ae0b4e94b79f04a1ae93ede6315eb3669de185a17d2b0ac9ee09fd4c64b678a0b61a0a86fa888a273c8511be83bfd6810f"
+ ]
+ }
+ },
+ {
+ "given": {
+ "txinIndex": 6,
+ "internalPrivkey": "415cfe9c15d9cea27d8104d5517c06e9de48e2f986b695e4f5ffebf230e725d8",
+ "merkleRoot": "2f6b2c5397b6d68ca18e09a3f05161668ffe93a988582d55c6f07bd5b3329def",
+ "hashType": 2
+ },
+ "intermediary": {
+ "internalPubkey": "55adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d",
+ "tweak": "6579138e7976dc13b6a92f7bfd5a2fc7684f5ea42419d43368301470f3b74ed9",
+ "tweakedPrivkey": "241c14f2639d0d7139282aa6abde28dd8a067baa9d633e4e7230287ec2d02901",
+ "sigMsg": "0002020000000065cd1de3b33bb4ef3a52ad1fffb555c0d82828eb22737036eaeb02a235d82b909c4c3f58a6964a4f5f8f0b642ded0a8a553be7622a719da71d1f5befcefcdee8e0fde623ad0f61ad2bca5ba6a7693f50fce988e17c3780bf2b1e720cfbb38fbdd52e2118959c7221ab5ce9e26c3cd67b22c24f8baa54bac281d8e6b05e400e6c3a957e0006000000",
+ "precomputedUsed": [
+ "hashAmounts",
+ "hashPrevouts",
+ "hashScriptPubkeys",
+ "hashSequences"
+ ],
+ "sigHash": "15f25c298eb5cdc7eb1d638dd2d45c97c4c59dcaec6679cfc16ad84f30876b85"
+ },
+ "expected": {
+ "witness": [
+ "a3785919a2ce3c4ce26f298c3d51619bc474ae24014bcdd31328cd8cfbab2eff3395fa0a16fe5f486d12f22a9cedded5ae74feb4bbe5351346508c5405bcfee002"
+ ]
+ }
+ },
+ {
+ "given": {
+ "txinIndex": 7,
+ "internalPrivkey": "c7b0e81f0a9a0b0499e112279d718cca98e79a12e2f137c72ae5b213aad0d103",
+ "merkleRoot": "6c2dc106ab816b73f9d07e3cd1ef2c8c1256f519748e0813e4edd2405d277bef",
+ "hashType": 130
+ },
+ "intermediary": {
+ "internalPubkey": "ee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf3786592",
+ "tweak": "9e0517edc8259bb3359255400b23ca9507f2a91cd1e4250ba068b4eafceba4a9",
+ "tweakedPrivkey": "65b6000cd2bfa6b7cf736767a8955760e62b6649058cbc970b7c0871d786346b",
+ "sigMsg": "0082020000000065cd1d00e9aa6b8e6c9de67619e6a3924ae25696bb7b694bb677a632a74ef7eadfd4eabf00000000804c8b2000000000225120712447206d7a5238acc7ff53fbe94a3b64539ad291c7cdbc490b7577e4b17df5ffffffff",
+ "precomputedUsed": [],
+ "sigHash": "cd292de50313804dabe4685e83f923d2969577191a3e1d2882220dca88cbeb10"
+ },
+ "expected": {
+ "witness": [
+ "ea0c6ba90763c2d3a296ad82ba45881abb4f426b3f87af162dd24d5109edc1cdd11915095ba47c3a9963dc1e6c432939872bc49212fe34c632cd3ab9fed429c482"
+ ]
+ }
+ },
+ {
+ "given": {
+ "txinIndex": 8,
+ "internalPrivkey": "77863416be0d0665e517e1c375fd6f75839544eca553675ef7fdf4949518ebaa",
+ "merkleRoot": "ab179431c28d3b68fb798957faf5497d69c883c6fb1e1cd9f81483d87bac90cc",
+ "hashType": 129
+ },
+ "intermediary": {
+ "internalPubkey": "f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd8",
+ "tweak": "639f0281b7ac49e742cd25b7f188657626da1ad169209078e2761cefd91fd65e",
+ "tweakedPrivkey": "ec18ce6af99f43815db543f47b8af5ff5df3b2cb7315c955aa4a86e8143d2bf5",
+ "sigMsg": "0081020000000065cd1da2e6dab7c1f0dcd297c8d61647fd17d821541ea69c3cc37dcbad7f90d4eb4bc500a778eb6a263dc090464cd125c466b5a99667720b1c110468831d058aa1b82af101000000002b0c230000000022512077e30a5522dd9f894c3f8b8bd4c4b2cf82ca7da8a3ea6a239655c39c050ab220ffffffff",
+ "precomputedUsed": [
+ "hashOutputs"
+ ],
+ "sigHash": "cccb739eca6c13a8a89e6e5cd317ffe55669bbda23f2fd37b0f18755e008edd2"
+ },
+ "expected": {
+ "witness": [
+ "bbc9584a11074e83bc8c6759ec55401f0ae7b03ef290c3139814f545b58a9f8127258000874f44bc46db7646322107d4d86aec8e73b8719a61fff761d75b5dd981"
+ ]
+ }
+ }
+ ],
+ "auxiliary": {
+ "fullySignedTx": "020000000001097de20cbff686da83a54981d2b9bab3586f4ca7e48f57f5b55963115f3b334e9c010000000000000000d7b7cab57b1393ace2d064f4d4a2cb8af6def61273e127517d44759b6dafdd990000000000fffffffff8e1f583384333689228c5d28eac13366be082dc57441760d957275419a41842000000006b4830450221008f3b8f8f0537c420654d2283673a761b7ee2ea3c130753103e08ce79201cf32a022079e7ab904a1980ef1c5890b648c8783f4d10103dd62f740d13daa79e298d50c201210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798fffffffff0689180aa63b30cb162a73c6d2a38b7eeda2a83ece74310fda0843ad604853b0100000000feffffffaa5202bdf6d8ccd2ee0f0202afbbb7461d9264a25e5bfd3c5a52ee1239e0ba6c0000000000feffffff956149bdc66faa968eb2be2d2faa29718acbfe3941215893a2a3446d32acd050000000000000000000e664b9773b88c09c32cb70a2a3e4da0ced63b7ba3b22f848531bbb1d5d5f4c94010000000000000000e9aa6b8e6c9de67619e6a3924ae25696bb7b694bb677a632a74ef7eadfd4eabf0000000000ffffffffa778eb6a263dc090464cd125c466b5a99667720b1c110468831d058aa1b82af10100000000ffffffff0200ca9a3b000000001976a91406afd46bcdfd22ef94ac122aa11f241244a37ecc88ac807840cb0000000020ac9a87f5594be208f8532db38cff670c450ed2fea8fcdefcc9a663f78bab962b0141ed7c1647cb97379e76892be0cacff57ec4a7102aa24296ca39af7541246d8ff14d38958d4cc1e2e478e4d4a764bbfd835b16d4e314b72937b29833060b87276c030141052aedffc554b41f52b521071793a6b88d6dbca9dba94cf34c83696de0c1ec35ca9c5ed4ab28059bd606a4f3a657eec0bb96661d42921b5f50a95ad33675b54f83000141ff45f742a876139946a149ab4d9185574b98dc919d2eb6754f8abaa59d18b025637a3aa043b91817739554f4ed2026cf8022dbd83e351ce1fabc272841d2510a010140b4010dd48a617db09926f729e79c33ae0b4e94b79f04a1ae93ede6315eb3669de185a17d2b0ac9ee09fd4c64b678a0b61a0a86fa888a273c8511be83bfd6810f0247304402202b795e4de72646d76eab3f0ab27dfa30b810e856ff3a46c9a702df53bb0d8cc302203ccc4d822edab5f35caddb10af1be93583526ccfbade4b4ead350781e2f8adcd012102f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f90141a3785919a2ce3c4ce26f298c3d51619bc474ae24014bcdd31328cd8cfbab2eff3395fa0a16fe5f486d12f22a9cedded5ae74feb4bbe5351346508c5405bcfee0020141ea0c6ba90763c2d3a296ad82ba45881abb4f426b3f87af162dd24d5109edc1cdd11915095ba47c3a9963dc1e6c432939872bc49212fe34c632cd3ab9fed429c4820141bbc9584a11074e83bc8c6759ec55401f0ae7b03ef290c3139814f545b58a9f8127258000874f44bc46db7646322107d4d86aec8e73b8719a61fff761d75b5dd9810065cd1d"
+ }
+ }
+ ]
+}
diff --git a/bip-0342.mediawiki b/bip-0342.mediawiki
index 87e07ae8c0..64d07cc2a0 100644
--- a/bip-0342.mediawiki
+++ b/bip-0342.mediawiki
@@ -7,7 +7,7 @@
Anthony Towns
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0342
- Status: Draft
+ Status: Final
Type: Standards Track
Created: 2020-01-19
License: BSD-3-Clause
@@ -104,13 +104,17 @@ The following rules apply to OP_CHECKSIG, OP_CHECKSIGVERIFY
*** For OP_CHECKSIG, a 1-byte value 0x01 is pushed onto the stack.
*** For OP_CHECKSIGADD, a CScriptNum with value of n + 1 is pushed onto the stack.
+===Common Signature Message Extension===
+
+We define the tapscript message extension ''ext'' to [[bip-0341.mediawiki#common-signature-message|BIP341 Common Signature Message]], indicated by ''ext_flag = 1'':
+* ''tapleaf_hash'' (32): the tapleaf hash as defined in [[bip-0341.mediawiki#design|BIP341]]
+* ''key_version'' (1): a constant value ''0x00'' representing the current version of public keys in the tapscript signature opcode execution.
+* ''codesep_pos'' (4): the opcode position of the last executed OP_CODESEPARATOR before the currently executed signature opcode, with the value in little endian (or ''0xffffffff'' if none executed). The first opcode in a script has a position of 0. A multi-byte push opcode is counted as one opcode, regardless of the size of data being pushed. Opcodes in parsed but unexecuted branches count towards this value as well.
+
===Signature validation===
To validate a signature ''sig'' with public key ''p'':
-* Compute the tapscript message extension ''ext'', consisting of the concatenation of:
-** ''tapleaf_hash'' (32): the tapleaf hash as defined in [[bip-0341.mediawiki#design|BIP341]]
-** ''key_version'' (1): a constant value ''0x00'' representing the current version of public keys in the tapscript signature opcode execution.
-** ''codesep_pos'' (4): the opcode position of the last executed OP_CODESEPARATOR before the currently executed signature opcode, with the value in little endian (or ''0xffffffff'' if none executed). The first opcode in a script has a position of 0. A multi-byte push opcode is counted as one opcode, regardless of the size of data being pushed. Opcodes in parsed but unexecuted branches count towards this value as well.
+* Compute the tapscript message extension ''ext'' described above.
* If the ''sig'' is 64 bytes long, return ''Verify(p, hashTapSighash(0x00 || SigMsg(0x00, 1) || ext), sig)'', where ''Verify'' is defined in [[bip-0340.mediawiki#design|BIP340]].
* If the ''sig'' is 65 bytes long, return ''sig[64] ≠ 0x00 and Verify(p, hashTapSighash(0x00 || SigMsg(sig[64], 1) || ext), sig[0:64])''.
* Otherwise, fail.
diff --git a/bip-0343.mediawiki b/bip-0343.mediawiki
index 3d2f392560..cab5cb707f 100644
--- a/bip-0343.mediawiki
+++ b/bip-0343.mediawiki
@@ -6,7 +6,7 @@
Michael Folkson
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0343
- Status: Proposed
+ Status: Final
Type: Standards Track
Created: 2021-04-25
License: BSD-3-Clause
@@ -19,7 +19,7 @@ This document specifies a BIP8 (LOT=true) deployment to activate taproot.
==Motivation==
-The Taproot soft fork upgrade has been assessed to have overwhelming community consensus and hence should attempt to be activated. Lessons have been learned from the BIP148 and BIP91 deployments in 2017 with regards to giving many months of advance warning before the mandatory signaling is attempted. The mandatory signaling is only required if miners have failed to meet the signaling threshold during the BIP8 deployment. It is important that mandatory signaling is included as without it miners would effectively have the ability to indefinitely block the activation of a soft fork with overwhelming consensus.
+The Taproot soft fork upgrade has been assessed to have overwhelming community consensus and hence should attempt to be activated. Lessons have been learned from the BIP148 and BIP91 deployments in 2017 with regards to giving many months of advance warning before the mandatory signaling is attempted. The mandatory signaling is only required if miners have failed to meet the signaling threshold during the BIP8 deployment. It is important that mandatory signaling is included as without it miners would effectively have the ability to indefinitely block the activation of a soft fork with overwhelming consensus.
==Specification==
diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki
new file mode 100644
index 0000000000..81477e4381
--- /dev/null
+++ b/bip-0345.mediawiki
@@ -0,0 +1,688 @@
+
+
+
+== Introduction ==
+
+This BIP proposes two new tapscript opcodes that add consensus support for a specialized
+covenant: OP_VAULT and OP_VAULT_RECOVER. These opcodes, in conjunction with
+OP_CHECKTEMPLATEVERIFY
+([https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki BIP-0119]),
+allow users to enforce a delay period before designated coins may be spent to
+an arbitrary destination, with the exception of a prespecified "recovery" path.
+At any time prior to final withdrawal, the coins can be spent to the
+recovery path.
+
+=== Copyright ===
+
+This document is licensed under the 3-clause BSD license.
+
+
+=== Motivation ===
+
+The hazard of custodying Bitcoin is well-known. Users of Bitcoin must go to
+significant effort to secure their private keys, and hope that once provisioned
+their custody system does not yield to any number of evolving and
+persistent threats. Users have little means to intervene once a compromise is
+detected. This proposal introduces a mechanism that significantly
+mitigates the worst-case outcome of key compromise: coin loss.
+
+Introducing a way to intervene during unexpected spends allows users to
+incorporate highly secure key storage methods or unusual fallback strategies
+that are only exercised in the worst case, and which may otherwise be
+operationally prohibitive. The goal of this proposal is to make this strategy
+usable for custodians of any size with minimal complication.
+
+==== Example uses ====
+
+A common configuration for an individual custodying Bitcoin is "single
+signature and passphrase" using a hardware wallet. A user with such a
+configuration might be concerned about the risk associated with relying on a
+single manufacturer for key management, as well as physical access to the
+hardware.
+
+This individual can use OP_VAULT to make use of a highly secure
+key as the unlikely recovery path, while using their existing signing procedure
+as the withdrawal trigger key with a configured spend delay of e.g. 1 day.
+
+The recovery path key can be of a highly secure nature that might otherwise
+make it impractical for daily use. For example, the key could be generated in
+some analog fashion, or on an old computer that is then destroyed, with the
+private key replicated only in paper form. Or the key could be a 2-of-3
+multisig using devices from different manufacturers. Perhaps the key is
+geographically or socially distributed.
+
+Since it can be any Bitcoin script policy, the recovery key can include a
+number of spending conditions, e.g. a time-delayed fallback to an "easier"
+recovery method, in case the highly secure key winds up being ''too'' highly
+secure.
+
+The user can run software on their mobile device that monitors the blockchain
+for spends of the vault outpoints. If the vaulted coins move in an unexpected
+way, the user can immediately sweep them to the recovery path, but spending the
+coins on a daily basis works in the same way it did prior to vaulting (aside
+from the spend delay).
+
+Institutional custodians of Bitcoin may use vaults in similar fashion.
+
+===== Provable timelocks =====
+
+This proposal provides a mitigation to the
+[https://web.archive.org/web/20230210123933/https://xkcd.com/538/ "$5 wrench attack."] By
+setting the spend delay to, say, a week, and using as the recovery path a
+script that enforces a longer relative timelock, the owner of the vault can
+prove that he is unable to access its value immediately. To the author's
+knowledge, this is the only way to configure this defense without rolling
+timelocked coins for perpetuity or relying on a trusted third party.
+
+== Goals ==
+
+[[File:bip-0345/vaults-Basic.png|frame|center]]
+
+Vaults in Bitcoin have been discussed formally since 2016
+([http://fc16.ifca.ai/bitcoin/papers/MES16.pdf MES16]) and informally since [https://web.archive.org/web/20160220215151/https://bitcointalk.org/index.php?topic=511881.0 2014]. The value of
+having a configurable delay period with recovery capability in light of an
+unexpected spend has been widely recognized.
+
+The only way to implement vaults given the existing consensus rules, aside from
+[https://github.com/revault emulating vaults with large multisig
+configurations], is to use presigned transactions created with a one-time-use
+key. This approach was first demonstrated
+[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html in 2020].
+
+Unfortunately, this approach has a number of practical shortcomings:
+* generating and securely deleting ephemeral keys, which are used to emulate the vault covenant, is required,
+* amounts and withdrawal patterns must be precommitted to,
+* there is a necessity to precommit to an address that the funds must pass through on their way to the final withdrawal target, which is likely only known at unvault time,
+* the particular fee management technique or wallet must be decided upon vault creation,
+* coin loss follows if a vault address is reused,
+* the transaction data that represents the "bearer asset" of the vault must be stored for perpetuity, otherwise value is lost, and
+* the vault creation ceremony must be performed each time a new balance is to be deposited.
+
+The deployment of a "precomputed" covenant mechanism like
+[https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki OP_CHECKTEMPLATEVERIFY] or
+[https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki SIGHASH_ANYPREVOUT]
+would both remove the necessity to use an ephemeral key, since the
+covenant is enforced on-chain, and lessen the burden of sensitive data storage,
+since the necessary transactions can be generated from a set of compact
+parameters. This approach was demonstrated [https://github.com/jamesob/simple-ctv-vault in
+2022].
+
+However, the limitations of precomputation still apply: amounts,
+destinations, and fee management are all fixed. Funds must flow through a fixed
+intermediary to their final destination. Batch operations, which may be vital
+for successful recovery during fee spikes or short spend delay, are not possible.
+
+[[File:bip-0345/withdrawal-comparison.drawio.png|frame|center]]
+
+Having a "general" covenant mechanism that can encode arbitrary transactional
+state machines would allow us to solve these issues, but at the cost of complex
+and large scripts that would probably be duplicated many times over in the
+blockchain. The particular design and deployment timeline of such a general
+framework is also uncertain. This approach was demonstrated
+[https://blog.blockstream.com/en-covenants-in-elements-alpha/ in 2016].
+
+This proposal intends to address the problems outlined above by
+providing a delay period/recovery path use with minimal transactional and
+operational overhead using a specialized covenant.
+
+The design goals of the proposal are:
+
+* '''efficient reuse of an existing vault configuration.''''''Why does this support address reuse?''' The proposal doesn't rely on or encourage address reuse, but certain uses are unsafe if address reuse cannot be handled - for example, if a custodian gives its users a vault address to deposit to, it cannot enforce that those users make a single deposit for each address. A single vault configuration, whether the same literal scriptPubKey or not, should be able to “receive” multiple deposits.
+
+* '''batched operations''' for recovery and withdrawal to allow managing multiple vault coins efficiently.
+
+* '''unbounded partial withdrawals''', which allows users to withdraw partial vault balances without having to perform the setup ceremony for a new vault.
+
+* '''dynamic unvault targets''', which allow the proposed withdrawal target for a vault to be specified at withdrawal time rather than when the vault is first created. This would remove the need for a prespecified, intermediate wallet that only exists to route unvaulted funds to their desired destination.
+
+* '''dynamic fee management''' that, like dynamic targets, defers the specification of fee rates and source to unvault time rather than vault creation time.
+
+These goals are accompanied by basic safety considerations (e.g. not being
+vulnerable to mempool pinning) and a desire for concision, both in terms of the number
+of outputs created as well as script sizes.
+
+This proposal is designed to be compatible with any future sighash modes (e.g. SIGHASH_GROUP) or fee management strategies (e.g. [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html transaction sponsors]) that may be introduced. Use of these opcodes will benefit from, but do not strictly rely on, [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html v3 transaction relay] and [https://github.com/instagibbs/bips/blob/ephemeral_anchor/bip-ephemeralanchors.mediawiki ephemeral anchors].
+
+== Design ==
+
+In typical usage, a vault is created by encumbering coins under a
+taptree [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki (BIP-341)]
+containing at least two leaves: one with an OP_VAULT-containing script that
+facilitates the expected withdrawal process, and another leaf with
+OP_VAULT_RECOVER which ensures the coins can be recovered
+at any time prior to withdrawal finalization.
+
+The rules of OP_VAULT ensure the timelocked, interruptible
+withdrawal by allowing a spending transaction to replace the
+OP_VAULT tapleaf with a prespecified script template, allowing for
+some parameters to be set at spend (trigger) time. All other leaves in the
+taptree must be unchanged in the destination output, which preserves the recovery path as well as any
+other spending conditions originally included in the vault. This is similar to
+the TAPLEAF_UPDATE_VERIFY design that was proposed
+[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019419.html in 2021].
+
+These tapleaf replacement rules, described more precisely below, ensure a
+timelocked withdrawal, where the timelock is fixed by the original
+OP_VAULT parameters, to a fixed set of outputs (via
+OP_CHECKTEMPLATEVERIFY'''Why is OP_CHECKTEMPLATEVERIFY (BIP-119) relied upon for this proposal?''' During the withdrawal process, the proposed final destination for value being withdrawn must be committed to. OP_CTV is the simplest, safest way to commit the spend of some coins to a particular set of outputs. An earlier version of this proposal attempted to use a simpler, but similar method, of locking the spend of coins to a set of outputs, but this method introduced txid malleability. Note that if some other method of locking spends to a particular set of outputs should be deployed, that method can be used in the OP_VAULT with no changes.) which is chosen when the withdrawal
+process is triggered.
+
+While OP_CHECKTEMPLATEVERIFY is used in this proposal as the
+preferred method to bind the proposed withdrawal to a particular set of final
+outputs, OP_VAULT is composable with other (and future) opcodes to
+facilitate other kinds of withdrawal processes.
+
+[[File:bip-0345/opvault.drawio.png|frame|center]]
+
+
+=== Transaction types ===
+
+The vault has a number of stages, some of them optional:
+
+* '''vault transaction''': encumbers some coins into a Taproot structure that includes at least one OP_VAULT leaf and one OP_VAULT_RECOVER leaf.
+
+* '''trigger transaction''': spends one or more OP_VAULT-tapleaf inputs into an output which is encumbered by a timelocked withdrawal to a fixed set of outputs, chosen at trigger time. This publicly broadcasts the intent to withdraw to some specific set of outputs.
The trigger transaction may have an additional output which allocates some of the vault balance into a partial "revault," which simply encumbers the revaulted portion of the value into the same scriptPubKey as the OP_VAULT-containing input(s) being spent.
+
+* '''withdrawal transaction''': spends the timelocked, destination-locked trigger inputs into a compatible set of final withdrawal outputs (per, e.g., a CHECKTEMPLATEVERIFY hash), after the trigger inputs have matured per the spend delay. Timelocked CTV transactions are the motivating usage of OP_VAULT, but any script template can be specified during the creation of the vault.
+
+* '''recovery transaction''': spends one or more vault inputs via OP_VAULT_RECOVER tapleaf to the prespecified recovery path, which can be done at any point before the withdrawal transaction confirms. Each input can optionally require a witness satisfying a specified ''recovery authorization'' script, an optional script prefixing the OP_VAULT_RECOVER fragment. The use of recovery authorization has certain trade-offs discussed later.
+
+
+=== Fee management ===
+
+A primary consideration of this proposal is how fee management is handled.
+Providing dynamic fee management is critical to the operation of a vault, since
+
+* precalculated fees are prone to making transactions unconfirmable in high fee environments, and
+* a fee wallet that is prespecified might be compromised or lost before use.
+
+But dynamic fee management can introduce
+[https://bitcoinops.org/en/topics/transaction-pinning/ pinning vectors]. Care
+has been taken to avoid unnecessarily introducing these vectors when using the new
+destination-based spending policies that this proposal introduces.
+
+Originally, this proposal had a hard dependency on reformed transaction
+nVersion=3 policies, including ephemeral anchors, but it has since been revised
+to simply benefit from these changes in policy as well as other potential fee
+management mechanisms.
+
+
+== Specification ==
+
+The tapscript opcodes OP_SUCCESS187 (0xbb) and
+OP_SUCCESS188 (0xbc) are constrained with new rules
+to implement OP_VAULT and OP_VAULT_RECOVER,
+respectively.
+
+=== OP_VAULT evaluation ===
+
+When evaluating OP_VAULT (OP_SUCCESS187,
+0xbb), the expected format of the stack, shown top to bottom, is:
+
+
+
+
+[ leaf-update script data items ... ]
+
+
+
+
+
+where
+
+* is a minimally-encoded data push of a serialized script. In conjunction with the leaf-update data items, it dictates the tapleaf script in the output taptree that will replace the one currently executing.
+** Otherwise, script execution MUST fail and terminate immediately.
+
+* is an up to 4-byte minimally encoded CScriptNum indicating how many leaf-update script items should be popped off the stack. '''Why only prefix with data pushes?''' Prefixing the leaf-update-script-body with opcodes opens up the door to prefix OP_SUCCESSX opcodes, to name a single issue only, side-stepping the validation that was meant to be run by the committed script.
+** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately.
+** If this value is less than 0, script execution MUST fail and terminate immediately.
+** If there are fewer than 3 items following the items on the stack, script execution MUST fail and terminate immediately. In other words, after popping , there must be at least 3 + items remaining on the stack.
+
+* The following stack items are popped off the stack and prefixed as minimally-encoded push-data arguments to the to construct the expected tapleaf replacement script.
+
+* is an up to 4-byte minimally encoded CScriptNum indicating the index of the output which, in conjunction with an optional revault output, carries forward the value of this input, and has an identical taptree aside from the currently executing leaf.
+** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately.
+** If this value is less than 0 or is greater than or equal to the number of outputs, script execution MUST fail and terminate immediately.
+
+* is an up to 4-byte minimally encoded CScriptNum optionally indicating the index of an output which, in conjunction with the trigger output, carries forward the value of this input, and has an identical scriptPubKey to the current input.
+** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately.
+** If this value is greater than or equal to the number of outputs, script execution MUST fail and terminate immediately.
+** If this value is negative and not equal to -1, script execution MUST fail and terminate immediately.'''Why is -1 the only allowable negative value for revault-vout-idx?''' A negative revault index indicates that no revault output exists; if this value were allowed to be any negative number, the witness could be malleated (and bloated) while a transaction is waiting for confirmation.
+
+* is an up to 7-byte minimally encoded CScriptNum indicating the number of satoshis being revaulted.
+** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately.
+** If this value is not greater than or equal to 0, script execution MUST fail and terminate immediately.
+** If this value is non-zero but is negative, script execution MUST fail and terminate immediately.
+** If this value is zero but is not -1, script execution MUST fail and terminate immediately.
+
+After the stack is parsed, the following validation checks are performed:
+
+* Decrement the per-script sigops budget (see [https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#user-content-Resource_limits BIP-0342]) by 60'''Why is the sigops cost for OP_VAULT set to 60?''' To determine the validity of a trigger output, OP_VAULT must perform an EC multiplication and hashing proportional to the length of the control block in order to generate the output's expected TapTweak. This has been measured to have a cost in the worst case (max length control block) of roughly twice a Schnorr verification. Because the hashing cost could be mitigated by caching midstate, the cost is 60 and not 100.; if the budget is brought below zero, script execution MUST fail and terminate immediately.
+* Let the output designated by be called ''triggerOut''.
+* If the scriptPubKey of ''triggerOut'' is not a version 1 witness program, script execution MUST fail and terminate immediately.
+* Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''.
+* If the scriptPubKey of ''triggerOut'' does not match that of a taptree that is identical to that of the currently evaluated input, but with the leaf script substituted for ''leaf-update-script'', script execution MUST fail and terminate immediately.
+** Note: the parity bit of the resulting taproot output is allowed to vary, so both values for the new output must be checked.
+* Let the output designated by (if the index value is non-negative) be called ''revaultOut''.
+* If the scriptPubKey of ''revaultOut'' is not equal to the scriptPubKey of the input being spent, script execution MUST fail and terminate immediately.
+* Implementation recommendation: if the sum of the amounts of ''triggerOut'' and ''revaultOut'' (if any) are not greater than or equal to the value of this input, script execution SHOULD fail and terminate immediately. This ensures that (at a minimum) the vaulted value for this input is carried through.
+** Amount checks are ultimately done with deferred checks, but this check can help short-circuit obviously invalid spends.
+* Queue a deferred check'''What is a deferred check and why does this proposal require them for correct script evaluation?''' A deferred check is a validation check that is executed only after all input scripts have been validated, and is based on aggregate information collected during each input's EvalScript run.
Currently, the validity of each input is (usually) checked concurrently across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation. that ensures the satoshis for this input's nValue minus are included within the output nValue found at .
+* Queue a deferred check that ensures satoshis, if non-zero, are included within the output's nValue found at .
+** These deferred checks could be characterized in terms of the pseudocode below (in ''Deferred checks'') as TriggerCheck(input_amount, , , ).
+
+If none of the conditions fail, a single true value (0x01) is left on the stack.
+
+=== OP_VAULT_RECOVER evaluation ===
+
+When evaluating OP_VAULT_RECOVER (OP_SUCCESS188,
+0xbc), the expected format of the stack, shown top to bottom, is:
+
+
+
+
+
+
+where
+
+* is a 32-byte data push.
+** If this is not 32 bytes in length, script execution MUST fail and terminate immediately.
+* is an up to 4-byte minimally encoded CScriptNum indicating the index of the recovery output.
+** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately.
+** If this value is less than 0 or is greater than or equal to the number of outputs, script execution MUST fail and terminate immediately.
+
+After the stack is parsed, the following validation checks are performed:
+
+* Let the output at index be called ''recoveryOut''.
+* If the scriptPubKey of ''recoveryOut'' does not have a tagged hash equal to (tagged_hash("VaultRecoverySPK", recoveryOut.scriptPubKey) == recovery-sPK-hash, where tagged_hash() is from the [https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py BIP-0340 reference code]), script execution MUST fail and terminate immediately.
+** Implementation recommendation: if ''recoveryOut'' does not have an nValue greater than or equal to this input's amount, the script SHOULD fail and terminate immediately.
+* Queue a deferred check that ensures the nValue of ''recoveryOut'' contains the entire nValue of this input.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor.
+** This deferred check could be characterized in terms of the pseudocode below as RecoveryCheck(, input_amount).
+
+If none of the conditions fail, a single true value (0x01) is left on the stack.
+
+=== Deferred check evaluation ===
+
+Once all inputs for a transaction are validated per the rules above, any
+deferred checks queued MUST be evaluated.
+
+The Python pseudocode for this is as follows:
+
+
+class TriggerCheck:
+ """Queued by evaluation of OP_VAULT (withdrawal trigger)."""
+ input_amount: int
+ revault_amount: int
+ trigger_vout_idx: int
+ revault_vout_idx: int
+
+
+class RecoveryCheck:
+ """Queued by evaluation of OP_VAULT_RECOVER."""
+ input_amount: int
+ vout_idx: int
+
+
+def validate_deferred_checks(checks: [DeferredCheck], tx: Transaction) -> bool:
+ """
+ Ensure that all value from vault inputs being triggered or recovered is preserved
+ in suitable output nValues.
+ """
+ # Map to hold expected output values.
+ out_map: Dict[int, int] = defaultdict(lambda: 0)
+
+ for c in checks:
+ if isinstance(c, TriggerCheck):
+ out_map[c.trigger_vout_idx] += (c.input_amount - c.revault_amount)
+
+ if c.revault_amount > 0:
+ out_map[c.revault_vout_idx] += c.revault_amount
+
+ elif isinstance(c, RecoveryCheck):
+ out_map[c.vout_idx] += c.input_amount
+
+ for (vout_idx, amount_sats) in out_map.items():
+ # Trigger/recovery value can be greater than the constituent vault input
+ # amounts.
+ if tx.vout[vout_idx].nValue < amount_sats:
+ return False
+
+ return True
+
+
+If the above procedure, or an equivalent, returns false, script execution MUST fail and terminate
+immediately.
+
+This ensures that all compatible vault inputs can be batched into shared
+corresponding trigger or recovery outputs while preserving their entire input value.
+
+
+== Policy changes ==
+
+In order to prevent possible pinning attacks, recovery transactions must be replaceable.
+
+* When validating an OP_VAULT_RECOVER input being spent, the script MUST fail (by policy, not consensus) and terminate immediately if both'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process.
+*# the input is not marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], and
+*# the version of the recovery transaction has an nVersion other than 3.
+
+If the script containing OP_VAULT_RECOVER is 34 bytes or less34 bytes is the length of a recovery script that consists solely of OP_VAULT_RECOVER., let
+it be called "unauthorized," because there is no script guarding the recovery
+process. In order to prevent pinning attacks in the case of unauthorized
+recovery - since the spend of the input (and the structure of the
+transaction) is not authorized by a signed signature message - the output structure of
+unauthorized recovery transaction is limited.
+
+* If the recovery is unauthorized, the recovery transaction MUST (by policy) abide by the following constraints:
+** If the spending transaction has more than two outputs, the script MUST fail and terminate immediately.
+** If the spending transaction has two outputs, and the output which is not ''recoveryOut'' is not an [https://github.com/instagibbs/bips/blob/ephemeral_anchor/bip-ephemeralanchors.mediawiki ephemeral anchor], the script MUST fail and terminate immediately.'''Why can unauthorized recoveries only process a single recovery path?''' Because there is no signature required for unauthorized recoveries, if additional outputs were allowed, someone observing a recovery in the mempool would be able to rebundle and broadcast the recovery with a lower fee rate.
+
+== Implementation ==
+
+A sample implementation is available on bitcoin-inquisition [https://github.com/jamesob/bitcoin/tree/2023-01-opvault-inq here], with an associated [https://github.com/bitcoin-inquisition/bitcoin/pull/21 pull request].
+
+
+== Applications ==
+
+The specification above, perhaps surprisingly, does not specifically cover how a relative timelocked withdrawal process with a fixed target is implemented. The tapleaf update semantics specified in OP_VAULT as well as the output-based authorization enabled by OP_VAULT_RECOVER can be used to implement a vault, but they are incomplete without two other pieces:
+
+* a way to enforce relative timelocks, like OP_CHECKSEQUENCEVERIFY, and
+* a way to enforce that proposed withdrawals are ultimately being spent to a precise set of outputs, like OP_CHECKTEMPLATEVERIFY.
+
+These two pieces are combined with the tapleaf update capabilities of
+OP_VAULT to create a vault, described below.
+
+=== Creating a vault ===
+
+In order to vault coins, they can be spent into a witness v1 scriptPubKey
+that contains a taptree of the form
+
+
+tr(,
+ leaves = {
+ recover:
+ OP_VAULT_RECOVER,
+
+ trigger:
+ OP_CHECKSIGVERIFY (i)
+ 2 $leaf-update-script-body OP_VAULT, (ii)
+
+ ... [ possibly other leaves ]
+ }
+)
+
+where
+* $leaf-update-script-body is, for example, OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKTEMPLATEVERIFY.
+** This is one example of a trigger script, but ''any'' script fragment can be used, allowing the creation of different types of vaults. For example, you could use OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKSIG to do a time-delayed transfer of the coins to another key. This also future-proofs OP_VAULT for future scripting capabilities.
+* The script fragment in (i) is called the "trigger authorization," because it gates triggering the withdrawal. This can be done in whatever manner the wallet designer would like.
+* The script fragment in (ii) is the incomplete OP_VAULT invocation - it will be completed once the rest of the parameters (the CTV target hash, trigger vout index, and revault vout index) are provided by the trigger transaction witness.
+
+Typically, the internal key for the vault taproot output will be specified so
+that it is controlled by the same descriptor as the recovery path, which
+facilitates another (though probably unused) means of recovering the vault
+output to the recovery path. This has the potential advantage of recovering the
+coin without ever revealing it was a vault.
+
+Otherwise, the internal key can be chosen to be an unspendable NUMS point to
+force execution of the taptree contents.
+
+=== Triggering a withdrawal ===
+
+To make use of the vault, and spend it towards some output, we construct a spend
+of the above tr() output that simply replaces the "trigger" leaf with the
+full leaf-update script (in this case, a timelocked CTV script):
+
+
+Witness stack:
+
+-
+- (-1 if none)
+-
+-
+-
+- [ "trigger" leaf script contents ]
+- [ taproot control block prompting a script-path spend to "trigger" leaf ]
+
+Output scripts:
+
+[
+ tr(,
+ leaves = {
+ recover:
+ OP_VAULT_RECOVER, <-- unchanged
+
+ trigger:
+
+ OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKTEMPLATEVERIFY <-- changed per the
+ leaf-update
+ rules of OP_VAULT
+ ... [ possibly other leaves ]
+ }
+ ),
+
+ [ optional revault output with the
+ same sPK as the original vault output ],
+]
+
+
+OP_VAULT has allowed the taptree to be transformed so that the trigger leaf
+becomes a timelocked CTV script, which is what actually facilitates the announced
+withdrawal. The withdrawal is interruptible by the recovery path because the
+"recover" leaf is preserved exactly from the original taptree.
+
+Note that the CTV hash is specified at spend time using the witness stack, and
+"locked in" via the OP_VAULT spend rules which assert its existence in the output.
+
+The vault funds can be recovered at any time prior to the spend of the
+timelocked CTV script by way of a script-path spend using the "recover" leaf.
+
+
+=== Recovery authorization ===
+
+When configuring a vault, the user must decide if they want to have the
+recovery process gated by a script fragment prefixing the
+OP_VAULT_RECOVER instruction in the "recover" leaf. Its use
+entails trade-offs.
+
+==== Unauthorized recovery ====
+
+Unauthorized recovery simplifies vault use in that recovery never requires additional information aside from the location of the vault outpoints and the recovery path - the "authorization" is simply the reveal of the recovery path, i.e. the preimage of .
+
+But because this reveal is the only authorization necessary to spend the vault coins to recovery, the user must expect to recover all such vaults at once, since an observer can replay this recovery (provided they know the outpoints).
+
+Additionally, unauthorized recovery across multiple distinct recovery paths
+cannot be done in the same transaction, and fee control is more constrained:
+because the output structure is limited for unauthorized recovery, fee
+management relies either on inputs which are completely spent to fees or the
+use of the optional ephemeral anchor and package relay.
+
+These limitations are to avoid pinning attacks.
+
+==== Authorized recovery ====
+
+With authorized recovery, the user must keep track of an additional piece of information: how to solve the recovery authorization script fragment when recovery is required.
+
+If this key is lost, the user will be unable to initiate the recovery process for their coins. If an attacker obtains the recovery key, they may grief the user during the recovery process by constructing a low fee rate recovery transaction and broadcasting it (though they will not be able to pin because of the replaceability requirement on recovery transactions).
+
+However, authorized recovery configurations have significant benefits. Batched recoveries are possible for vaults with otherwise incompatible recovery parameters. Fee management is much more flexible, since authorized recovery transactions are "free form" and unrelated inputs and outputs can be added, potentially to handle fees.
+
+==== Recommendation: use a simple, offline recovery authorization key seed ====
+
+The benefits of batching and fee management that authorized recovery provides are significant. If the recovery authorization key falls into the hands of an attacker, the outcome is not catastrophic, whereas if the user loses their recovery authorization key as well as their trigger key, the result is likely coin loss. Consequently, the author's recommendation is to use a simple seed for the recovery authorization key that can be written down offline and replicated.
+
+Note that the recovery authorization key '''is not''' the recovery path key, and
+this is '''much different''' than any recommendation on how to generate the
+recovery path key itself.
+
+=== Address reuse and recovery ===
+
+When creating a vault, four factors affect the resulting P2TR address:
+# The internal pubkey (likely belonging to the recovery wallet)
+# The recovery leaf
+# The trigger leaf
+# Any other leaves that exist in the taptree
+
+The end user has the option of varying certain contents along descriptors in
+order to avoid reusing vault addresses without affecting key management, e.g.
+the trigger authorization pubkeys.
+
+Note that when using unauthorized recovery, the reveal of the
+recovery scriptPubKey will allow any observer to initiate the recovery process
+for any vault with matching recovery params, provided they are able to locate
+the vault outpoints. As a result, it is recommended to expect that
+'''all outputs sharing an identical unauthorized should be recovered together'''.
+
+This situation can be avoided with a comparable key management model by varying
+the generation of each vault's recovery scriptPubKey along a single descriptor,
+but note that this will prevent recovering multiple separate vaults into a single
+recovery output.
+
+Varying the internal pubkey will prevent batching the trigger of multiple vault
+inputs into a single trigger output; consequently it is recommended that users
+instead vary some component of the trigger leaf script if address reuse is
+undesirable. Users could vary the trigger pubkey along a descriptor, keeping
+the recovery path and internal-pubkey the same, which both avoids reusing
+addresses and allows batched trigger and recovery operations.
+
+==== Recommendation: generate new recovery addresses for new trigger keys ====
+
+If using unauthorized recovery, it is recommended that you do not share recovery scriptPubKeys
+across separate trigger keys. If one trigger key is compromised, that will necessitate the (unauthorized)
+recovery of all vaults with that trigger key, which will reveal the recovery path preimage. This
+means that an observer might be able to initiate recovery for vaults controlled by an uncompromised
+trigger key.
+
+==== Fee management ====
+
+Fees can be managed in a variety of ways, but it's worth noting that both
+trigger and recovery transactions must preserve the total value of vault
+inputs, so vaulted values cannot be repurposed to pay for fees. This does not
+apply to the withdrawal transaction, which can allocate value arbitrarily.
+
+In the case of vaults that use recovery authorization, all transactions can
+"bring their own fees" in the form of unrelated inputs and outputs. These
+transactions are also free to specify ephemeral anchors, once the related relay
+policies are deployed. This means that vaults using recovery authorization have
+no dependence on the deploy of v3 relay policy.
+
+For vaults using unauthorized recovery, the recovery
+transaction relies on the use of either fully-spent fee inputs or an ephemeral
+anchor output. This means that vaults which do not use recovery authorization
+are essentially dependent on v3 transaction relay policy being deployed.
+
+=== Batching ===
+
+==== During trigger ====
+
+OP_VAULT outputs with the same taptree, aside from slightly
+different trigger leaves, can be batched together in the same withdrawal
+process. Two "trigger" leaves are compatible if they have the same
+OP_VAULT arguments.
+
+Note that this allows the trigger authorization -- the script prefixing the
+OP_VAULT invocation -- to differ while still allowing batching.
+
+Trigger transactions can act on multiple incompatible OP_VAULT
+input sets, provided each set has a suitable associated ''triggerOut''
+output.
+
+Since SIGHASH_DEFAULT can be used to sign the trigger
+authorization, unrelated inputs and outputs can be included, possibly to
+facilitate fee management or the batch withdrawal of incompatible vaults.
+
+==== During withdrawal ====
+
+During final withdrawal, multiple trigger outputs can be used towards the same
+withdrawal transaction provided that they share identical
+ parameters. This facilitates batched
+withdrawals.
+
+==== During recovery ====
+
+OP_VAULT_RECOVER outputs with the same
+can be recovered into the same output.
+
+Recovery-incompatible vaults which have authorized recovery can be recovered in
+the same transaction, so long as each set (grouped by
+) has an associated ''recoveryOut''. This allows
+unrelated recoveries to share common fee management.
+
+=== Watchtowers ===
+
+The value of vaults is contingent upon having monitoring in place that will
+alert the owner when unexpected spends are taking place. This can be done in a
+variety of ways, with varying degrees of automation and trust in the
+watchtower.
+
+In the maximum-trust case, the watchtower can be fully aware of all vaulted
+coins and has the means to initiate the recovery process if spends are not
+pre-reported to the watchtower.
+
+In the minimum-trust case, the user can supply a probabilistic filter of which
+coins they wish to monitor; the watchtower would then alert the user if any
+coins matching the filter move, and the user would be responsible for ignoring
+false positives and handling recovery initiation.
+
+=== Output descriptors ===
+
+Output descriptors for vault-related outputs will be covered in a subsequent BIP.
+
+== Deployment ==
+
+Activation mechanism is to be determined.
+
+This BIP should be deployed concurrently with BIP-0119 to enable full use of vaults.
+
+== Backwards compatibility ==
+
+OP_VAULT and OP_VAULT_RECOVER replace, respectively,
+the witness v1-only opcodes OP_SUCCESS187 and OP_SUCCESS188 with stricter
+verification semantics. Consequently, scripts using those opcodes which
+previously were valid will cease to be valid with this change.
+
+Stricter verification semantics for an OP_SUCCESSx opcode are a soft fork, so
+existing software will be fully functional without upgrade except for mining
+and block validation.
+
+Backwards compatibility considerations are very comparable to previous
+deployments for OP_CHECKSEQUENCEVERIFY and OP_CHECKLOCKTIMEVERIFY (see
+[https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP-0065] and
+[https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP-0112]).
+
+
+== Rationale ==
+
+
+
+== References ==
+
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-February/012470.html [bitcoin-dev] Bitcoin Vaults (2016)]
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-February/015793.html [bitcoin-dev] Simple lock/unlock mechanism (2018)]
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html [bitcoin-dev] On-chain vaults prototype (2020)]
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019419.html [bitcoin-dev] TAPLEAF_UPDATE_VERIFY covenant opcode (2021)]
+* [https://arxiv.org/abs/2005.11776 Custody Protocols Using Bitcoin Vaults (2020)]
+* [https://jameso.be/vaults.pdf Vaults and Covenants (2023)]
+
+== Acknowledgements ==
+
+The author would like to thank
+
+* AJ Towns and Greg Sanders for discussion, numerous suggestions that improved the proposal, and advice.
+* Jeremy Rubin for inspiration, advice, and mentorship.
+* BL for discussion and insight.
+* John Moffett for early feedback and a test case demonstrating a recursive script evaluation attack.
+* Johan Halseth for providing conceptual review and pointing out a pinning attack.
+* Pieter Wuille for implementation advice.
diff --git a/bip-0345/opvault.drawio.png b/bip-0345/opvault.drawio.png
new file mode 100644
index 0000000000..702189d156
Binary files /dev/null and b/bip-0345/opvault.drawio.png differ
diff --git a/bip-0345/vaults-Basic.png b/bip-0345/vaults-Basic.png
new file mode 100644
index 0000000000..591b633dad
Binary files /dev/null and b/bip-0345/vaults-Basic.png differ
diff --git a/bip-0345/vaults.drawio b/bip-0345/vaults.drawio
new file mode 100644
index 0000000000..6f7fd4ebc2
--- /dev/null
+++ b/bip-0345/vaults.drawio
@@ -0,0 +1,1113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bip-0345/withdrawal-comparison.drawio.png b/bip-0345/withdrawal-comparison.drawio.png
new file mode 100644
index 0000000000..8a76d20722
Binary files /dev/null and b/bip-0345/withdrawal-comparison.drawio.png differ
diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki
new file mode 100644
index 0000000000..0aed70db49
--- /dev/null
+++ b/bip-0347.mediawiki
@@ -0,0 +1,113 @@
+
+
+==Abstract==
+
+This BIP introduces OP_CAT as a tapscript opcode which allows the concatenation of two values on the stack. OP_CAT would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (126 in decimal and 0x7e in hexadecimal). This is the same opcode value used by the original OP_CAT.
+
+== Copyright ==
+
+This document is licensed under the 3-clause BSD license.
+
+==Specification==
+
+When evaluated, the OP_CAT instruction:
+# Pops the top two values off the stack,
+# concatenates the popped values together in stack order,
+# and then pushes the concatenated value on the top of the stack.
+
+Given the stack ''[x1, x2]'', where ''x2'' is at the top of the stack, OP_CAT will push ''x1 || x2'' onto the stack. By ''||'' we denote concatenation. OP_CAT fails if there are fewer than two values on the stack or if a concatenated value would have a combined size greater than the maximum script element size of 520 bytes.
+
+This opcode would be activated via a soft fork by redefining the tapscript opcode OP_SUCCESS126 (126 in decimal and 0x7e in hexadecimal) to OP_CAT.
+
+==Motivation==
+
+Bitcoin Tapscript lacks a general purpose way of combining objects on the stack, restricting the expressiveness and power of Tapscript. This prevents, among many other things, the ability to construct and evaluate merkle trees and other hashed data structures in Tapscript. OP_CAT, by adding a general purpose way to concatenate stack values, would overcome this limitation and greatly increase the functionality of Tapscript.
+
+OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modular, and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable:
+
+* Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT, they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf
+* Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with up to 4,294,967,296 public keys. This also enables generalized logical spend conditions. P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/
+* Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It has been proposed that if ECDSA is broken or a powerful computer was on the horizon, there might be an effort to protect ownership of bitcoins by allowing people to mark their taproot outputs as "script-path only" and then move their coins into such outputs with a leaf in the script tree requiring a Lamport signature. It is an open question if a tapscript commitment would preserve the quantum resistance of Lamport signatures. Beyond this question, the use of Lamport Signatures in taproot outputs is unlikely to be quantum resistant even if the script spend-path is made quantum resistant. This is because taproot outputs can also be spent with a key. An attacker with a sufficiently powerful quantum computer could bypass the taproot script spend-path by finding the discrete log of the taproot output and thus spending the output using the key spend-path. The use of "Nothing Up My Sleeve" (NUMS) points as described in [[bip-0341.mediawiki|BIP341]] to disable the key spend-path does not disable the key spend-path against a quantum attacker as NUMS relies on the hardness of finding discrete logs. We are not aware of any mechanism which could disable the key spend-path in a taproot output without a softfork change to taproot.
+* Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://web.archive.org/web/20221023121048/https://publications.cispa.saarland/565/1/penalizing.pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols.
+* Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin.
+* Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-i.html which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md.
+
+OP_CAT was available in early versions of Bitcoin.
+In 2010, a single commit disabled OP_CAT, along with another 15 opcodes.
+Folklore states that OP_CAT was removed in this commit because it enabled the construction of a script whose evaluation could have memory usage exponential in the size of the script.
+For example, a script that pushed a 1-byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack element whose size was greater than 1 terabyte assuming no maximum stack element size. As Bitcoin at that time had a maximum stack element size of 5000 bytes, the effect of this expansion was limited to 5000 bytes.
+This is no longer an issue because tapscript enforces a maximum stack element size of 520 bytes.
+
+
+==Rationale==
+
+Our decision to reenable OP_CAT by redefining a tapscript OP_SUCCESSx opcode to OP_CAT was motivated to leverage the tapscript softfork opcode upgrade path introduced in [[bip-0342.mediawiki|BIP342]].
+
+We specifically choose to use OP_SUCCESS126 rather than another OP_SUCCESSx as OP_SUCCESS126 uses the same opcode value (126 in decimal and 0x7e in hexadecimal) that was used for OP_CAT prior to it being disabled in Bitcoin. This removes a potential source of confusion that would exist if we had a opcode value different from the one used in the original OP_CAT opcode.
+
+While the OP_SUCCESSx opcode upgrade path could enable us to increase the stack element size while reenabling OP_CAT, we wanted to separate the decision to change the stack element size limit from the decision to reenable OP_CAT. This BIP takes no position in favor or against increasing the stack element size limit.
+
+==Backwards Compatibility==
+
+OP_CAT usage in a non-tapscript script will continue to trigger the SCRIPT_ERR_DISABLED_OPCODE. The only change would be to OP_CAT usage in tapscript. This change to tapscript would be activated as a soft fork that redefines an OP_SUCCESSx opcode (OP_SUCCESS126) to OP_CAT.
+
+==Reference implementation==
+
+
+
+
+The value of MAX_SCRIPT_ELEMENT_SIZE is 520.
+
+This implementation is inspired by the original implementation of [https://github.com/bitcoin/bitcoin/blob/01cd2fdaf3ac6071304ceb80fb7436ac02b1059e/script.cpp#L381-L393 OP_CAT as it existed in the Bitcoin codebase] prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefR94 which disabled it:
+
+
+
+An alternative implementation of OP_CAT can be found in Elements Roose S., Elements Project, "Re-enable several disabled opcodes", 2019, https://github.com/ElementsProject/elements/commit/13e1103abe3e328c5a4e2039b51a546f8be6c60a#diff-a0337ffd7259e8c7c9a7786d6dbd420c80abfa1afdb34ebae3261109d9ae3c19R740-R759.
+
+==References==
+
+
+
+==Acknowledgements==
+
+We wish to acknowledge Dan Gould for encouraging and helping review this effort. We also want to thank Madars Virza, Jeremy Rubin, Andrew Poelstra, Bob Summerwill,
+Tim Ruffing and Johan T. Halseth for their feedback, review and helpful comments.
diff --git a/bip-0348.md b/bip-0348.md
new file mode 100644
index 0000000000..54ac31c8db
--- /dev/null
+++ b/bip-0348.md
@@ -0,0 +1,140 @@
+```
+ BIP: 348
+ Layer: Consensus (soft fork)
+ Title: CHECKSIGFROMSTACK
+ Author: Brandon Black
+ Jeremy Rubin
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0348
+ Status: Draft
+ Type: Standards Track
+ Created: 2024-11-26
+ License: BSD-3-Clause
+```
+
+## Abstract
+
+This BIP describes a new opcode for the purpose of checking cryptographic
+signatures in bitcoin scripts against data from the stack.
+
+## Summary
+
+When verifying taproot script spends having leaf version 0xc0 (as defined in
+[BIP 342]), we propose `OP_CHECKSIGFROMSTACK` to replace `OP_SUCCESS204`
+(0xcc).
+
+`OP_CHECKSIGFROMSTACK` has semantics similar to `OP_CHECKSIG`, as specified
+below. Briefly, it pops 3 elements from the stack: a 32-byte public key, a
+message, and a signature. If the signature is valid for that public key and
+message, 1 is pushed to the stack. If the signature is the empty vector, 0 is
+pushed to the stack, and otherwise script execution fails.
+
+Only 32-byte keys are constrained. Similar to [BIP 342] unknown key types, for
+other key lengths no signature verification is performed and it is considered
+successful.
+
+## Specification
+
+* If fewer than 3 elements are on the stack, the script MUST fail and terminate immediately.
+* The public key (top element), message (second to top element), and signature (third from top element) are read from the stack.
+* The top three elements are popped from the stack.
+* If the public key size is zero, the script MUST fail and terminate immediately.
+* If the public key size is 32 bytes, it is considered to be a public key as described in [BIP 340]:
+ * If the signature is not the empty vector, the signature is validated against the public key and message according to [BIP 340]. Validation failure in this case immediately terminates script execution with failure.
+* If the public key size is not zero and not 32 bytes; the public key is of an unknown public key type. Signature verification for unknown public key types succeeds as if signature verification for a known public key type had succeeded.
+* If the script did not fail and terminate before this step, regardless of the public key type:
+ * If the signature is the empty vector: An empty vector is pushed onto the stack, and execution continues with the next opcode.
+ * If the signature is not the empty vector:
+ * The opcode is counted towards the sigops budget as described in [BIP 342].
+ * A 1-byte value 0x01 is pushed onto the stack.
+
+## Design Considerations
+
+1. Message hashing: [BIP 340] is compatible with any size of message and does not require it to be a securely hashed input, so the message is not hashed prior to [BIP 340] verification.
+2. Lack of verify semantics: Adding a single opcode for this purpose keeps the implementation and design simple. An earlier draft had a verify variant as a NOP upgrade, and if this functionality is later brought to legacy scripts, that would be a good time to add a verify variant.
+3. Add/multisig: No concession is made to `OP_CHECKMULTISIG` or `OP_CHECKSIGADD` semantics with `OP_CHECKSIGFROMSTACK`. In Tapscript, add semantics can be implemented with 1 additional vByte per key (`OP_TOALTSTACK OP_CHECKSIGFROMSTACK OP_FROMALTSTACK OP_ADD`).
+4. Splitting R/S on the stack: Implementing split/separate signatures is left as an exercise for other bitcoin upgrades, such as [BIP 347] (`OP_CAT`).
+5. APO-style ([BIP 118]) Taproot internal key: Rather than introducing an additional key type in this change, we suggest implementing `OP_INTERNALKEY` ([BIP 349]) or separately introducing that key type for all Tapscript signature checking operations in a separate change.
+
+## Resource Limits
+
+These opcodes are treated identically to other signature checking opcodes and
+count against the sigops and budget.
+
+## Motivation
+
+### LN Symmetry
+
+When combined with [BIP 119] (`OP_CHECKTEMPLATEVERIFY`/CTV),
+`OP_CHECKSIGFROMSTACK` (CSFS) can be used to implement Lightning Symmetry
+channels. The construction `OP_CHECKTEMPLATEVERIFY
+OP_CHECKSIGFROMSTACK` with a spend stack containing the CTV hash and a
+signature for it is logically equivalent to ` OP_CHECKSIG` and
+a signature over `SIGHASH_ALL|SIGHASH_ANYPREVOUTANYSCRIPT`. The
+`OP_CHECKSIGFROMSTACK` construction is 8 vBytes larger.
+
+Summary of alternatives:
+* CTV+CSFS is the minimal functionality needed for Lightning Symmetry but requires the use of an `OP_RETURN` for data availability
+* APO is the original design for Lightning Symmetry and uses the taproot annex for data availability.
+* LNHANCE (CTV+CSFS+IKEY+PC) is the most efficient and direct way currently designed to implement Lightning Symmetry.
+
+### Delegation
+
+Using a script like:
+` SWAP IF 2 PICK SWAP CSFS VERIFY ENDIF CHECKSIG`
+either direct verification or delegation can be achieved by the following
+unlock stacks: ` 0` or ` 1`
+
+### Advanced delegation when combined with [OP_PAIRCOMMIT] or OP_CAT
+
+Using a script like:
+`CLTV OVER PAIRCOMMIT TOALT CHECKSIGVERIFY FROMALT CSFS`
+or:
+`CLTV SHA256 OVER CAT TOALT CHECKSIGVERIFY FROMALT CSFS`
+with the unlock stack:
+``
+
+Delegates to a public key after a lock time, enabling delegation to various
+keys after various associated times.
+
+## Reference Implementation
+
+A reference implementation is provided here:
+
+https://github.com/bitcoin/bitcoin/pull/29270
+
+## Backward Compatibility
+
+By constraining the behavior of an OP_SUCCESS opcode,
+deployment of the BIP can be done in a backwards compatible, soft-fork manner.
+If anyone were to rely on the OP_SUCCESS behavior of
+`OP_SUCCESS204`, `OP_CHECKSIGFROMSTACK` would invalidate
+their spend.
+
+## Deployment
+
+TBD
+
+## Credits
+
+Reference implementation was made with reference to the implementation in
+Elements and started by moonsettler.
+
+## Copyright
+
+This document is licensed under the 3-clause BSD license.
+
+[BIP 119]: https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki
+
+[BIP 118]: https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki
+
+[BIP 340]: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
+
+[BIP 342]: https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki
+
+[BIP 349]: https://github.com/bitcoin/bips/blob/master/bip-0349.md
+
+[BIP 347]: https://github.com/bitcoin/bips/blob/master/bip-0347.mediawiki
+
+[OP_PAIRCOMMIT]: https://github.com/bitcoin/bips/pull/1699
+
+[mailing list]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019192.html
diff --git a/bip-0349.md b/bip-0349.md
new file mode 100644
index 0000000000..afd111a9c1
--- /dev/null
+++ b/bip-0349.md
@@ -0,0 +1,95 @@
+```
+ BIP: 349
+ Layer: Consensus (soft fork)
+ Title: OP_INTERNALKEY
+ Author: Brandon Black
+ Jeremy Rubin
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0349
+ Status: Draft
+ Type: Standards Track
+ Created: 2024-11-14
+ License: BSD-3-Clause
+```
+
+## Abstract
+
+This BIP describes a new tapscript opcode (`OP_INTERNALKEY`) which
+pushes the _taproot internal key_ to the stack.
+
+## Specification
+
+When verifying taproot script path spends having leaf version `0xc0` (as
+defined in [BIP 342]), `OP_INTERNALKEY` replaces `OP_SUCCESS203` (0xcb).
+`OP_INTERNALKEY` pushes the 32-byte x-only representation of the _taproot
+internal key_ (referred to as _p_), as defined in [BIP 341], to the stack.
+
+## Motivation
+
+### Key spend with additional conditions
+
+When building taproot outputs, especially those secured by an aggregate key
+representing more than one signer, the parties may wish to collaborate on
+signing with the _taproot internal key_, but only with additional script
+restrictions. In this case, `OP_INTERNALKEY` saves 8 vBytes.
+
+### Mitigated control block overhead for scripts using hash locks
+
+In cases where key path spending is not desired, the internal key may be set to
+a NUMS point whose bytes would otherwise be required in a tapscript. This could
+be used with any hash locked transaction, for example, to save 8 vBytes.
+
+Note: The internal key must be the X coordinate of a point on the SECP256K1
+curve, so any such hash must be checked and modified until it is such an X
+coordinate. This will typically take approximately 2 attempts.
+
+### Re-Keying with Merkle Root Preservation
+
+Consider a program such `CTV CSFS CLTV`. Such fragments are useful for LN-Symmetry applications.
+
+Such a program would be embedded within a Taproot script path, such as `TR(X, {CTV CSFS CLTV})`.
+
+Were the internal key to be updated from `X` to `Y`, the resulting program would be: `TR(Y, {CTV CSFS CLTV})`.
+
+The key in the leaf and the key-path would be mismatched. Were `OP_INTERNALKEY` to be used,
+the leaf would automatically re-key.
+E.g., `TR(X, {CTV OP_INTERNALKEY CSFS CLTV})` is equivalent to `TR(X, {CTV CSFS CLTV})`
+and `TR(Y, {CTV OP_INTERNALKEY CSFS CLTV})` is equivalent to `TR(Y, {CTV CSFS CLTV})`.
+
+While this particular example is contrived, the general technique of using `OP_INTERNALKEY`
+as updatable across an entire script tree is a helpful covenant primitive when it is desirable to
+invalidate signatures from prior states. For example, the theoretical `OP_TAPLEAFUPDATEVERIFY` opcode
+modifies the internal key directly to remove or add a participant, and `OP_INTERNALKEY` would ensure
+that the tweaked key is used from all script paths where desired.
+
+## Reference Implementation
+
+A reference implementation is provided here:
+
+https://github.com/bitcoin/bitcoin/pull/29269
+
+## Backward Compatibility
+
+By constraining the behavior of an OP_SUCCESS opcode, deployment of the BIP
+can be done in a backwards compatible, soft-fork manner. If anyone were to
+rely on the OP_SUCCESS behavior of `OP_SUCCESS203`, `OP_INTERNALKEY` would
+invalidate their spend.
+
+## Deployment
+
+TBD
+
+## Credits
+
+The concept for INTERNALKEY first arose in a [discussion](https://gnusha.org/bitcoin-wizards/2022-01-05.log) between Russell O'Connor
+and Jeremy Rubin in Bitcoin Wizards IRC, inspired by BIP-0118's key punning technique
+for the internal key. It was later
+drafted into this BIP by Brandon Black.
+
+
+## Copyright
+
+This document is licensed under the 3-clause BSD license.
+
+[BIP 341]: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki
+
+[BIP 342]: https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki
diff --git a/bip-0350.mediawiki b/bip-0350.mediawiki
index 9873d80966..4c30b8f841 100644
--- a/bip-0350.mediawiki
+++ b/bip-0350.mediawiki
@@ -5,7 +5,7 @@
Author: Pieter Wuille
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0350
- Status: Draft
+ Status: Final
Type: Standards Track
Created: 2020-12-16
License: BSD-2-Clause
@@ -217,7 +217,7 @@ their invalidity.
Checksums are used to detect errors introduced into data during transfer. A hash function-based checksum such as Base58Check detects any type of error uniformly, but not all classes of errors are equally likely to occur in practice. Bech32 prioritizes detection of substitution errors, but improving detection of one error class inevitably worsens detection of other error classes. During the design of Bech32, it was assumed that other simple error patterns beside substitutions would have a similar detection rate as in a hash function-based design, and detection would only be worse for complex, impractical errors. The discovered insertion weakness shows that this is not the case.
-For Bech32m, we aim to retain Bech32's guarantees for substitution errors, but make sure that other common errors don't perform worse than a hash function-based checksum would. To make sure the new standard is easy to implement, we restrict the design space to only amending the final constant that is xored in, as it was [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-December/017521.html observed] that that is sufficient to mitigate the 'q' insertion issue while retaining the intended substitution error detection. In what follows, we explain how the new constant ''0x2bc830a3'' was chosen.
+For Bech32m, we aim to retain Bech32's guarantees for substitution errors, but make sure that other common errors don't perform worse than a hash function-based checksum would. To make sure the new standard is easy to implement, we restrict the design space to only amending the final constant that is xored in, as it was [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-December/017521.html observed] that is sufficient to mitigate the 'q' insertion issue while retaining the intended substitution error detection. In what follows, we explain how the new constant ''0x2bc830a3'' was chosen.
===Error patterns & detection probability===
diff --git a/bip-0351.mediawiki b/bip-0351.mediawiki
new file mode 100644
index 0000000000..a782b0c8f9
--- /dev/null
+++ b/bip-0351.mediawiki
@@ -0,0 +1,263 @@
+
+
+==Abstract==
+
+This BIP makes it possible for two parties to transact using addresses that only they can calculate. This is done using exclusively on-chain methods and in a manner that minimizes blockchain footprint. Receiving parties can share their payment codes publicly without a loss of privacy, as every sender will calculate a unique set of addresses for each payment code.
+
+==Motivation==
+
+A recipient that wishes to receive funds privately has several options. Each has tradeoffs in terms of chain analysis potential, recoverability, and wallet complexity.
+
+'''Sharing a static address''' works well enough for one-time payments between two parties as long as the address is shared through a private channel. It does not work well for recurring payments because address reuse leads to a loss of privacy. Using this method for donations exacerbates the problem since the address will serve as a focal point for data collection and analysis. Wallets must not reissue the same address to multiple recipients.
+
+'''Sharing a BIP32 extended public key''' works for recurring payments between two parties only. The same key cannot be shared to any other party without leaking the chain of payments. Furthermore, an extended public key does not say anything about address types and makes it possible for a sender to send to a script that a recipient cannot spend from. Alternate [https://github.com/satoshilabs/slips/blob/master/slip-0132.md version bytes] have been proposed to specify address types, but wallet adoption is limited.
+
+'''Sharing a BIP380 descriptor containing an extended public key''' solves the address type issue from sharing a raw BIP32 extended key. The drawback is that descriptor support is not widespread, especially in mobile wallets.
+
+'''Using a payment server''' works in the case of recipients that have the resources to set up and maintain a payment server that will generate a fresh address for each payment. These are usually businesses and the method is usually out of reach for the average user. The centralized server is vulnerable to takedown remotely and physically.
+
+'''Sharing a BIP47 payment code''' addresses most of the above shortcomings. However, it introduces the following problems:
+
+* The BIP uses a notification mechanism that relies on publicly known per-recipient notification addresses. If Alice wants to send funds to Bob, she has to use the same notification address that everyone else uses to notify Bob. If Alice is not careful with coin selection, i.e. ensuring that her notification UTXO is not linked to her, she will publicly expose herself as someone who is trying to send funds to Bob and their relationship becomes permanently visible on the blockchain.
+
+* The BIP does not say anything about address types. Receiving wallets therefore have to watch all address types that can be created from a single public key. Even then, a sender could send to a script that a recipient cannot spend from.
+
+==Method==
+
+When Alice wants to start paying Bob in private, she imports his payment code into a compatible wallet. Her wallet extracts Bob's public key from the payment code and sends a notification transaction. If Bob finds a notification transaction addressed to himself, he imports Alice's public key contained therein and stores it. Bob then performs ECDH using Alice's public key and his own private key in order to calculate a common set of addresses to watch. Alice calculates the same set of addresses on her end and uses them to send coins to Bob. If Alice engages in coin control, both the initial notification transaction and subsequent payment transactions cannot be attributed to either party. Even if Alice uses coins that are already associated with her, chain analysis will identify her as a sender but Bob's privacy will remain entirely preserved.
+
+==Specification==
+
+===Definitions===
+
+* Alice: sender
+* Bob: recipient
+* Payment code: static string that Bob generates and shares with others so that he can receive payments
+* ''P'': public key contained in Bob's payment code
+* ''p'': private key associated with Bob's public key ''P''
+* ''N'': extended public key used by Alice to derive child keys for each Bob she wants to transact with
+* ''n'': private key associated with Alice's public key ''N''
+* ''x'': Alice's secret recipient index, unique for each Bob
+* ''Nx'': child public key derived from ''N'' at index ''x'' (non-hardened)
+* ''nx'': private key associated with ''Nx''
+* ''c'': Alice's transaction count toward Bob
+* ''Pc'': Bob's public key at index ''c''
+* ''pc'': Bob's private key at index ''c''
+* ''Ac'': Bob's receive address at index ''c''
+* ''H'': SHA256 hash function
+* ''*'': EC multiplication
+* ''+'': EC addition
+* ''|'': string concatenation
+* ''[a..b]'': string slicing (inclusive of ''a'', exclusive of ''b'')
+
+===Public Key Derivation Path===
+
+The derivation path for this BIP follows BIP44. The following BIP32 path levels are defined:
+
+
+m / purpose' / coin_type' / account'
+
+
+purpose is set to 351.
+
+''(p, P)'' and ''(n, N)'' are keys associated with the above path, depending on which side is performing the calculation.
+
+''Nx'' keys are the direct non-hardened children of ''N''. For instance, the path of ''N0'' from ''N'' is ''m / 0''.
+
+===Payment Code Structure and Encoding===
+
+* bytes [0..2]: address type flags (2 bytes)
+* bytes [2..35]: compressed public key P (33 bytes)
+
+Payment codes are encoded in bech32m and the human readable part is "pay" for mainnet and "payt" for testnet (all types), resulting in payment codes that look like "pay1cqqq8d29g0a7m8ghmycqk5yv24mfh3xg8ptzqcn8xz6d2tjl8ccdnfkpjl7p84".
+
+===Address Types===
+
+Address type flags determine which address types a payment code accepts. This is represented by big-endian ordered 16 bits. For instance, a hypothetical payment code that handles all address types will have all defined bits set to 1 (0xffff).
+
+Currently defined flags:
+
+{| class="wikitable"
+! Address Type !! Flag !! Flag Value !! Ordinal Value
+|-
+| P2PKH || 1 << 0 || 0x0001 || 0
+|-
+| P2WPKH || 1 << 1 || 0x0002 || 1
+|-
+| P2TR || 1 << 2 || 0x0004 || 2
+|}
+
+The remaining flags are reserved for future address types.
+
+While payment codes use 2-byte bitflag arrays, notifications use ordinal values in the form of a single byte.
+
+All keys are compressed. Using uncompressed keys at any point is illegal.
+
+===Notifications===
+
+Notifications are performed by publishing transactions that contain a 40-byte OP_RETURN output. The value of the OP_RETURN is constructed using the following formula:
+
+''search_key | notification_code | Nx | address_type''
+
+* ''search_key'' equals "PP" and is a static ASCII-encoded string (2 bytes)
+* ''notification_code'' is ''H(nx * P)[0..4]'' (4 bytes)
+* ''Nx'' is the unique public key a sender is using for a particular recipient (33 bytes)
+* ''address_type'' is the '''ordinal''' value of a single address type that a sender wants to send to (1 byte). This must be selected from the recipient's accepted address types.
+
+When Alice wants to notify Bob that he will receive future payments from her, she performs the following procedure:
+
+# Assigns an unused, unique index ''x'' to Bob (''0'' if Bob is the first party she is notifying).
+# Calculates a 4-byte notification code: ''notification_code = H(nx * P)[0..4]''
+# Commits to one of Bob's accepted address types by choosing its ordinal value. Going forward Alice must not send to address types other than the one she committed to in the notification.
+# Constructs a notification payload by concatenating the above values according to the formula.
+# Selects any UTXO in her wallet, preferably not associated with her.
+# Sends a transaction including an OP_RETURN output whose value is set to the constructed payload.
+
+When Bob notices a 40-byte OP_RETURN starting with ''search key'', he performs the following procedure:
+
+# Breaks down the payload into its four constituent parts.
+# Discards the ''search_key'' (item #0).
+# Selects ''Nx'' (item #2) and performs ''H(Nx * p)'' (Bob does not know the value of ''x''). Bob takes the first four bytes of the calculated value.
+# If the four bytes match the notification value (item #1), Bob found a notification addressed to himself and stores ''Nx'' together with ''address_type''.
+# If this process fails for any reason, Bob assumes a spurious notification or one not addressed to himself and gives up.
+
+Since changing ''x'' yields a completely different sender identity, Alice can always re-notify Bob from a different index when she does not want to be associated with her previous identity. Alice can also re-notify Bob when she wants to start sending to a different address type. Bob must be able to update his watchlist in that case and he can stop watching addresses associated with the old address type.
+
+Out-of-band notifications between Alice and Bob are legal (in fact, they may not be prevented), but in that case Bob loses the ability to restore his wallet from OP_RETURN outputs embedded in the blockchain. In that case, Bob has the burden of keeping a valid backup of any out-of-band notifications.
+
+===Allowing Notification Collisions===
+
+Since ''notification_code'' is a 4-byte truncation of the full value, Bob has a 1 in ~4.3 billion chance of detecting a spurious notification. This is considered acceptable because the cost of doing so is adding a few more addresses to Bob's watchlist. The benefit of this approach is that is saves 28 bytes per notification.
+
+===Scanning Requirement===
+
+There is a scanning requirement on the recipient side in that the recipient must have access to full blocks in order to be able to search them for OP_RETURN outputs containing notifications. For more information on how light clients can get around this limitation and still use the standard, see Appendix B.
+
+Recipients that do not want to decode raw block data can quickly search for notifications in a block by looking for the following byte array: [106, 40, 80, 80]. The first two bytes represent ''OP_RETURN'' and ''OP_PUSHBYTES_40'', followed by the ASCII value of ''search_key''.
+
+===Transacting===
+
+Alice initializes counter ''c'' which is unique to Bob and increments with each transaction. ''c'' is a 64-bit integer and must be inputted into a hasher as a big-endian encoded array of 8 bytes.
+
+1. Alice calculates a secret point (constant between Alice and Bob):
+
+''S = nx * P''
+
+2. Alice calculates a shared secret:
+
+''s = H(S | c)''
+
+3. Alice calculates Bob's ephemeral public key and its associated address where the funds will be sent:
+
+''Pc = P + s*G''
+
+4. Alice constructs an address using the key ''Pc'', using one of the address types she committed to in the notification transaction.
+
+Bob constructs his watchlist by mirroring this process on his end, except that his method of calculating ''S'' is:
+
+''S = Nx * p''
+
+When Bob wants to spend from such addresses, he calculates his private keys in the following manner:
+
+''pc = p + s''
+
+==Backward Compatibility==
+
+Private Payments is a new standard which is not compatible with any previous standard based on static payment codes, such as BIP47.
+
+While the standard does not support versioning, it reserves unused bits in the address type bitflag array which can be allocated to new address types once they are deemed ubiquitous. Older payment codes (i.e. those generated when fewer address types were available) are readable by software supporting new address types. The reverse is also supported since older software will ignore newer address type flags that are not understood.
+
+==Appendix A: Test Vectors==
+
+===Alice's Wallet===
+
+'''BIP32 seed:''' 0xfe
+
+'''Master xprv:''' xprv9s21ZrQH143K2qVytoy3eZSSuc1gfzFrkV4bgoHzYTkgge4UoNP62eV8jkHYNqddaaefpnjwkz71P5m4EW6RuQBJeP9pdfa9WBnjP6XUivG
+
+'''n:''' xprv9zNFGn56Wm1s89ycTCg4hB615ehu6ZvNL4mxUEAL28pNhBAb6SZgLdsgmQd1ECgAiCjy6XxTTRyBdPAhH1oMfLhv2bSwfiCYhL9s9ahEehf
+
+'''N:''' xpub6DMbgHbzM8aALe45ZED54K2jdgYPW2eDhHhZGcZwaUMMZyVjdysvtSCAcfPYiqB5Zw41EyLWPxCXko6iEckwRdF5CD2ZKdTxUKigPXsnpaE
+
+'''x:''' 0
+
+'''nx:''' be9518016ec15762877de7d2ce7367a2087cf5682e72bbffa89535d73bb42f40
+
+'''Nx:''' 02e3217349724307eed5514b53b1f53f0802672a9913d9bbb76afecc86be23f464
+
+
+===Bob's Wallet===
+'''BIP32 seed:''' 0xff
+
+'''Master xprv:''' xprv9s21ZrQH143K47bRNtc26e8Gb3wkUiJ4fH3ewYgJeiGABp7vQtTKsLBzHM2fsfiK7Er6uMrWbdDwwrdcVn5TDC1T1npTFFkdEVoMgTwfVuR
+
+'''p:''' 0x26c610e7d0ed4395be3f0664073d66b0a3442b49e1ec13faf2dd9b7d3c335441
+
+'''P:''' 0x0302be8bff520f35fae3439f245c52afb9085a7bf62d099c1f5e9e1b15a7e2121a
+
+'''Accepted scripts:''' 0x03 (legacy + segwit) (0x01 | 0x02)
+
+'''Payment code:''' pay1qqpsxq4730l4yre4lt3588eyt3f2lwggtfalvtgfns04a8smzkn7yys6xv2gs8
+
+
+===Alice notifying Bob===
+'''S:''' 0x02c0892d6ba30b5b1eafebd47172e46d358721f294698f9f59b4d96b781da09a62
+
+'''Notification code:''' 0x49cb55bb
+
+'''Address type commitment:''' 1 (segwit)
+
+'''Notification output script:''' OP_RETURN OP_PUSHBYTES_40 505049cb55bb02e3217349724307eed5514b53b1f53f0802672a9913d9bbb76afecc86be23f46401
+
+
+===Alice sending to Bob===
+'''c:''' 0
+
+'''s:''' 0x5dbe5efee4a5b9df73708241858f2bf7ec65f141dbd229ea8e2f9f51804a18f2
+
+'''s*G:''' 0x039362033c1bc3f05e081d4d7f76d5ffebde349b0f6a4d2e8ffc5c065c17233247
+
+'''Pc:''' 0x03e669bd1705691a080840b07d76713d040934a37f2e8dde2fe02f5d3286a49219
+
+'''Ac:''' bc1qw7ld5h9tj2ruwxqvetznjfq9g5jyp0gjhrs30w
+
+
+===Bob spending===
+'''c:''' 0
+
+'''pc:''' 0x84846fe6b592fd7531af88a58ccc92a88faa1c8bbdbe3de5810d3acebc7d6d33
+
+==Appendix B: Potential OP_RETURN Services==
+
+Compact Block Filters, as formulated in BIP-0158, do not cover OP_RETURN data payloads. In support of light wallets, an external service could publish transaction proofs for all transactions that include the tagged notification payload. Light wallets would download all such transactions, filter for matches against their payment code, then verify the transaction proofs against the block headers obtained over the P2P network.
+
+==Appendix C: Potential Notification Transaction Services==
+
+No specific instruction is given as to the details of the notification transaction beyond simply including the single OP_RETURN payload. Since no restriction exists for other inputs or outputs of this transaction, there is an opportunity for an external service to include this payload in a transaction completely unrelated to Alice's wallet. Such a service could charge a fee out-of-band to help cover fees.
+
+Another opportunity exists for an existing business to attach notification payloads to transactions sent during the normal course of operations. Large withdrawal transactions from mining pools or exchanges could include a marginal notification payload without affecting overall fees.
+
+==Reference Implementation==
+
+Reference implementation is available at https://github.com/private-payments/rust-private-payments
+
+==Reference==
+* [[bip-0032.mediawiki|BIP32 - Hierarchical Deterministic Wallets]]
+* [[bip-0043.mediawiki|BIP43 - Purpose Field for Deterministic Wallets]]
+* [[bip-0044.mediawiki|BIP44 - Multi-Account Hierarchy for Deterministic Wallets]]
+* [[bip-0047.mediawiki|BIP47 - Reusable Payment Codes for Hierarchical Deterministic Wallets]]
+* [[bip-0157.mediawiki|BIP157 - Client Side Block Filtering]]
+* [[bip-0158.mediawiki|BIP158 - Compact Block Filters for Light Clients]]
+* [https://gist.github.com/RubenSomsen/21c477c90c942acf45f8e8f5c1ad4fae BIP47 Prague Discussion (acknowledgements: @rubensomsen, @afilini, @kixunil])
+
diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki
new file mode 100644
index 0000000000..4462efcaf6
--- /dev/null
+++ b/bip-0352.mediawiki
@@ -0,0 +1,498 @@
+
+ BIP: 352
+ Layer: Applications
+ Title: Silent Payments
+ Author: josibake
+ Ruben Somsen
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0352
+ Status: Proposed
+ Type: Standards Track
+ Created: 2023-03-09
+ License: BSD-2-Clause
+ Post-History: 2022-03-13: https://gist.github.com/RubenSomsen/c43b79517e7cb701ebf77eec6dbb46b8 [gist] Original proposal
+ 2022-03-28: https://gnusha.org/pi/bitcoindev/CAPv7TjbXm953U2h+-12MfJ24YqOM5Kcq77_xFTjVK+R2nf-nYg@mail.gmail.com/ [bitcoin-dev] Silent Payments – Non-interactive private payments with no on-chain overhead
+ 2022-10-11: https://gnusha.org/pi/bitcoindev/P_21MLHGJicZ-hkbC4DGu86c5BtNKiH8spY4TOw5FJsfimdi_6VyHzU_y-s1mZsOcC2FA3EW_6w6W5qfV9dRK_7AvTAxDlwVfU-yhWZPEuo=@protonmail.com/ [bitcoin-dev] Silent Payment v4 (coinjoin support added)
+ 2023-08-04: https://gnusha.org/pi/bitcoindev/ZM03twumu88V2NFH@petertodd.org/ [bitcoin-dev] BIP-352 Silent Payments addresses should have an expiration time
+
+
+== Introduction ==
+
+=== Abstract ===
+
+This document specifies a protocol for static payment addresses in Bitcoin without on-chain linkability of payments or a need for on-chain notifications.
+
+=== Copyright ===
+
+This BIP is licensed under the BSD 2-clause license.
+
+=== Motivation ===
+
+Using a new address for each Bitcoin transaction is a crucial aspect of maintaining privacy. This often requires a secure interaction between sender and receiver, so that the receiver can hand out a fresh address, a batch of fresh addresses, or a method for the sender to generate addresses on-demand, such as an xpub.
+
+However, interaction is often infeasible and in many cases undesirable. To solve for this, various protocols have been proposed which use a static payment address and notifications sent via the blockchain'''Why not use out-of-band notifications''' Out-of-band notifications (e.g. using something other than the Bitcoin blockchain) have been proposed as a way of addressing the privacy and cost concerns of using the Bitcoin blockchain as a messaging layer. This, however, simply moves the privacy and cost concerns somewhere else and increases the risk of losing money due to a notification not being reliably delivered, or even censored, and makes this notification data critical for backup to recover funds.. These protocols eliminate the need for interaction, but at the expense of increased costs for one-time payments and a noticeable footprint in the blockchain, potentially revealing metadata about the sender and receiver. Notification schemes also allow the receiver to link all payments from the same sender, compromising sender privacy.
+
+This proposal aims to address the limitations of these current approaches by presenting a solution that eliminates the need for interaction, eliminates the need for notifications, and protects both sender and receiver privacy. These benefits come at the cost of requiring wallets to scan the blockchain in order to detect payments. This added requirement is generally feasible for full nodes but poses a challenge for light clients. While it is possible today to implement a privacy-preserving light client at the cost of increased bandwidth, light client support is considered an area of open research (see [[#appendix-a-light-client-support|Appendix A: Light Client Support]]).
+
+The design keeps collaborative transactions such as CoinJoins and inputs with MuSig and FROST keys in mind, but it is recommended that the keys of all inputs of a transaction belong to the same entity as there is no formal proof that the protocol is secure in a collaborative setting.
+
+== Goals ==
+
+We aim to present a protocol which satisfies the following properties:
+
+* No increase in the size or cost of transactions
+* Resulting transactions blend in with other bitcoin transactions and can't be distinguished
+* Transactions can't be linked to a silent payment address by an outside observer
+* No sender-receiver interaction required
+* No linking of multiple payments to the same sender
+* Each silent payment goes to a unique address, avoiding accidental address reuse
+* Supports payment labeling
+* Uses existing seed phrase or descriptor methods for backup and recovery
+* Separates scanning and spending responsibilities
+* Compatible with other spending protocols, such as CoinJoin
+* Light client/SPV wallet support
+* Protocol is upgradeable
+
+== Overview ==
+
+We first present an informal overview of the protocol. In what follows, uppercase letters represent public keys, lowercase letters represent private keys, ''||'' refers to byte concatenation, ''·'' refers to elliptic curve scalar multiplication, ''G'' represents the generator point for secp256k1, and ''n'' represents the curve order for secp256k1. Each section of the overview is incomplete on its own and is meant to build on the previous section in order to introduce and briefly explain each aspect of the protocol. For the full protocol specification, see [[#specification|Specification]].
+
+''' Simple case '''
+
+Bob publishes a public key ''B'' as a silent payment address. Alice discovers Bob's silent payment address, selects a UTXO with private key ''a'', public key ''A'' and creates a destination output ''P'' for Bob in the following manner:
+
+* Let ''P = B + hash(a·B)·G''
+* Encode ''P'' as a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot output
+
+Since ''a·B == b·A'' ([https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman Elliptic-curve Diffie–Hellman]), Bob scans with his private key ''b'' by collecting the input public keys for each transaction with at least one unspent taproot output and performing the ECDH calculation until ''P'' is found (i.e. calculating ''P = B + hash(b·A)·G'' and seeing that ''P'' is present in the transaction outputs).
+
+''' Creating more than one output '''
+
+In order to allow Alice to create more than one output for Bob'''Why allow for more than one output?''' Allowing Alice to break her payment to Bob into multiple amounts opens up a number of privacy improving techniques for Alice, making the transaction look like a CoinJoin or better hiding the change amount by splitting both the payment and change outputs into multiple amounts. It also allows for Alice and Carol to both have their own unique output paying Bob in the event they are in a collaborative transaction and both paying Bob's silent payment address., we include an integer in the following manner:
+
+* Let ''k = 0''
+* Let ''P0 = B + hash(a·B || k)·G''
+* For additional outputs:
+** Increment ''k'' by one (''k++'')
+** Let ''Pi = B + hash(a·B || k)·G''
+
+Bob detects this output the same as before by searching for ''P0 = B + hash(b·A || 0)·G''. Once he detects the first output, he must:
+
+* Check for ''P1 = B + hash(b·A || 1)·G''
+* If ''P1'' is not found, stop
+* If ''P1'' is found, continue to check for ''P2'' and so on until an additional output is not found
+
+Since Bob will only perform these subsequent checks after a transaction with at least one output paying him is found, the increase to his overall scanning requirement is negligible. It should also be noted that the order in which these outputs appear in the transaction does not affect the outcome.
+
+''' Preventing address reuse '''
+
+If Alice were to use a different UTXO from the same public key ''A'' for a subsequent payment to Bob, she would end up deriving the same destinations ''Pi''. To prevent this, Alice should include an input hash in the following manner:
+
+* Let ''input_hash = hash(outpoint || A)'''''Why include A in the input hash calculation?''' By committing to A in input hash, this ensures that the sender cannot maliciously choose a private key ''a′'' in a subsequent transaction where ''a′ = input_hash·a / input_hash′'', which would force address reuse in the protocol.
+* Let ''P0 = B + hash(input_hash·a·B || 0)·G''
+
+Bob must calculate the same ''input_hash'' when scanning.
+
+''' Using all inputs '''
+
+In our simplified example we have been referring to Alice's transactions as having only one input ''A'', but in reality a Bitcoin transaction can have many inputs. Instead of requiring Alice to pick a particular input and requiring Bob to check each input separately, we can instead require Alice to perform the tweak with the sum of the input public keys'''What about inputs without public keys?''' Inputs without public keys can still be spent in the transaction but are simply ignored in the silent payments protocol.. This significantly reduces Bob's scanning requirement, makes light client support more feasible'''How does using all inputs help light clients?''' If Alice uses a random input for the tweak, Bob necessarily has to have access to and check all transaction inputs, which requires performing an ECC multiplication per input. If instead Alice performs the tweak with the sum of the input public keys, Bob only needs the summed 33 byte public key per transaction and only does one ECC multiplication per transaction. Bob can then use BIP158 block filters to determine if any of the outputs exist in a block and thus avoids downloading transactions which don't belong to him. It is still an open question as to how Bob can source the 33 bytes per transaction in a trustless manner, see [[#appendix-a-light-client-support|Appendix A: Light Client Support]] for more details., and protects Alice's privacy in collaborative transaction protocols such as CoinJoin'''Why does using all inputs matter for CoinJoin?''' If Alice uses a random input to create the output for Bob, this necessarily reveals to Bob which input Alice has control of. If Alice is paying Bob as part of a CoinJoin, this would reveal which input belongs to her, degrading the anonymity set of the CoinJoin and giving Bob more information about Alice. If instead all inputs are used, Bob has no way of knowing which input(s) belong to Alice. This comes at the cost of increased complexity as the CoinJoin participants now need to coordinate to create the silent payment output and would need to use [https://gist.github.com/RubenSomsen/be7a4760dd4596d06963d67baf140406 Blind Diffie–Hellman] to prevent the other participants from learning who Alice is paying. Note it is currently not recommended to use this protocol for CoinJoins due to a lack of a formal security proof..
+
+Alice performs the tweak with the sum of her input private keys in the following manner:
+
+* Let ''a = a1 + a2 + ... + an''
+* Let ''input_hash = hash(outpointL || (a·G))'', where ''outpointL'' is the smallest outpoint lexicographically'''Why use the lexicographically smallest outpoint for the hash?''' Recall that the purpose of including the input hash is so that the sender and receiver can both come up with a deterministic nonce that ensures that a unique address is generated each time, even when reusing the same scriptPubKey as an input. Choosing the smallest outpoint lexicographically satisfies this requirement, while also ensuring that the generated output is not dependent on the final ordering of inputs in the transaction. Using a single outpoint also works well with memory constrained devices (such as hardware signing devices) as it does not require the device to have the entire transaction in memory in order to generate the silent payment output.
+* Let ''P0 = B + hash(input_hash·a·B || 0)·G''
+
+''' Spend and Scan Key '''
+
+Since Bob needs his private key ''b'' to check for incoming payments, this requires ''b'' to be exposed to an online device. To minimize the risks involved, Bob can instead publish an address of the form ''(Bscan, Bspend)''. This allows Bob to keep ''bspend'' in offline cold storage and perform the scanning with the public key ''Bspend'' and private key ''bscan''. Alice performs the tweak using both of Bob's public keys in the following manner:
+
+* Let ''P0 = Bspend + hash(input_hash·a·Bscan || 0)·G''
+
+Bob detects this payment by calculating ''P0 = Bspend + hash(input_hash·bscan·A || 0)·G'' with his online device and can spend from his cold storage signing device using ''(bspend + hash(input_hash·bscan·A || 0)) mod n'' as the private key.
+
+''' Labels '''
+
+For a single silent payment address of the form ''(Bscan, Bspend)'', Bob may wish to differentiate incoming payments. Naively, Bob could publish multiple silent payment addresses, but this would require him to scan for each one, which becomes prohibitively expensive. Instead, Bob can label his spend public key ''Bspend'' with an integer ''m'' in the following way:
+
+* Let ''Bm = Bspend + hash(bscan || m)·G'' where m is an incrementable integer starting from 1
+* Publish ''(Bscan, B1)'', ''(Bscan, B2)'' etc.
+
+Alice performs the tweak as before using one of the published ''(Bscan, Bm)'' pairs. Bob detects the labeled payment in the following manner:
+
+* Let ''P0 = Bspend + hash(input_hash·bscan·A || 0)·G''
+* Subtract ''P0'' from each of the transaction outputs and check if the remainder matches any of the labels (''hash(bscan || 1)·G'', ''hash(bscan || 2)·G'' etc.) that the wallet has previously used
+
+It is important to note that an outside observer can easily deduce that each published ''(Bscan, Bm)'' pair is owned by the same entity as each published address will have ''Bscan'' in common. As such, labels are not meant as a way for Bob to manage separate identities, but rather a way for Bob to determine the source of an incoming payment.
+
+''' Labels for change '''
+
+Bob can also use labels for managing his own change outputs. We reserve ''m = 0'' for this use case. This gives Bob an alternative to using BIP32 for managing change, while still allowing him to know which of his unspent outputs were change when recovering his wallet from the master key. It is important that the wallet never hands out the label with ''m = 0'' in order to ensure nobody else can create payments that are wrongly labeled as change.
+
+While the use of labels is optional, every receiving silent payments wallet should at least scan for the change label when recovering from backup in order to ensure maximum cross-compatibility.
+
+== Specification ==
+
+We use the following functions and conventions:
+
+* ''outpoint'' (36 bytes): the COutPoint of an input (32-byte txid, least significant byte first || 4-byte vout, least significant byte first)'''Why are outpoints little-endian?''' Despite using big endian throughout the rest of the BIP, outpoints are sorted and hashed matching their transaction serialization, which is little-endian. This allows a wallet to parse a serialized transaction for use in silent payments without needing to re-order the bytes when computing the input hash. Note: despite outpoints being stored and serialized as little-endian, the transaction hash (txid) is always displayed as big-endian.
+* ser32(i): serializes a 32-bit unsigned integer ''i'' as a 4-byte sequence, most significant byte first.
+* ser256(p): serializes the integer p as a 32-byte sequence, most significant byte first.
+* serP(P): serializes the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form: (0x02 or 0x03) || ser256(x), where the header byte depends on the parity of the omitted Y coordinate.
+
+For everything not defined above, we use the notation from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#specification BIP340]. This includes the ''hashtag(x)'' notation to refer to ''SHA256(SHA256(tag) || SHA256(tag) || x)''.
+
+=== Versions ===
+
+This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as bech32 addresses (see [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 BIP173]. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP.
+
+Future silent payments versions will use the following scheme:
+
+{| class="wikitable"
+|-
+!
+!0
+!1
+!2
+!3
+!4
+!5
+!6
+!7
+!Compatibility
+|-
+!+0
+|q||p||z||r||y||9||x||8||rowspan="4" | backwards compatible
+|-
+!+8
+|g||f||2||t||v||d||w||0
+|-
+!+16
+|s||3||j||n||5||4||k||h
+|-
+!+24
+|c||e||6||m||u||a||7|| -
+|}
+
+''v31'' (l) is reserved for a backwards incompatible change, if needed. For silent payments v0:
+
+* If the receiver's silent payment address version is:
+** ''v0'': check that the data part is exactly 66-bytes. Otherwise, fail
+** ''v1'' through ''v30'': read the first 66-bytes of the data part and discard the remaining bytes
+** ''v31'': fail
+* Receiver addresses are always [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot outputs'''Why only taproot outputs?''' Providing too much optionality for the protocol makes it difficult to implement and can be at odds with the goal of providing the best privacy. Limiting to taproot outputs helps simplify the implementation significantly while also putting users in the best eventual anonymity set.
+* The sender should sign with one of the sighash flags ''DEFAULT'', ''ALL'', ''SINGLE'', ''NONE'' (''ANYONECANPAY'' is unsafe). It is strongly recommended implementations use ''SIGHASH_ALL'' (''SIGHASH_DEFAULT'' for taproot inputs) when possible'''Why is it unsafe to use ''SIGHASH_ANYONECANPAY''?''' Since the output address for the receiver is derived from the sum of the [[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]] public keys, the inputs must not change once the sender has signed the transaction. If the inputs are allowed to change after the fact, the receiver will not be able to calculate the shared secret needed to find and spend the output. It is currently an open question on how a future version of silent payments could be made to work with new sighash flags such as ''SIGHASH_GROUP'' and ''SIGHASH_ANYPREVOUT''.
+* Inputs used to derive the shared secret are from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list
+
+=== Scanning silent payment eligible transactions ===
+
+For silent payments v0 a transaction MUST be scanned if and only if all of the following are true:
+
+* The transaction contains at least one BIP341 taproot output (note: spent transactions optionally can be skipped by only considering transactions with at least one unspent taproot output)
+* The transaction has at least one input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list
+* The transaction does not spend an output with SegWit version > 1'''Why skip transactions that spend SegWit version > 1?''' Skipping transactions that spend unknown output scripts allows us to have a clean upgrade path for silent payments by avoiding the need to scan the same transaction multiple times with different rule sets. If a new SegWit version is added in the future and silent payments v1 is released with support, we would want to avoid having to first scan the transaction with the silent payment v0 rules and then again with the silent payment v1 rules. Note: this restriction only applies to the inputs of a transaction.
+
+=== Address encoding ===
+
+A silent payment address is constructed in the following manner:
+
+* Let ''Bscan, bscan = Receiver's scan public key and corresponding private key''
+* Let ''Bspend, bspend = Receiver's spend public key and corresponding private key''
+* Let ''Bm = Bspend + hashBIP0352/Label(ser256(bscan) || ser32(m))·G'', where ''hashBIP0352/Label(ser256(bscan) || ser32(m))·G'' is an optional integer tweak for labeling
+** If no label is applied then ''Bm = Bspend''
+* The final address is a [https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki Bech32m] encoding of:
+** The human-readable part "sp" for mainnet, "tsp" for testnets (e.g. signet, testnet)
+** The data-part values:
+*** The character "q", to represent a silent payment address of version 0
+*** The 66-byte concatenation of the receiver's public keys, ''serP(Bscan) || serP(Bm)''
+
+Note: [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki BIP173] imposes a 90 character limit for Bech32 segwit addresses and limits versions to 0 through 16, whereas a silent payment address requires ''at least'' 117 characters ''' Why do silent payment addresses need at least 117 characters?''' A silent payment address is a bech32m encoding comprised of the following parts:
+
+
+* HRP [2-3 characters]
+* separator [1 character]
+* version [1-2 characters]
+* payload, 66 bytes concatenated pubkeys [ceil(66*8/5) = 106 characters]
+* checksum [6 characters]
+
+
+For a silent payments v0 address, this results in a 117-character address when using a 3-character HRP. Future versions of silent payment addresses may add to the payload, which is why a 1023-character limit is suggested. and allows versions up to 31. Additionally, since higher versions may add to the data field, it is recommended implementations use a limit of 1023 characters (see [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#checksum-design BIP173: Checksum design] for more details).
+
+=== Inputs For Shared Secret Derivation ===
+
+While any UTXO with known output scripts can be used to fund the transaction, the sender and receiver MUST use inputs from the following list when deriving the shared secret:
+
+* ''P2TR''
+* ''P2WPKH''
+* ''P2SH-P2WPKH''
+* ''P2PKH''
+
+Inputs with conditional branches or multiple public keys (e.g. ''CHECKMULTISIG'') are excluded from shared secret derivation as this introduces malleability and would allow a sender to re-sign with a different set of public keys after the silent payment output has been derived. This is not a concern when the sender controls all of the inputs, but is an issue for CoinJoins and other collaborative protocols, where a malicious participant can participate in deriving the silent payment address with one set of keys and then re-broadcast the transaction with signatures for a different set of public keys. P2TR can have hidden conditional branches (script path), but we work around this by using only the output public key.
+
+For all of the output types listed, only X-only and compressed public keys are permitted''' Why only compressed public keys ''' Uncompressed and hybrid public keys are less common than compressed keys and generally considered to be a bad idea due to their blockspace inefficiency. Additionally, [https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#restrictions-on-public-key-type BIP143] recommends restricting P2WPKH inputs to compressed keys as a default policy..
+
+''' P2TR '''
+
+'' Keypath spend ''
+
+ witness:
+ scriptSig: (empty)
+ scriptPubKey: 1 <32-byte-x-only-key>
+ (0x5120{32-byte-x-only-key})
+
+The sender uses the private key corresponding to the taproot output key (i.e. the tweaked private key). This can be a single private key or an aggregate key (e.g. taproot outputs using MuSig or FROST)'''Are key aggregation techniques like FROST and MuSig supported?''' While we do not recommend it due to lack of a security proof (except if all participants are trusted or are the same entity), any taproot output able to do a key path theoretically is supported. Any offline key aggregation technique can be used, such as FROST or MuSig. This would require participants to perform the ECDH step collaboratively e.g. ''ECDH = a1·Bscan + a2·Bscan + ... + at·Bscan'' and ''P = Bspend + hash(input_hash·ECDH || 0)·G''. Additionally, it may be necessary for the participants to provide a DLEQ proof to ensure they are not acting maliciously.. The receiver obtains the public key from the ''scriptPubKey'' (i.e. the taproot output key).
+
+'' Script path spend ''
+
+ witness:
+ scriptSig: (empty)
+ scriptPubKey: 1 <32-byte-x-only-key>
+ (0x5120{32-byte-x-only-key})
+
+Same as a keypath spend, the sender MUST use the private key corresponding to the taproot output key. If this key is not available, the output cannot be included as an input to the transaction. Same as a keypath spend, the receiver obtains the public key from the ''scriptPubKey'' (i.e. the taproot output key)''' Why not skip all taproot script path spends? ''' This causes malleability issues for CoinJoins. If the silent payments protocol skipped taproot script path spends, this would allow an attacker to join a CoinJoin round, participate in deriving the silent payment address using the tweaked private key for a key path spend, and then broadcast their own version of the transaction using the script path spend. If the receiver were to only consider key path spends, they would skip the attacker's script path spend input when deriving the shared secret and not be able to find the funds. Additionally, there may be scenarios where the sender can perform ECDH with the key path private key but spends the output using the script path..
+
+The one exception is script path spends that use NUMS point ''H'' as their internal key (where ''H'' is constructed by taking the hash of the standard uncompressed encoding of the secp256k1 base point ''G'' as X coordinate, see [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs BIP341: Constructing and spending Taproot outputs] for more details), in which case the input will be skipped for the purposes of shared secret derivation'''Why skip outputs with H as the internal taproot key?''' If use cases get popularized where the taproot key path cannot be used, these outputs can still be included without getting in the way of making a silent payment, provided they specifically use H as their internal taproot key.. The receiver determines whether or not to skip the input by checking in the control block if the taproot internal key is equal to ''H''.
+
+''' P2WPKH '''
+
+ witness: <33-byte-compressed-key>
+ scriptSig: (empty)
+ scriptPubKey: 0 <20-byte-key-hash>
+ (0x0014{20-byte-key-hash})
+
+The sender performs the tweak using the private key for the output and the receiver obtains the public key as the last witness item.
+
+''' P2SH-P2WPKH '''
+
+ witness: <33-byte-compressed-key>
+ scriptSig: <0 <20-byte-key-hash>>
+ (0x160014{20-byte-key-hash})
+ scriptPubKey: HASH160 <20-byte-script-hash> EQUAL
+ (0xA914{20-byte-script-hash}87)
+
+The sender performs the tweak using the private key for the nested ''P2WPKH'' output and the receiver obtains the public key as the last witness item.
+
+''' P2PKH '''
+
+ scriptSig: <33-byte-compressed-key>
+ scriptPubKey: OP_DUP HASH160 <20-byte-key-hash> OP_EQUALVERIFY OP_CHECKSIG
+ (0x76A914{20-byte-key-hash}88AC)
+
+The receiver obtains the public key from the ''scriptSig''. The receiver MUST parse the ''scriptSig'' for the public key, even if the ''scriptSig'' does not match the template specified (e.g. OP_DROP ). This is to address the [https://en.bitcoin.it/wiki/Transaction_malleability third-party malleability of ''P2PKH'' ''scriptSigs''].
+
+=== Sender ===
+
+==== Selecting inputs ====
+
+The sending wallet performs coin selection as usual with the following restrictions:
+
+* At least one input MUST be from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list
+* Exclude inputs with SegWit version > 1 (see ''[[#scanning-silent-payment-eligible-transactions|Scanning silent payment eligible transactions]]'')
+* For each taproot output spent the sending wallet MUST have access to the private key corresponding to the taproot output key, unless ''H'' is used as the internal public key
+
+==== Creating outputs ====
+
+After the inputs have been selected, the sender can create one or more outputs for one or more silent payment addresses in the following manner:
+
+* Collect the private keys for each input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list
+* For each private key ''ai'' corresponding to a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot output, check that the private key produces a point with an even Y coordinate and negate the private key if not'''Why do taproot private keys need to be checked?''' Recall from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] that each X-only public key has two corresponding private keys, ''d'' and ''n - d''. To maintain parity between sender and receiver, it is necessary to use the private key corresponding to the even Y coordinate when performing the ECDH step since the receiver will assume the even Y coordinate when summing the taproot X-only public keys.
+* Let ''a = a1 + a2 + ... + an'', where each ''ai'' has been negated if necessary
+** If ''a = 0'', fail
+* Let ''input_hash = hashBIP0352/Inputs(outpointL || A)'', where ''outpointL'' is the smallest ''outpoint'' lexicographically used in the transaction and ''A = a·G''
+* Group receiver silent payment addresses by ''Bscan'' (e.g. each group consists of one ''Bscan'' and one or more ''Bm'')
+* For each group:
+** Let ''ecdh_shared_secret = input_hash·a·Bscan''
+** Let ''k = 0''
+** For each ''Bm'' in the group:
+*** Let ''tk = hashBIP0352/SharedSecret(serP(ecdh_shared_secret) || ser32(k))''
+**** If ''tk'' is not valid tweak, i.e., if ''tk = 0'' or ''tk'' is larger or equal to the secp256k1 group order, fail
+*** Let ''Pmn = Bm + tk·G''
+*** Encode ''Pmn'' as a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot output
+*** Optionally, repeat with k++ to create additional outputs for the current ''Bm''
+*** If no additional outputs are required, continue to the next ''Bm'' with ''k++''''' Why not re-use ''tk'' when paying different labels to the same receiver?''' If paying the same entity but to two separate labeled addresses in the same transaction without incrementing ''k'', an outside observer could subtract the two output values and observe that this value is the same as the difference between two published silent payment addresses and learn who the recipient is.
+** Optionally, if the sending wallet implements receiving silent payments, it can create change outputs by sending to its own silent payment address using label ''m = 0'', following the steps above
+
+=== Receiver ===
+
+==== Key Derivation ====
+
+Two keys are needed to create a silent payments address: the spend key and the scan key. To ensure compatibility, wallets MAY use BIP32 derivation with the following derivation paths for the spend and scan key. When using BIP32 derivation, wallet software MUST use hardened derivation'''Why use BIP32 hardened derivation?''' Using BIP32 derivation allows users to add silent payments to an existing master seed. It also ensures that a user's silent payment funds are recoverable in any BIP32/BIP43 compatible wallet. Using hardened derivation ensures that it is safe to export the scan private key without exposing the master key or spend private key. for both the spend and scan key.
+
+A scan and spend key pair using BIP32 derivation are defined (taking inspiration from [https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki BIP44]) in the following manner:
+
+ scan_private_key: m / purpose' / coin_type' / account' / 1' / 0
+ spend_private_key: m / purpose' / coin_type' / account' / 0' / 0
+
+purpose is a constant set to ''352'' following the BIP43 recommendation. Refer to [https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki BIP43] and [https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki BIP44] for more details.
+
+==== Scanning ====
+
+If each of the checks in ''[[#scanning-silent-payment-eligible-transactions|Scanning silent payment eligible transactions]]'' passes, the receiving wallet must:
+
+* Let ''A = A1 + A2 + ... + An'', where each ''Ai'' is the public key of an input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list
+** If ''A'' is the point at infinity, skip the transaction
+* Let ''input_hash = hashBIP0352/Inputs(outpointL || A)'', where ''outpointL'' is the smallest ''outpoint'' lexicographically used in the transaction
+* Let ''ecdh_shared_secret = input_hash·bscan·A''
+* Check for outputs:
+** Let ''outputs_to_check'' be the taproot output keys from all taproot outputs in the transaction (spent and unspent).
+** Starting with ''k = 0'':
+*** Let ''tk = hashBIP0352/SharedSecret(serP(ecdh_shared_secret) || ser32(k))''
+**** If ''tk'' is not valid tweak, i.e., if ''tk = 0'' or ''tk'' is larger or equal to the secp256k1 group order, fail
+*** Compute ''Pk = Bspend + tk·G''
+*** For each ''output'' in ''outputs_to_check'':
+**** If ''Pk'' equals ''output'':
+***** Add ''Pk'' to the wallet
+***** Remove ''output'' from ''outputs_to_check'' and rescan ''outputs_to_check'' with ''k++''
+**** Else, check for labels (always check for the change label, i.e. ''hashBIP0352/Label(ser256(bscan) || ser32(m))'' where ''m = 0'')''' Why precompute labels?''' Precomputing the labels is not strictly necessary: a wallet could track the max number of labels it has used (call it ''M'') and scan for labels by adding ''hash(bscan || m)·G'' to ''P0'' for each label ''m'' up to ''M'' and comparing to the transaction outputs. This is more performant than precomputing the labels and checking via subtraction in cases where the number of eligible outputs exceeds the number of labels in use. In practice this will mainly apply to users that choose never to use labels, or users that use a single label for generating silent payment change outputs. If using a large number of labels, the wallet would need to add all possible labels to each output. This ends up being ''n·M'' additions, where ''n'' is the number of outputs in the transaction and ''M'' is the number of labels in the wallet. By precomputing the labels, the wallet only needs to compute ''hash(bscan || m)·G'' once when creating the labeled address and can determine if a label was used via a lookup, rather than adding each label to each output.:
+***** Compute ''label = output - Pk''
+***** Check if ''label'' exists in the list of labels used by the wallet
+***** If a match is found:
+****** Add ''Pk + label'' to the wallet
+****** Remove ''output'' from ''outputs_to_check'' and rescan ''outputs_to_check'' with ''k++''
+***** If a label is not found, negate ''output'' and check a second time''' Why negate the output?''' Unfortunately taproot outputs are X-only, meaning we don't know what the correct Y coordinate is. This causes this specific calculation to fail 50% of the time, so we need to repeat it with the other Y coordinate by negating the output.
+*** If no matches are found, stop
+
+==== Spending ====
+
+Recall that a silent payment output is of the form ''Bspend + tk·G + hashBIP0352/Label(ser256(bscan) || ser32(m))·G'', where ''hashBIP0352/Label(ser256(bscan) || ser32(m))·G'' is an optional label. To spend a silent payment output:
+
+* Let ''d = (bspend + tk + hashBIP0352/Label(ser256(bscan) || ser32(m))) mod n'', where ''hashBIP0352/Label(ser256(bscan) || ser32(m))'' is the optional label
+* Spend the [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] output with the private key ''d''
+
+==== Backup and Recovery ====
+
+Since each silent payment output address is derived independently, regular backups are recommended. When recovering from a backup, the wallet will need to scan since the last backup to detect new payments.
+
+If using a seed/seed phrase only style backup, the user can recover the wallet's unspent outputs from the UTXO set (i.e. only scanning transactions with at least one unspent taproot output) and can recover the full wallet history by scanning the blockchain starting from the wallet birthday. If a wallet uses labels, this information SHOULD be included in the backup. If the user does not know whether labels were used, it is strongly recommended they always precompute and check a large number of labels (e.g. 100k labels) to use when re-scanning. This ensures that the wallet can recover all funds from only a seed/seed phrase backup. The change label should simply always be scanned for, even when no other labels were used. This ensures the use of a change label is not critical for backups and maximizes cross-compatibility.
+
+== Backward Compatibility ==
+
+Silent payments introduces a new address format and protocol for sending and as such is not compatible with older wallet software or wallets which have not implemented the silent payments protocol.
+
+== Test Vectors ==
+
+A [[bip-0352/send_and_receive_test_vectors.json|collection of test vectors in JSON format]] are provided, along with a [[bip-0352/reference.py|python reference implementation]]. Each test vector consists of a sending test case and corresponding receiving test case. This is to allow sending and receiving to be implemented separately. To ensure determinism while testing, sort the array of ''Bm'' by amount (see the [[bip-0352/reference.py|reference implementation]]). Test cases use the following schema:
+
+''' test_case '''
+
+ {
+ "comment": "Comment describing the behavior being tested",
+ "sending": [],
+ "receiving": [],
+ }
+
+''' sender '''
+
+ {
+ "given": {
+ "vin": [],
+ "recipients": []
+ },
+ "expected": {
+ "outputs": [],
+ "n_outputs": ,
+ },
+ }
+
+''' recipient '''
+
+ {
+ "given": {
+ "vin": [],
+ "key_material": {
+ "scan_priv_key": ,
+ "spend_priv_key": ,
+ }
+ "labels": [],
+ },
+ "expected": {
+ "addresses": [],
+ "outputs": [
+ {
+ "priv_key_tweak": ,
+ "pub_key": ,
+ "signature":
+ },
+ ...
+ ],
+ "n_outputs":
+ }
+ }
+
+Wallets should include inputs not in the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list when testing to ensure that only inputs from the list are being used for shared secret derivation. Additionally, receiving wallets should include non-silent payment outputs for themselves in testing to ensure silent payments scanning does not interfere with regular outputs detection.
+
+=== Functional tests ===
+
+Below is a list of functional tests which should be included in sending and receiving implementations.
+
+==== Sending ====
+
+* Ensure taproot outputs are excluded during coin selection if the sender does not have access to the key path private key (unless using ''H'' as the taproot internal key)
+* Ensure the silent payment address is re-derived if inputs are added or removed during RBF
+
+==== Receiving ====
+
+* Ensure the public key can be extracted from non-standard ''P2PKH'' scriptSigs
+* Ensure taproot script path spends are included, using the taproot output key (unless ''H'' is used as the taproot internal key)
+* Ensure the scanner can extract the public key from each of the input types supported (e.g. ''P2WPKH'', ''P2SH-P2WPKH'', etc.)
+
+== Appendix A: Light Client Support ==
+
+This section proposes a few ideas for how light clients could support scanning for incoming silent payments (sending is fairly straightforward) in ways that preserve bandwidth and privacy. While this is out of scope for the current BIP, it is included to motivate further research into this topic. In this context, a light client refers to any bitcoin wallet client which does not process blocks and does not have a direct connection to a node which does process blocks (e.g. a full node). Based on this definition, clients that directly connect to a personal electrum server or a bitcoin node are not light clients.
+
+This distinction makes the problem for light clients more clear: light clients need a way to source the necessary data for performing the tweaks and a way of determining if any of the generated outputs exist in a block.
+
+=== Tweak Data ===
+
+Recall that a silent payment eligible transaction follows [[#scanning-silent-payment-eligible-transactions|certain conditions]] and should have at least one unspent taproot output. Full nodes (or any index server backed by a full node, such as electrum server) can build an index which collects all of the eligible public keys for a silent payments eligible transaction, sums them up, multiplies the sum by the ''input_hash'', and serves them to clients. This would be 33 bytes per silent payment eligible transaction.
+
+For a typical bitcoin block of ~3500 txs, lets assume every transaction is a silent payments eligible transaction. This means a client would need to request ''33 bytes * 3500'' of data per block (roughly 100 kB per block). If a client were to request data for every block, this would amount to ~450 MB per month, assuming 100% taproot usage and all non-dust outputs remain unspent for > 1 month. As of today, these numbers are closer to 7–12 kB per block (30–50 MB per month)''' Data for Appendix A ''' These numbers are based on data from January 2023 until July 2024. See [https://github.com/josibake/bitcoin-data-analysis/blob/main/notebooks/silent-payments-light-client-data.ipynb Silent payments light client data] for the full analysis..
+
+=== Transaction cut-through ===
+
+It is unlikely a light client would need to scan every block and as such can take advantage of transaction cut-through, depending on how often they choose to scan for new blocks. Empirically, ~75% of transactions with at least one non-dust unspent taproot output will have spent all non-dust taproot UTXOs in 150 blocks or less. This means a client that only scans once per day could ''significantly'' cut down on the number of blocks and the number of transactions per block that they need to request by only asking for data on transactions that were created since their last scan and that still have at least one non-dust unspent taproot output as of the current block height. Based on taproot adoption as of July 2024, a light client scanning once every 3 days would use roughly 30 MB per month.
+
+[[File:bip-0352/scan_data_downloader_per_month.png]]
+
+=== BIP158 ===
+
+Once a light client has the tweak data for a block, they can determine whether or not an output to them exists in the block using BIP158 block filters. Per BIP158, they would then request the entire block and add the transaction to their wallet, though it maybe be possible to only request the prevout txids and vouts for all transactions with at least one taproot output, along with the scriptPubKeys and amounts. This would allow the client to download the necessary data for constructing a spending transaction, without downloading the entire block. How this affects the security assumptions of BIP158 is an open question.
+
+=== Out-of-band notifications ===
+
+Assuming a secure messaging protocol exists, the sender can send an encrypted (using the scan public key of the silent payment address) notification to the receiver with the following information:
+* The spend public key (communicates the label)
+* The shared secret portion of the private key (i.e ''hash(ecdh_shared_secret || k)'')
+* The outpoint and amount (so it's immediately spendable)
+
+It is important to note that these notifications are not required. At any point, the receiver can fall back to scanning for silent payment transactions if they don't trust the notifications they are receiving, are being spammed with fake notifications, or if they are concerned that they are not receiving notifications.
+
+A malicious notification could potentially cause the following issues:
+
+* You did not actually receive money to the stated key
+** This can be probabilistically resolved by matching the key against the BIP158 block filters and assuming it's not a false positive, or fully resolved by downloading the block
+* You received money but the outpoint or amount is incorrect, so attempts to spend it will fail or cause you to overpay fees
+** There doesn't seem to be much motivation for malicious senders to ever do this, but light clients need to take into account that this can occur and should ideally check for it by downloading the block
+* The private key is correct but it wasn't actually derived using the silent payment protocol, causing recovery from back-up to fail (unsafe - no implementation should ever allow this)
+** This can be detected by downloading the tweak data of the corresponding block and should be resolved by immediately spending the output
+
+Wallet designers can choose which tradeoffs they find appropriate. For example, a wallet could check the block filter to at least probabilistically confirm the likely existence of the UTXO, thus efficiently cutting down on spam. The payment could then be marked as unconfirmed until a scan is performed and the existence of the UTXO in accordance to the silent payment specification is verified.
+
+== Change Log ==
+
+To help implementers understand updates to this document, we attach a version number that resembles ''semantic versioning'' (MAJOR.MINOR.PATCH).
+The MAJOR version is incremented if changes to the BIP are introduced that are incompatible with prior versions.
+The MINOR version is incremented whenever the inputs or the output of an algorithm changes in a backward-compatible way or new backward-compatible functionality is added.
+The PATCH version is incremented for other changes that are noteworthy (bug fixes, test vectors, important clarifications, etc.).
+
+* '''1.0.1''' (2024-06-22):
+** Add steps to fail if private key sum is zero (for sender) or public key sum is point at infinity (for receiver), add corresponding test vectors.
+* '''1.0.0''' (2024-05-08):
+** Initial version, merged as BIP-352.
+
+== Acknowledgements ==
+
+This document is the result of many discussions and contains contributions by a number of people. The authors wish to thank all those who provided valuable feedback and reviews, including the participants of the [https://gist.github.com/RubenSomsen/21c477c90c942acf45f8e8f5c1ad4fae BIP47 Prague discussion], the [https://github.com/josibake/silent-payments-workshop Advancing Bitcoin silent payments Workshop], and [https://btctranscripts.com/bitcoin-core-dev-tech/2023-04/2023-04-26-silent-payments/ coredev]. The authors would like to also thank [https://github.com/w0xlt w0xlt] for writing the initial implementation of silent payments.
+
+== Rationale and References ==
+
+
diff --git a/bip-0352/bech32m.py b/bip-0352/bech32m.py
new file mode 100644
index 0000000000..795e153863
--- /dev/null
+++ b/bip-0352/bech32m.py
@@ -0,0 +1,135 @@
+# Copyright (c) 2017, 2020 Pieter Wuille
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+"""Reference implementation for Bech32/Bech32m and segwit addresses."""
+
+
+from enum import Enum
+
+class Encoding(Enum):
+ """Enumeration type to list the various supported encodings."""
+ BECH32 = 1
+ BECH32M = 2
+
+CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+BECH32M_CONST = 0x2bc830a3
+
+def bech32_polymod(values):
+ """Internal function that computes the Bech32 checksum."""
+ generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
+ chk = 1
+ for value in values:
+ top = chk >> 25
+ chk = (chk & 0x1ffffff) << 5 ^ value
+ for i in range(5):
+ chk ^= generator[i] if ((top >> i) & 1) else 0
+ return chk
+
+
+def bech32_hrp_expand(hrp):
+ """Expand the HRP into values for checksum computation."""
+ return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp]
+
+
+def bech32_verify_checksum(hrp, data):
+ """Verify a checksum given HRP and converted data characters."""
+ const = bech32_polymod(bech32_hrp_expand(hrp) + data)
+ if const == 1:
+ return Encoding.BECH32
+ if const == BECH32M_CONST:
+ return Encoding.BECH32M
+ return None
+
+def bech32_create_checksum(hrp, data, spec):
+ """Compute the checksum values given HRP and data."""
+ values = bech32_hrp_expand(hrp) + data
+ const = BECH32M_CONST if spec == Encoding.BECH32M else 1
+ polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ const
+ return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)]
+
+
+def bech32_encode(hrp, data, spec):
+ """Compute a Bech32 string given HRP and data values."""
+ combined = data + bech32_create_checksum(hrp, data, spec)
+ return hrp + '1' + ''.join([CHARSET[d] for d in combined])
+
+def bech32_decode(bech):
+ """Validate a Bech32/Bech32m string, and determine HRP and data."""
+ if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or
+ (bech.lower() != bech and bech.upper() != bech)):
+ return (None, None, None)
+ bech = bech.lower()
+ pos = bech.rfind('1')
+
+ # remove the requirement that bech32m be less than 90 chars
+ if pos < 1 or pos + 7 > len(bech):
+ return (None, None, None)
+ if not all(x in CHARSET for x in bech[pos+1:]):
+ return (None, None, None)
+ hrp = bech[:pos]
+ data = [CHARSET.find(x) for x in bech[pos+1:]]
+ spec = bech32_verify_checksum(hrp, data)
+ if spec is None:
+ return (None, None, None)
+ return (hrp, data[:-6], spec)
+
+def convertbits(data, frombits, tobits, pad=True):
+ """General power-of-2 base conversion."""
+ acc = 0
+ bits = 0
+ ret = []
+ maxv = (1 << tobits) - 1
+ max_acc = (1 << (frombits + tobits - 1)) - 1
+ for value in data:
+ if value < 0 or (value >> frombits):
+ return None
+ acc = ((acc << frombits) | value) & max_acc
+ bits += frombits
+ while bits >= tobits:
+ bits -= tobits
+ ret.append((acc >> bits) & maxv)
+ if pad:
+ if bits:
+ ret.append((acc << (tobits - bits)) & maxv)
+ elif bits >= frombits or ((acc << (tobits - bits)) & maxv):
+ return None
+ return ret
+
+
+def decode(hrp, addr):
+ """Decode a segwit address."""
+ hrpgot, data, spec = bech32_decode(addr)
+ if hrpgot != hrp:
+ return (None, None)
+ decoded = convertbits(data[1:], 5, 8, False)
+ if decoded is None or len(decoded) < 2:
+ return (None, None)
+ if data[0] > 16:
+ return (None, None)
+ return (data[0], decoded)
+
+
+def encode(hrp, witver, witprog):
+ """Encode a segwit address."""
+ spec = Encoding.BECH32 if witver == 0 else Encoding.BECH32M
+ ret = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5), spec)
+ if decode(hrp, ret) == (None, None):
+ return None
+ return ret
diff --git a/bip-0352/bitcoin_utils.py b/bip-0352/bitcoin_utils.py
new file mode 100644
index 0000000000..ee55f2d3b3
--- /dev/null
+++ b/bip-0352/bitcoin_utils.py
@@ -0,0 +1,159 @@
+import hashlib
+import struct
+from io import BytesIO
+from ripemd160 import ripemd160
+from secp256k1 import ECKey
+from typing import Union
+
+
+def from_hex(hex_string):
+ """Deserialize from a hex string representation (e.g. from RPC)"""
+ return BytesIO(bytes.fromhex(hex_string))
+
+
+def ser_uint32(u: int) -> bytes:
+ return u.to_bytes(4, "big")
+
+
+def ser_uint256(u):
+ return u.to_bytes(32, 'little')
+
+
+def deser_uint256(f):
+ return int.from_bytes(f.read(32), 'little')
+
+
+def deser_txid(txid: str):
+ # recall that txids are serialized little-endian, but displayed big-endian
+ # this means when converting from a human readable hex txid, we need to first
+ # reverse it before deserializing it
+ dixt = "".join(map(str.__add__, txid[-2::-2], txid[-1::-2]))
+ return bytes.fromhex(dixt)
+
+
+def deser_compact_size(f: BytesIO):
+ view = f.getbuffer()
+ nbytes = view.nbytes;
+ view.release()
+ if (nbytes == 0):
+ return 0 # end of stream
+
+ nit = struct.unpack(" bytes:
+ return ripemd160(hashlib.sha256(s).digest())
+
+
+def is_p2tr(spk: bytes) -> bool:
+ if len(spk) != 34:
+ return False
+ # OP_1 OP_PUSHBYTES_32 <32 bytes>
+ return (spk[0] == 0x51) & (spk[1] == 0x20)
+
+
+def is_p2wpkh(spk: bytes) -> bool:
+ if len(spk) != 22:
+ return False
+ # OP_0 OP_PUSHBYTES_20 <20 bytes>
+ return (spk[0] == 0x00) & (spk[1] == 0x14)
+
+
+def is_p2sh(spk: bytes) -> bool:
+ if len(spk) != 23:
+ return False
+ # OP_HASH160 OP_PUSHBYTES_20 <20 bytes> OP_EQUAL
+ return (spk[0] == 0xA9) & (spk[1] == 0x14) & (spk[-1] == 0x87)
+
+
+def is_p2pkh(spk: bytes) -> bool:
+ if len(spk) != 25:
+ return False
+ # OP_DUP OP_HASH160 OP_PUSHBYTES_20 <20 bytes> OP_EQUALVERIFY OP_CHECKSIG
+ return (spk[0] == 0x76) & (spk[1] == 0xA9) & (spk[2] == 0x14) & (spk[-2] == 0x88) & (spk[-1] == 0xAC)
diff --git a/bip-0352/reference.py b/bip-0352/reference.py
new file mode 100755
index 0000000000..3d0899ce27
--- /dev/null
+++ b/bip-0352/reference.py
@@ -0,0 +1,342 @@
+#!/usr/bin/env python3
+# For running the test vectors, run this script:
+# ./reference.py send_and_receive_test_vectors.json
+
+import hashlib
+import json
+from typing import List, Tuple, Dict, cast
+from sys import argv, exit
+from functools import reduce
+from itertools import permutations
+
+# local files
+from bech32m import convertbits, bech32_encode, decode, Encoding
+from secp256k1 import ECKey, ECPubKey, TaggedHash, NUMS_H
+from bitcoin_utils import (
+ deser_txid,
+ from_hex,
+ hash160,
+ is_p2pkh,
+ is_p2sh,
+ is_p2wpkh,
+ is_p2tr,
+ ser_uint32,
+ COutPoint,
+ CTxInWitness,
+ VinInfo,
+ )
+
+
+def get_pubkey_from_input(vin: VinInfo) -> ECPubKey:
+ if is_p2pkh(vin.prevout):
+ # skip the first 3 op_codes and grab the 20 byte hash
+ # from the scriptPubKey
+ spk_hash = vin.prevout[3:3 + 20]
+ for i in range(len(vin.scriptSig), 0, -1):
+ if i - 33 >= 0:
+ # starting from the back, we move over the scriptSig with a 33 byte
+ # window (to match a compressed pubkey). we hash this and check if it matches
+ # the 20 byte hash from the scriptPubKey. for standard scriptSigs, this will match
+ # right away because the pubkey is the last item in the scriptSig.
+ # if its a non-standard (malleated) scriptSig, we will still find the pubkey if its
+ # a compressed pubkey.
+ #
+ # note: this is an incredibly inefficient implementation, for demonstration purposes only.
+ pubkey_bytes = vin.scriptSig[i - 33:i]
+ pubkey_hash = hash160(pubkey_bytes)
+ if pubkey_hash == spk_hash:
+ pubkey = ECPubKey().set(pubkey_bytes)
+ if (pubkey.valid) & (pubkey.compressed):
+ return pubkey
+ if is_p2sh(vin.prevout):
+ redeem_script = vin.scriptSig[1:]
+ if is_p2wpkh(redeem_script):
+ pubkey = ECPubKey().set(vin.txinwitness.scriptWitness.stack[-1])
+ if (pubkey.valid) & (pubkey.compressed):
+ return pubkey
+ if is_p2wpkh(vin.prevout):
+ txin = vin.txinwitness
+ pubkey = ECPubKey().set(txin.scriptWitness.stack[-1])
+ if (pubkey.valid) & (pubkey.compressed):
+ return pubkey
+ if is_p2tr(vin.prevout):
+ witnessStack = vin.txinwitness.scriptWitness.stack
+ if (len(witnessStack) >= 1):
+ if (len(witnessStack) > 1 and witnessStack[-1][0] == 0x50):
+ # Last item is annex
+ witnessStack.pop()
+
+ if (len(witnessStack) > 1):
+ # Script-path spend
+ control_block = witnessStack[-1]
+ # control block is <32 byte internal key> and 0 or more <32 byte hash>
+ internal_key = control_block[1:33]
+ if (internal_key == NUMS_H.to_bytes(32, 'big')):
+ # Skip if NUMS_H
+ return ECPubKey()
+
+ pubkey = ECPubKey().set(vin.prevout[2:])
+ if (pubkey.valid) & (pubkey.compressed):
+ return pubkey
+
+
+ return ECPubKey()
+
+
+def get_input_hash(outpoints: List[COutPoint], sum_input_pubkeys: ECPubKey) -> bytes:
+ lowest_outpoint = sorted(outpoints, key=lambda outpoint: outpoint.serialize())[0]
+ return TaggedHash("BIP0352/Inputs", lowest_outpoint.serialize() + cast(bytes, sum_input_pubkeys.get_bytes(False)))
+
+
+
+def encode_silent_payment_address(B_scan: ECPubKey, B_m: ECPubKey, hrp: str = "tsp", version: int = 0) -> str:
+ data = convertbits(cast(bytes, B_scan.get_bytes(False)) + cast(bytes, B_m.get_bytes(False)), 8, 5)
+ return bech32_encode(hrp, [version] + cast(List[int], data), Encoding.BECH32M)
+
+
+def generate_label(b_scan: ECKey, m: int) -> bytes:
+ return TaggedHash("BIP0352/Label", b_scan.get_bytes() + ser_uint32(m))
+
+
+def create_labeled_silent_payment_address(b_scan: ECKey, B_spend: ECPubKey, m: int, hrp: str = "tsp", version: int = 0) -> str:
+ G = ECKey().set(1).get_pubkey()
+ B_scan = b_scan.get_pubkey()
+ B_m = B_spend + generate_label(b_scan, m) * G
+ labeled_address = encode_silent_payment_address(B_scan, B_m, hrp, version)
+
+ return labeled_address
+
+
+def decode_silent_payment_address(address: str, hrp: str = "tsp") -> Tuple[ECPubKey, ECPubKey]:
+ _, data = decode(hrp, address)
+ if data is None:
+ return ECPubKey(), ECPubKey()
+ B_scan = ECPubKey().set(data[:33])
+ B_spend = ECPubKey().set(data[33:])
+
+ return B_scan, B_spend
+
+
+def create_outputs(input_priv_keys: List[Tuple[ECKey, bool]], outpoints: List[COutPoint], recipients: List[str], hrp="tsp") -> List[str]:
+ G = ECKey().set(1).get_pubkey()
+ negated_keys = []
+ for key, is_xonly in input_priv_keys:
+ k = ECKey().set(key.get_bytes())
+ if is_xonly and k.get_pubkey().get_y() % 2 != 0:
+ k.negate()
+ negated_keys.append(k)
+
+ a_sum = sum(negated_keys)
+ if not a_sum.valid:
+ # Input privkeys sum is zero -> fail
+ return []
+ input_hash = get_input_hash(outpoints, a_sum * G)
+ silent_payment_groups: Dict[ECPubKey, List[ECPubKey]] = {}
+ for recipient in recipients:
+ B_scan, B_m = decode_silent_payment_address(recipient, hrp=hrp)
+ if B_scan in silent_payment_groups:
+ silent_payment_groups[B_scan].append(B_m)
+ else:
+ silent_payment_groups[B_scan] = [B_m]
+
+ outputs = []
+ for B_scan, B_m_values in silent_payment_groups.items():
+ ecdh_shared_secret = input_hash * a_sum * B_scan
+ k = 0
+ for B_m in B_m_values:
+ t_k = TaggedHash("BIP0352/SharedSecret", ecdh_shared_secret.get_bytes(False) + ser_uint32(k))
+ P_km = B_m + t_k * G
+ outputs.append(P_km.get_bytes().hex())
+ k += 1
+
+ return list(set(outputs))
+
+
+def scanning(b_scan: ECKey, B_spend: ECPubKey, A_sum: ECPubKey, input_hash: bytes, outputs_to_check: List[ECPubKey], labels: Dict[str, str] = {}) -> List[Dict[str, str]]:
+ G = ECKey().set(1).get_pubkey()
+ ecdh_shared_secret = input_hash * b_scan * A_sum
+ k = 0
+ wallet = []
+ while True:
+ t_k = TaggedHash("BIP0352/SharedSecret", ecdh_shared_secret.get_bytes(False) + ser_uint32(k))
+ P_k = B_spend + t_k * G
+ for output in outputs_to_check:
+ if P_k == output:
+ wallet.append({"pub_key": P_k.get_bytes().hex(), "priv_key_tweak": t_k.hex()})
+ outputs_to_check.remove(output)
+ k += 1
+ break
+ elif labels:
+ m_G_sub = output - P_k
+ if m_G_sub.get_bytes(False).hex() in labels:
+ P_km = P_k + m_G_sub
+ wallet.append({
+ "pub_key": P_km.get_bytes().hex(),
+ "priv_key_tweak": (ECKey().set(t_k).add(
+ bytes.fromhex(labels[m_G_sub.get_bytes(False).hex()])
+ )).get_bytes().hex(),
+ })
+ outputs_to_check.remove(output)
+ k += 1
+ break
+ else:
+ output.negate()
+ m_G_sub = output - P_k
+ if m_G_sub.get_bytes(False).hex() in labels:
+ P_km = P_k + m_G_sub
+ wallet.append({
+ "pub_key": P_km.get_bytes().hex(),
+ "priv_key_tweak": (ECKey().set(t_k).add(
+ bytes.fromhex(labels[m_G_sub.get_bytes(False).hex()])
+ )).get_bytes().hex(),
+ })
+ outputs_to_check.remove(output)
+ k += 1
+ break
+ else:
+ break
+ return wallet
+
+
+if __name__ == "__main__":
+ if len(argv) != 2 or argv[1] in ('-h', '--help'):
+ print("Usage: ./reference.py send_and_receive_test_vectors.json")
+ exit(0)
+
+ with open(argv[1], "r") as f:
+ test_data = json.loads(f.read())
+
+ # G , needed for generating the labels "database"
+ G = ECKey().set(1).get_pubkey()
+ for case in test_data:
+ print(case["comment"])
+ # Test sending
+ for sending_test in case["sending"]:
+ given = sending_test["given"]
+ expected = sending_test["expected"]
+
+ vins = [
+ VinInfo(
+ outpoint=COutPoint(hash=deser_txid(input["txid"]), n=input["vout"]),
+ scriptSig=bytes.fromhex(input["scriptSig"]),
+ txinwitness=CTxInWitness().deserialize(from_hex(input["txinwitness"])),
+ prevout=bytes.fromhex(input["prevout"]["scriptPubKey"]["hex"]),
+ private_key=ECKey().set(bytes.fromhex(input["private_key"])),
+ )
+ for input in given["vin"]
+ ]
+ # Convert the tuples to lists so they can be easily compared to the json list of lists from the given test vectors
+ input_priv_keys = []
+ input_pub_keys = []
+ for vin in vins:
+ pubkey = get_pubkey_from_input(vin)
+ if not pubkey.valid:
+ continue
+ input_priv_keys.append((
+ vin.private_key,
+ is_p2tr(vin.prevout),
+ ))
+ input_pub_keys.append(pubkey)
+
+ sending_outputs = []
+ if (len(input_pub_keys) > 0):
+ outpoints = [vin.outpoint for vin in vins]
+ sending_outputs = create_outputs(input_priv_keys, outpoints, given["recipients"], hrp="sp")
+
+ # Note: order doesn't matter for creating/finding the outputs. However, different orderings of the recipient addresses
+ # will produce different generated outputs if sending to multiple silent payment addresses belonging to the
+ # same sender but with different labels. Because of this, expected["outputs"] contains all possible valid output sets,
+ # based on all possible permutations of recipient address orderings. Must match exactly one of the possible output sets.
+ assert(any(set(sending_outputs) == set(lst) for lst in expected["outputs"])), "Sending test failed"
+ else:
+ assert(sending_outputs == expected["outputs"][0] == []), "Sending test failed"
+
+ # Test receiving
+ msg = hashlib.sha256(b"message").digest()
+ aux = hashlib.sha256(b"random auxiliary data").digest()
+ for receiving_test in case["receiving"]:
+ given = receiving_test["given"]
+ expected = receiving_test["expected"]
+ outputs_to_check = [
+ ECPubKey().set(bytes.fromhex(p)) for p in given["outputs"]
+ ]
+ vins = [
+ VinInfo(
+ outpoint=COutPoint(hash=deser_txid(input["txid"]), n=input["vout"]),
+ scriptSig=bytes.fromhex(input["scriptSig"]),
+ txinwitness=CTxInWitness().deserialize(from_hex(input["txinwitness"])),
+ prevout=bytes.fromhex(input["prevout"]["scriptPubKey"]["hex"]),
+ )
+ for input in given["vin"]
+ ]
+ # Check that the given inputs for the receiving test match what was generated during the sending test
+ receiving_addresses = []
+ b_scan = ECKey().set(bytes.fromhex(given["key_material"]["scan_priv_key"]))
+ b_spend = ECKey().set(
+ bytes.fromhex(given["key_material"]["spend_priv_key"])
+ )
+ B_scan = b_scan.get_pubkey()
+ B_spend = b_spend.get_pubkey()
+ receiving_addresses.append(
+ encode_silent_payment_address(B_scan, B_spend, hrp="sp")
+ )
+ if given["labels"]:
+ for label in given["labels"]:
+ receiving_addresses.append(
+ create_labeled_silent_payment_address(
+ b_scan, B_spend, m=label, hrp="sp"
+ )
+ )
+
+ # Check that the silent payment addresses match for the given BIP32 seed and labels dictionary
+ assert (receiving_addresses == expected["addresses"]), "Receiving addresses don't match"
+ input_pub_keys = []
+ for vin in vins:
+ pubkey = get_pubkey_from_input(vin)
+ if not pubkey.valid:
+ continue
+ input_pub_keys.append(pubkey)
+
+ add_to_wallet = []
+ if (len(input_pub_keys) > 0):
+ A_sum = reduce(lambda x, y: x + y, input_pub_keys)
+ if A_sum.get_bytes() is None:
+ # Input pubkeys sum is point at infinity -> skip tx
+ assert expected["outputs"] == []
+ continue
+ input_hash = get_input_hash([vin.outpoint for vin in vins], A_sum)
+ pre_computed_labels = {
+ (generate_label(b_scan, label) * G).get_bytes(False).hex(): generate_label(b_scan, label).hex()
+ for label in given["labels"]
+ }
+ add_to_wallet = scanning(
+ b_scan=b_scan,
+ B_spend=B_spend,
+ A_sum=A_sum,
+ input_hash=input_hash,
+ outputs_to_check=outputs_to_check,
+ labels=pre_computed_labels,
+ )
+
+ # Check that the private key is correct for the found output public key
+ for output in add_to_wallet:
+ pub_key = ECPubKey().set(bytes.fromhex(output["pub_key"]))
+ full_private_key = b_spend.add(bytes.fromhex(output["priv_key_tweak"]))
+ if full_private_key.get_pubkey().get_y() % 2 != 0:
+ full_private_key.negate()
+
+ sig = full_private_key.sign_schnorr(msg, aux)
+ assert pub_key.verify_schnorr(sig, msg), f"Invalid signature for {pub_key}"
+ output["signature"] = sig.hex()
+
+ # Note: order doesn't matter for creating/finding the outputs. However, different orderings of the recipient addresses
+ # will produce different generated outputs if sending to multiple silent payment addresses belonging to the
+ # same sender but with different labels. Because of this, expected["outputs"] contains all possible valid output sets,
+ # based on all possible permutations of recipient address orderings. Must match exactly one of the possible found output
+ # sets in expected["outputs"]
+ generated_set = {frozenset(d.items()) for d in add_to_wallet}
+ expected_set = {frozenset(d.items()) for d in expected["outputs"]}
+ assert generated_set == expected_set, "Receive test failed"
+
+
+ print("All tests passed")
diff --git a/bip-0352/ripemd160.py b/bip-0352/ripemd160.py
new file mode 100644
index 0000000000..12801364b4
--- /dev/null
+++ b/bip-0352/ripemd160.py
@@ -0,0 +1,130 @@
+# Copyright (c) 2021 Pieter Wuille
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test-only pure Python RIPEMD160 implementation."""
+
+import unittest
+
+# Message schedule indexes for the left path.
+ML = [
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
+ 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
+ 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
+ 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
+]
+
+# Message schedule indexes for the right path.
+MR = [
+ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
+ 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
+ 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
+ 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
+ 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
+]
+
+# Rotation counts for the left path.
+RL = [
+ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
+ 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
+ 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
+ 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
+ 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
+]
+
+# Rotation counts for the right path.
+RR = [
+ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
+ 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
+ 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
+ 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
+ 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
+]
+
+# K constants for the left path.
+KL = [0, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]
+
+# K constants for the right path.
+KR = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0]
+
+
+def fi(x, y, z, i):
+ """The f1, f2, f3, f4, and f5 functions from the specification."""
+ if i == 0:
+ return x ^ y ^ z
+ elif i == 1:
+ return (x & y) | (~x & z)
+ elif i == 2:
+ return (x | ~y) ^ z
+ elif i == 3:
+ return (x & z) | (y & ~z)
+ elif i == 4:
+ return x ^ (y | ~z)
+ else:
+ assert False
+
+
+def rol(x, i):
+ """Rotate the bottom 32 bits of x left by i bits."""
+ return ((x << i) | ((x & 0xffffffff) >> (32 - i))) & 0xffffffff
+
+
+def compress(h0, h1, h2, h3, h4, block):
+ """Compress state (h0, h1, h2, h3, h4) with block."""
+ # Left path variables.
+ al, bl, cl, dl, el = h0, h1, h2, h3, h4
+ # Right path variables.
+ ar, br, cr, dr, er = h0, h1, h2, h3, h4
+ # Message variables.
+ x = [int.from_bytes(block[4*i:4*(i+1)], 'little') for i in range(16)]
+
+ # Iterate over the 80 rounds of the compression.
+ for j in range(80):
+ rnd = j >> 4
+ # Perform left side of the transformation.
+ al = rol(al + fi(bl, cl, dl, rnd) + x[ML[j]] + KL[rnd], RL[j]) + el
+ al, bl, cl, dl, el = el, al, bl, rol(cl, 10), dl
+ # Perform right side of the transformation.
+ ar = rol(ar + fi(br, cr, dr, 4 - rnd) + x[MR[j]] + KR[rnd], RR[j]) + er
+ ar, br, cr, dr, er = er, ar, br, rol(cr, 10), dr
+
+ # Compose old state, left transform, and right transform into new state.
+ return h1 + cl + dr, h2 + dl + er, h3 + el + ar, h4 + al + br, h0 + bl + cr
+
+
+def ripemd160(data):
+ """Compute the RIPEMD-160 hash of data."""
+ # Initialize state.
+ state = (0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0)
+ # Process full 64-byte blocks in the input.
+ for b in range(len(data) >> 6):
+ state = compress(*state, data[64*b:64*(b+1)])
+ # Construct final blocks (with padding and size).
+ pad = b"\x80" + b"\x00" * ((119 - len(data)) & 63)
+ fin = data[len(data) & ~63:] + pad + (8 * len(data)).to_bytes(8, 'little')
+ # Process final blocks.
+ for b in range(len(fin) >> 6):
+ state = compress(*state, fin[64*b:64*(b+1)])
+ # Produce output.
+ return b"".join((h & 0xffffffff).to_bytes(4, 'little') for h in state)
+
+
+class TestFrameworkKey(unittest.TestCase):
+ def test_ripemd160(self):
+ """RIPEMD-160 test vectors."""
+ # See https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
+ for msg, hexout in [
+ (b"", "9c1185a5c5e9fc54612808977ee8f548b2258d31"),
+ (b"a", "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"),
+ (b"abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"),
+ (b"message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36"),
+ (b"abcdefghijklmnopqrstuvwxyz",
+ "f71c27109c692c1b56bbdceb5b9d2865b3708dbc"),
+ (b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "12a053384a9c0c88e405a06c27dcf49ada62eb2b"),
+ (b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "b0e20b6e3116640286ed3a87a5713079b21f5189"),
+ (b"1234567890" * 8, "9b752e45573d4b39f4dbd3323cab82bf63326bfb"),
+ (b"a" * 1000000, "52783243c1697bdbe16d37f97f68f08325dc1528")
+ ]:
+ self.assertEqual(ripemd160(msg).hex(), hexout)
diff --git a/bip-0352/scan_data_downloader_per_month.png b/bip-0352/scan_data_downloader_per_month.png
new file mode 100644
index 0000000000..a672a91add
Binary files /dev/null and b/bip-0352/scan_data_downloader_per_month.png differ
diff --git a/bip-0352/secp256k1.py b/bip-0352/secp256k1.py
new file mode 100644
index 0000000000..0ccbc4e6a4
--- /dev/null
+++ b/bip-0352/secp256k1.py
@@ -0,0 +1,696 @@
+# Copyright (c) 2019 Pieter Wuille
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test-only secp256k1 elliptic curve implementation
+
+WARNING: This code is slow, uses bad randomness, does not properly protect
+keys, and is trivially vulnerable to side channel attacks. Do not use for
+anything but tests."""
+import random
+import hashlib
+import hmac
+
+def TaggedHash(tag, data):
+ ss = hashlib.sha256(tag.encode('utf-8')).digest()
+ ss += ss
+ ss += data
+ return hashlib.sha256(ss).digest()
+
+def modinv(a, n):
+ """Compute the modular inverse of a modulo n
+
+ See https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers.
+ """
+ t1, t2 = 0, 1
+ r1, r2 = n, a
+ while r2 != 0:
+ q = r1 // r2
+ t1, t2 = t2, t1 - q * t2
+ r1, r2 = r2, r1 - q * r2
+ if r1 > 1:
+ return None
+ if t1 < 0:
+ t1 += n
+ return t1
+
+def jacobi_symbol(n, k):
+ """Compute the Jacobi symbol of n modulo k
+
+ See http://en.wikipedia.org/wiki/Jacobi_symbol
+
+ For our application k is always prime, so this is the same as the Legendre symbol."""
+ assert k > 0 and k & 1, "jacobi symbol is only defined for positive odd k"
+ n %= k
+ t = 0
+ while n != 0:
+ while n & 1 == 0:
+ n >>= 1
+ r = k & 7
+ t ^= (r == 3 or r == 5)
+ n, k = k, n
+ t ^= (n & k & 3 == 3)
+ n = n % k
+ if k == 1:
+ return -1 if t else 1
+ return 0
+
+def modsqrt(a, p):
+ """Compute the square root of a modulo p when p % 4 = 3.
+
+ The Tonelli-Shanks algorithm can be used. See https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm
+
+ Limiting this function to only work for p % 4 = 3 means we don't need to
+ iterate through the loop. The highest n such that p - 1 = 2^n Q with Q odd
+ is n = 1. Therefore Q = (p-1)/2 and sqrt = a^((Q+1)/2) = a^((p+1)/4)
+
+ secp256k1's is defined over field of size 2**256 - 2**32 - 977, which is 3 mod 4.
+ """
+ if p % 4 != 3:
+ raise NotImplementedError("modsqrt only implemented for p % 4 = 3")
+ sqrt = pow(a, (p + 1)//4, p)
+ if pow(sqrt, 2, p) == a % p:
+ return sqrt
+ return None
+
+def int_or_bytes(s):
+ "Convert 32-bytes to int while accepting also int and returning it as is."
+ if isinstance(s, bytes):
+ assert(len(s) == 32)
+ s = int.from_bytes(s, 'big')
+ elif not isinstance(s, int):
+ raise TypeError
+ return s
+
+class EllipticCurve:
+ def __init__(self, p, a, b):
+ """Initialize elliptic curve y^2 = x^3 + a*x + b over GF(p)."""
+ self.p = p
+ self.a = a % p
+ self.b = b % p
+
+ def affine(self, p1):
+ """Convert a Jacobian point tuple p1 to affine form, or None if at infinity.
+
+ An affine point is represented as the Jacobian (x, y, 1)"""
+ x1, y1, z1 = p1
+ if z1 == 0:
+ return None
+ inv = modinv(z1, self.p)
+ inv_2 = (inv**2) % self.p
+ inv_3 = (inv_2 * inv) % self.p
+ return ((inv_2 * x1) % self.p, (inv_3 * y1) % self.p, 1)
+
+ def has_even_y(self, p1):
+ """Whether the point p1 has an even Y coordinate when expressed in affine coordinates."""
+ return not (p1[2] == 0 or self.affine(p1)[1] & 1)
+
+ def negate(self, p1):
+ """Negate a Jacobian point tuple p1."""
+ x1, y1, z1 = p1
+ return (x1, (self.p - y1) % self.p, z1)
+
+ def on_curve(self, p1):
+ """Determine whether a Jacobian tuple p is on the curve (and not infinity)"""
+ x1, y1, z1 = p1
+ z2 = pow(z1, 2, self.p)
+ z4 = pow(z2, 2, self.p)
+ return z1 != 0 and (pow(x1, 3, self.p) + self.a * x1 * z4 + self.b * z2 * z4 - pow(y1, 2, self.p)) % self.p == 0
+
+ def is_x_coord(self, x):
+ """Test whether x is a valid X coordinate on the curve."""
+ x_3 = pow(x, 3, self.p)
+ return jacobi_symbol(x_3 + self.a * x + self.b, self.p) != -1
+
+ def lift_x(self, x):
+ """Given an X coordinate on the curve, return a corresponding affine point."""
+ x_3 = pow(x, 3, self.p)
+ v = x_3 + self.a * x + self.b
+ y = modsqrt(v, self.p)
+ if y is None:
+ return None
+ return (x, y, 1)
+
+ def double(self, p1):
+ """Double a Jacobian tuple p1
+
+ See https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates - Point Doubling"""
+ x1, y1, z1 = p1
+ if z1 == 0:
+ return (0, 1, 0)
+ y1_2 = (y1**2) % self.p
+ y1_4 = (y1_2**2) % self.p
+ x1_2 = (x1**2) % self.p
+ s = (4*x1*y1_2) % self.p
+ m = 3*x1_2
+ if self.a:
+ m += self.a * pow(z1, 4, self.p)
+ m = m % self.p
+ x2 = (m**2 - 2*s) % self.p
+ y2 = (m*(s - x2) - 8*y1_4) % self.p
+ z2 = (2*y1*z1) % self.p
+ return (x2, y2, z2)
+
+ def add_mixed(self, p1, p2):
+ """Add a Jacobian tuple p1 and an affine tuple p2
+
+ See https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates - Point Addition (with affine point)"""
+ x1, y1, z1 = p1
+ x2, y2, z2 = p2
+ assert(z2 == 1)
+ # Adding to the point at infinity is a no-op
+ if z1 == 0:
+ return p2
+ z1_2 = (z1**2) % self.p
+ z1_3 = (z1_2 * z1) % self.p
+ u2 = (x2 * z1_2) % self.p
+ s2 = (y2 * z1_3) % self.p
+ if x1 == u2:
+ if (y1 != s2):
+ # p1 and p2 are inverses. Return the point at infinity.
+ return (0, 1, 0)
+ # p1 == p2. The formulas below fail when the two points are equal.
+ return self.double(p1)
+ h = u2 - x1
+ r = s2 - y1
+ h_2 = (h**2) % self.p
+ h_3 = (h_2 * h) % self.p
+ u1_h_2 = (x1 * h_2) % self.p
+ x3 = (r**2 - h_3 - 2*u1_h_2) % self.p
+ y3 = (r*(u1_h_2 - x3) - y1*h_3) % self.p
+ z3 = (h*z1) % self.p
+ return (x3, y3, z3)
+
+ def add(self, p1, p2):
+ """Add two Jacobian tuples p1 and p2
+
+ See https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates - Point Addition"""
+ x1, y1, z1 = p1
+ x2, y2, z2 = p2
+ # Adding the point at infinity is a no-op
+ if z1 == 0:
+ return p2
+ if z2 == 0:
+ return p1
+ # Adding an Affine to a Jacobian is more efficient since we save field multiplications and squarings when z = 1
+ if z1 == 1:
+ return self.add_mixed(p2, p1)
+ if z2 == 1:
+ return self.add_mixed(p1, p2)
+ z1_2 = (z1**2) % self.p
+ z1_3 = (z1_2 * z1) % self.p
+ z2_2 = (z2**2) % self.p
+ z2_3 = (z2_2 * z2) % self.p
+ u1 = (x1 * z2_2) % self.p
+ u2 = (x2 * z1_2) % self.p
+ s1 = (y1 * z2_3) % self.p
+ s2 = (y2 * z1_3) % self.p
+ if u1 == u2:
+ if (s1 != s2):
+ # p1 and p2 are inverses. Return the point at infinity.
+ return (0, 1, 0)
+ # p1 == p2. The formulas below fail when the two points are equal.
+ return self.double(p1)
+ h = u2 - u1
+ r = s2 - s1
+ h_2 = (h**2) % self.p
+ h_3 = (h_2 * h) % self.p
+ u1_h_2 = (u1 * h_2) % self.p
+ x3 = (r**2 - h_3 - 2*u1_h_2) % self.p
+ y3 = (r*(u1_h_2 - x3) - s1*h_3) % self.p
+ z3 = (h*z1*z2) % self.p
+ return (x3, y3, z3)
+
+ def mul(self, ps):
+ """Compute a (multi) point multiplication
+
+ ps is a list of (Jacobian tuple, scalar) pairs.
+ """
+ r = (0, 1, 0)
+ for i in range(255, -1, -1):
+ r = self.double(r)
+ for (p, n) in ps:
+ if ((n >> i) & 1):
+ r = self.add(r, p)
+ return r
+
+SECP256K1_FIELD_SIZE = 2**256 - 2**32 - 977
+SECP256K1 = EllipticCurve(SECP256K1_FIELD_SIZE, 0, 7)
+SECP256K1_G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8, 1)
+SECP256K1_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
+SECP256K1_ORDER_HALF = SECP256K1_ORDER // 2
+NUMS_H = 0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0
+
+class ECPubKey():
+ """A secp256k1 public key"""
+
+ def __init__(self):
+ """Construct an uninitialized public key"""
+ self.valid = False
+
+ def __repr__(self):
+ return self.get_bytes().hex()
+
+ def __eq__(self, other):
+ assert isinstance(other, ECPubKey)
+ return self.get_bytes() == other.get_bytes()
+
+ def __hash__(self):
+ return hash(self.get_bytes())
+
+ def set(self, data):
+ """Construct a public key from a serialization in compressed or uncompressed DER format or BIP340 format"""
+ if (len(data) == 65 and data[0] == 0x04):
+ p = (int.from_bytes(data[1:33], 'big'), int.from_bytes(data[33:65], 'big'), 1)
+ self.valid = SECP256K1.on_curve(p)
+ if self.valid:
+ self.p = p
+ self.compressed = False
+ elif (len(data) == 33 and (data[0] == 0x02 or data[0] == 0x03)):
+ x = int.from_bytes(data[1:33], 'big')
+ if SECP256K1.is_x_coord(x):
+ p = SECP256K1.lift_x(x)
+ # if the oddness of the y co-ord isn't correct, find the other
+ # valid y
+ if (p[1] & 1) != (data[0] & 1):
+ p = SECP256K1.negate(p)
+ self.p = p
+ self.valid = True
+ self.compressed = True
+ else:
+ self.valid = False
+ elif (len(data) == 32):
+ x = int.from_bytes(data[0:32], 'big')
+ if SECP256K1.is_x_coord(x):
+ p = SECP256K1.lift_x(x)
+ # if the oddness of the y co-ord isn't correct, find the other
+ # valid y
+ if p[1]%2 != 0:
+ p = SECP256K1.negate(p)
+ self.p = p
+ self.valid = True
+ self.compressed = True
+ else:
+ self.valid = False
+ else:
+ self.valid = False
+ return self
+
+ @property
+ def is_compressed(self):
+ return self.compressed
+
+ @property
+ def is_valid(self):
+ return self.valid
+
+ def get_y(self):
+ return SECP256K1.affine(self.p)[1]
+
+ def get_x(self):
+ return SECP256K1.affine(self.p)[0]
+
+ def get_bytes(self, bip340=True):
+ assert(self.valid)
+ p = SECP256K1.affine(self.p)
+ if p is None:
+ return None
+ if bip340:
+ return bytes(p[0].to_bytes(32, 'big'))
+ elif self.compressed:
+ return bytes([0x02 + (p[1] & 1)]) + p[0].to_bytes(32, 'big')
+ else:
+ return bytes([0x04]) + p[0].to_bytes(32, 'big') + p[1].to_bytes(32, 'big')
+
+ def verify_ecdsa(self, sig, msg, low_s=True):
+ """Verify a strictly DER-encoded ECDSA signature against this pubkey.
+
+ See https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm for the
+ ECDSA verifier algorithm"""
+ assert(self.valid)
+
+ # Extract r and s from the DER formatted signature. Return false for
+ # any DER encoding errors.
+ if (sig[1] + 2 != len(sig)):
+ return False
+ if (len(sig) < 4):
+ return False
+ if (sig[0] != 0x30):
+ return False
+ if (sig[2] != 0x02):
+ return False
+ rlen = sig[3]
+ if (len(sig) < 6 + rlen):
+ return False
+ if rlen < 1 or rlen > 33:
+ return False
+ if sig[4] >= 0x80:
+ return False
+ if (rlen > 1 and (sig[4] == 0) and not (sig[5] & 0x80)):
+ return False
+ r = int.from_bytes(sig[4:4+rlen], 'big')
+ if (sig[4+rlen] != 0x02):
+ return False
+ slen = sig[5+rlen]
+ if slen < 1 or slen > 33:
+ return False
+ if (len(sig) != 6 + rlen + slen):
+ return False
+ if sig[6+rlen] >= 0x80:
+ return False
+ if (slen > 1 and (sig[6+rlen] == 0) and not (sig[7+rlen] & 0x80)):
+ return False
+ s = int.from_bytes(sig[6+rlen:6+rlen+slen], 'big')
+
+ # Verify that r and s are within the group order
+ if r < 1 or s < 1 or r >= SECP256K1_ORDER or s >= SECP256K1_ORDER:
+ return False
+ if low_s and s >= SECP256K1_ORDER_HALF:
+ return False
+ z = int.from_bytes(msg, 'big')
+
+ # Run verifier algorithm on r, s
+ w = modinv(s, SECP256K1_ORDER)
+ u1 = z*w % SECP256K1_ORDER
+ u2 = r*w % SECP256K1_ORDER
+ R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, u1), (self.p, u2)]))
+ if R is None or R[0] != r:
+ return False
+ return True
+
+ def verify_schnorr(self, sig, msg):
+ assert(len(msg) == 32)
+ assert(len(sig) == 64)
+ assert(self.valid)
+ r = int.from_bytes(sig[0:32], 'big')
+ if r >= SECP256K1_FIELD_SIZE:
+ return False
+ s = int.from_bytes(sig[32:64], 'big')
+ if s >= SECP256K1_ORDER:
+ return False
+ e = int.from_bytes(TaggedHash("BIP0340/challenge", sig[0:32] + self.get_bytes() + msg), 'big') % SECP256K1_ORDER
+ R = SECP256K1.mul([(SECP256K1_G, s), (self.p, SECP256K1_ORDER - e)])
+ if not SECP256K1.has_even_y(R):
+ return False
+ if ((r * R[2] * R[2]) % SECP256K1_FIELD_SIZE) != R[0]:
+ return False
+ return True
+
+ def __add__(self, other):
+ """Adds two ECPubKey points."""
+ assert isinstance(other, ECPubKey)
+ assert self.valid
+ assert other.valid
+ ret = ECPubKey()
+ ret.p = SECP256K1.add(other.p, self.p)
+ ret.valid = True
+ ret.compressed = self.compressed
+ return ret
+
+ def __radd__(self, other):
+ """Allows this ECPubKey to be added to 0 for sum()"""
+ if other == 0:
+ return self
+ else:
+ return self + other
+
+ def __mul__(self, other):
+ """Multiplies ECPubKey point with a scalar(int/32bytes/ECKey)."""
+ if isinstance(other, ECKey):
+ assert self.valid
+ assert other.secret is not None
+ multiplier = other.secret
+ else:
+ # int_or_bytes checks that other is `int` or `bytes`
+ multiplier = int_or_bytes(other)
+
+ assert multiplier < SECP256K1_ORDER
+ multiplier = multiplier % SECP256K1_ORDER
+ ret = ECPubKey()
+ ret.p = SECP256K1.mul([(self.p, multiplier)])
+ ret.valid = True
+ ret.compressed = self.compressed
+ return ret
+
+ def __rmul__(self, other):
+ """Multiplies a scalar(int/32bytes/ECKey) with an ECPubKey point"""
+ return self * other
+
+ def __sub__(self, other):
+ """Subtract one point from another"""
+ assert isinstance(other, ECPubKey)
+ assert self.valid
+ assert other.valid
+ ret = ECPubKey()
+ ret.p = SECP256K1.add(self.p, SECP256K1.negate(other.p))
+ ret.valid = True
+ ret.compressed = self.compressed
+ return ret
+
+ def tweak_add(self, tweak):
+ assert(self.valid)
+ t = int_or_bytes(tweak)
+ if t >= SECP256K1_ORDER:
+ return None
+ tweaked = SECP256K1.affine(SECP256K1.mul([(self.p, 1), (SECP256K1_G, t)]))
+ if tweaked is None:
+ return None
+ ret = ECPubKey()
+ ret.p = tweaked
+ ret.valid = True
+ ret.compressed = self.compressed
+ return ret
+
+ def mul(self, data):
+ """Multiplies ECPubKey point with scalar data."""
+ assert self.valid
+ other = ECKey()
+ other.set(data, True)
+ return self * other
+
+ def negate(self):
+ self.p = SECP256K1.affine(SECP256K1.negate(self.p))
+
+def rfc6979_nonce(key):
+ """Compute signing nonce using RFC6979."""
+ v = bytes([1] * 32)
+ k = bytes([0] * 32)
+ k = hmac.new(k, v + b"\x00" + key, 'sha256').digest()
+ v = hmac.new(k, v, 'sha256').digest()
+ k = hmac.new(k, v + b"\x01" + key, 'sha256').digest()
+ v = hmac.new(k, v, 'sha256').digest()
+ return hmac.new(k, v, 'sha256').digest()
+
+class ECKey():
+ """A secp256k1 private key"""
+
+ def __init__(self):
+ self.valid = False
+
+ def __repr__(self):
+ return str(self.secret)
+
+ def __eq__(self, other):
+ assert isinstance(other, ECKey)
+ return self.secret == other.secret
+
+ def __hash__(self):
+ return hash(self.secret)
+
+ def set(self, secret, compressed=True):
+ """Construct a private key object from either 32-bytes or an int secret and a compressed flag."""
+ secret = int_or_bytes(secret)
+
+ self.valid = (secret > 0 and secret < SECP256K1_ORDER)
+ if self.valid:
+ self.secret = secret
+ self.compressed = compressed
+ return self
+
+ def generate(self, compressed=True):
+ """Generate a random private key (compressed or uncompressed)."""
+ self.set(random.randrange(1, SECP256K1_ORDER).to_bytes(32, 'big'), compressed)
+ return self
+
+ def get_bytes(self):
+ """Retrieve the 32-byte representation of this key."""
+ assert(self.valid)
+ return self.secret.to_bytes(32, 'big')
+
+ def as_int(self):
+ return self.secret
+
+ def from_int(self, secret, compressed=True):
+ self.valid = (secret > 0 and secret < SECP256K1_ORDER)
+ if self.valid:
+ self.secret = secret
+ self.compressed = compressed
+
+ def __add__(self, other):
+ """Add key secrets. Returns compressed key."""
+ assert isinstance(other, ECKey)
+ assert other.secret > 0 and other.secret < SECP256K1_ORDER
+ assert self.valid is True
+ ret_data = ((self.secret + other.secret) % SECP256K1_ORDER).to_bytes(32, 'big')
+ ret = ECKey()
+ ret.set(ret_data, True)
+ return ret
+
+ def __radd__(self, other):
+ """Allows this ECKey to be added to 0 for sum()"""
+ if other == 0:
+ return self
+ else:
+ return self + other
+
+ def __sub__(self, other):
+ """Subtract key secrets. Returns compressed key."""
+ assert isinstance(other, ECKey)
+ assert other.secret > 0 and other.secret < SECP256K1_ORDER
+ assert self.valid is True
+ ret_data = ((self.secret - other.secret) % SECP256K1_ORDER).to_bytes(32, 'big')
+ ret = ECKey()
+ ret.set(ret_data, True)
+ return ret
+
+ def __mul__(self, other):
+ """Multiply a private key by another private key or multiply a public key by a private key. Returns compressed key."""
+ if isinstance(other, ECKey):
+ assert other.secret > 0 and other.secret < SECP256K1_ORDER
+ assert self.valid is True
+ ret_data = ((self.secret * other.secret) % SECP256K1_ORDER).to_bytes(32, 'big')
+ ret = ECKey()
+ ret.set(ret_data, True)
+ return ret
+ elif isinstance(other, ECPubKey):
+ return other * self
+ else:
+ # ECKey().set() checks that other is an `int` or `bytes`
+ assert self.valid
+ second = ECKey().set(other, self.compressed)
+ return self * second
+
+ def __rmul__(self, other):
+ return self * other
+
+ def add(self, data):
+ """Add key to scalar data. Returns compressed key."""
+ other = ECKey()
+ other.set(data, True)
+ return self + other
+
+ def mul(self, data):
+ """Multiply key secret with scalar data. Returns compressed key."""
+ other = ECKey()
+ other.set(data, True)
+ return self * other
+
+ def negate(self):
+ """Negate a private key."""
+ assert self.valid
+ self.secret = SECP256K1_ORDER - self.secret
+
+ @property
+ def is_valid(self):
+ return self.valid
+
+ @property
+ def is_compressed(self):
+ return self.compressed
+
+ def get_pubkey(self):
+ """Compute an ECPubKey object for this secret key."""
+ assert(self.valid)
+ ret = ECPubKey()
+ p = SECP256K1.mul([(SECP256K1_G, self.secret)])
+ ret.p = p
+ ret.valid = True
+ ret.compressed = self.compressed
+ return ret
+
+ def sign_ecdsa(self, msg, low_s=True, rfc6979=False):
+ """Construct a DER-encoded ECDSA signature with this key.
+
+ See https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm for the
+ ECDSA signer algorithm."""
+ assert(self.valid)
+ z = int.from_bytes(msg, 'big')
+ # Note: no RFC6979 by default, but a simple random nonce (some tests rely on distinct transactions for the same operation)
+ if rfc6979:
+ k = int.from_bytes(rfc6979_nonce(self.secret.to_bytes(32, 'big') + msg), 'big')
+ else:
+ k = random.randrange(1, SECP256K1_ORDER)
+ R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, k)]))
+ r = R[0] % SECP256K1_ORDER
+ s = (modinv(k, SECP256K1_ORDER) * (z + self.secret * r)) % SECP256K1_ORDER
+ if low_s and s > SECP256K1_ORDER_HALF:
+ s = SECP256K1_ORDER - s
+ # Represent in DER format. The byte representations of r and s have
+ # length rounded up (255 bits becomes 32 bytes and 256 bits becomes 33
+ # bytes).
+ rb = r.to_bytes((r.bit_length() + 8) // 8, 'big')
+ sb = s.to_bytes((s.bit_length() + 8) // 8, 'big')
+ return b'\x30' + bytes([4 + len(rb) + len(sb), 2, len(rb)]) + rb + bytes([2, len(sb)]) + sb
+
+ def sign_schnorr(self, msg, aux=None):
+ """Create a Schnorr signature (see BIP340)."""
+ if aux is None:
+ aux = bytes(32)
+
+ assert self.valid
+ assert len(msg) == 32
+ assert len(aux) == 32
+
+ t = (self.secret ^ int.from_bytes(TaggedHash("BIP0340/aux", aux), 'big')).to_bytes(32, 'big')
+ kp = int.from_bytes(TaggedHash("BIP0340/nonce", t + self.get_pubkey().get_bytes() + msg), 'big') % SECP256K1_ORDER
+ assert kp != 0
+ R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, kp)]))
+ k = kp if SECP256K1.has_even_y(R) else SECP256K1_ORDER - kp
+ e = int.from_bytes(TaggedHash("BIP0340/challenge", R[0].to_bytes(32, 'big') + self.get_pubkey().get_bytes() + msg), 'big') % SECP256K1_ORDER
+ return R[0].to_bytes(32, 'big') + ((k + e * self.secret) % SECP256K1_ORDER).to_bytes(32, 'big')
+
+ def tweak_add(self, tweak):
+ """Return a tweaked version of this private key."""
+ assert(self.valid)
+ t = int_or_bytes(tweak)
+ if t >= SECP256K1_ORDER:
+ return None
+ tweaked = (self.secret + t) % SECP256K1_ORDER
+ if tweaked == 0:
+ return None
+ ret = ECKey()
+ ret.set(tweaked.to_bytes(32, 'big'), self.compressed)
+ return ret
+
+def generate_key_pair(secret=None, compressed=True):
+ """Convenience function to generate a private-public key pair."""
+ d = ECKey()
+ if secret:
+ d.set(secret, compressed)
+ else:
+ d.generate(compressed)
+
+ P = d.get_pubkey()
+ return d, P
+
+def generate_bip340_key_pair():
+ """Convenience function to generate a BIP0340 private-public key pair."""
+ d = ECKey()
+ d.generate()
+ P = d.get_pubkey()
+ if P.get_y()%2 != 0:
+ d.negate()
+ P.negate()
+ return d, P
+
+def generate_schnorr_nonce():
+ """Generate a random valid BIP340 nonce.
+
+ See https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki.
+ This implementation ensures the y-coordinate of the nonce point is even."""
+ kp = random.randrange(1, SECP256K1_ORDER)
+ assert kp != 0
+ R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, kp)]))
+ k = kp if R[1] % 2 == 0 else SECP256K1_ORDER - kp
+ k_key = ECKey()
+ k_key.set(k.to_bytes(32, 'big'), True)
+ return k_key
diff --git a/bip-0352/send_and_receive_test_vectors.json b/bip-0352/send_and_receive_test_vectors.json
new file mode 100644
index 0000000000..264f7becb5
--- /dev/null
+++ b/bip-0352/send_and_receive_test_vectors.json
@@ -0,0 +1,2760 @@
+[
+ {
+ "comment": "Simple send: two inputs",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ },
+ "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "f438b40179a3c4262de12986c0e6cce0634007cdc79c1dcd3e20b9ebc2e7eef6",
+ "pub_key": "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1",
+ "signature": "74f85b856337fbe837643b86f462118159f93ac4acc2671522f27e8f67b079959195ccc7a5dbee396d2909f5d680d6e30cda7359aa2755822509b70d6b0687a1"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Simple send: two inputs, order reversed",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ },
+ "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "f438b40179a3c4262de12986c0e6cce0634007cdc79c1dcd3e20b9ebc2e7eef6",
+ "pub_key": "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1",
+ "signature": "74f85b856337fbe837643b86f462118159f93ac4acc2671522f27e8f67b079959195ccc7a5dbee396d2909f5d680d6e30cda7359aa2755822509b70d6b0687a1"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Simple send: two inputs from the same transaction",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 3,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 7,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ },
+ "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "79e71baa2ba3fc66396de3a04f168c7bf24d6870ec88ca877754790c1db357b6"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 3,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 7,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "79e71baa2ba3fc66396de3a04f168c7bf24d6870ec88ca877754790c1db357b6"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "4851455bfbe1ab4f80156570aa45063201aa5c9e1b1dcd29f0f8c33d10bf77ae",
+ "pub_key": "79e71baa2ba3fc66396de3a04f168c7bf24d6870ec88ca877754790c1db357b6",
+ "signature": "10332eea808b6a13f70059a8a73195808db782012907f5ba32b6eae66a2f66b4f65147e2b968a1678c5f73d57d5d195dbaf667b606ff80c8490eac1f3b710657"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Simple send: two inputs from the same transaction, order reversed",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 7,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 3,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ },
+ "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "f4c2da807f89cb1501f1a77322a895acfb93c28e08ed2724d2beb8e44539ba38"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 7,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 3,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "f4c2da807f89cb1501f1a77322a895acfb93c28e08ed2724d2beb8e44539ba38"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "ab0c9b87181bf527879f48db9f14a02233619b986f8e8f2d5d408ce68a709f51",
+ "pub_key": "f4c2da807f89cb1501f1a77322a895acfb93c28e08ed2724d2beb8e44539ba38",
+ "signature": "398a9790865791a9db41a8015afad3a47d60fec5086c50557806a49a1bc038808632b8fe679a7bb65fc6b455be994502eed849f1da3729cd948fc7be73d67295"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Outpoint ordering byte-lexicographically vs. vout-integer",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 1,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 256,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ },
+ "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "a85ef8701394b517a4b35217c4bd37ac01ebeed4b008f8d0879f9e09ba95319c"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 1,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 256,
+ "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "a85ef8701394b517a4b35217c4bd37ac01ebeed4b008f8d0879f9e09ba95319c"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "c8ac0292997b5bca98b3ebd99a57e253071137550f270452cd3df8a3e2266d36",
+ "pub_key": "a85ef8701394b517a4b35217c4bd37ac01ebeed4b008f8d0879f9e09ba95319c",
+ "signature": "c036ee38bfe46aba03234339ae7219b31b824b52ef9d5ce05810a0d6f62330dedc2b55652578aa5bdabf930fae941acd839d5a66f8fce7caa9710ccb446bddd1"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Single recipient: multiple UTXOs from the same public key",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "548ae55c8eec1e736e8d3e520f011f1f42a56d166116ad210b3937599f87f566"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "548ae55c8eec1e736e8d3e520f011f1f42a56d166116ad210b3937599f87f566"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "f032695e2636619efa523fffaa9ef93c8802299181fd0461913c1b8daf9784cd",
+ "pub_key": "548ae55c8eec1e736e8d3e520f011f1f42a56d166116ad210b3937599f87f566",
+ "signature": "f238386c5d5e5444f8d2c75aabbcb28c346f208c76f60823f5de3b67b79e0ec72ea5de2d7caec314e0971d3454f122dda342b3eede01b3857e83654e36b25f76"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Single recipient: taproot only inputs with even y-values",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338"
+ }
+ },
+ "private_key": "fc8716a97a48ba9a05a98ae47b5cd201a25a7fd5d8b73c203c5f7b6b6b3b6ad7"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "de88bea8e7ffc9ce1af30d1132f910323c505185aec8eae361670421e749a1fb"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "de88bea8e7ffc9ce1af30d1132f910323c505185aec8eae361670421e749a1fb"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "3fb9ce5ce1746ced103c8ed254e81f6690764637ddbc876ec1f9b3ddab776b03",
+ "pub_key": "de88bea8e7ffc9ce1af30d1132f910323c505185aec8eae361670421e749a1fb",
+ "signature": "c5acd25a8f021a4192f93bc34403fd8b76484613466336fb259c72d04c169824f2690ca34e96cee86b69f376c8377003268fda56feeb1b873e5783d7e19bcca5"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Single recipient: taproot only with mixed even/odd y-values",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "01400a4d0dca6293f40499394d7eefe14a1de11e0e3454f51de2e802592abf5ee549042a1b1a8fb2e149ee9dd3f086c1b69b2f182565ab6ecf599b1ec9ebadfda6c5",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51208c8d23d4764feffcd5e72e380802540fa0f88e3d62ad5e0b47955f74d7b283c4"
+ }
+ },
+ "private_key": "1d37787c2b7116ee983e9f9c13269df29091b391c04db94239e0d2bc2182c3bf"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "77cab7dd12b10259ee82c6ea4b509774e33e7078e7138f568092241bf26b99f1"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "01400a4d0dca6293f40499394d7eefe14a1de11e0e3454f51de2e802592abf5ee549042a1b1a8fb2e149ee9dd3f086c1b69b2f182565ab6ecf599b1ec9ebadfda6c5",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51208c8d23d4764feffcd5e72e380802540fa0f88e3d62ad5e0b47955f74d7b283c4"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "77cab7dd12b10259ee82c6ea4b509774e33e7078e7138f568092241bf26b99f1"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "f5382508609771068ed079b24e1f72e4a17ee6d1c979066bf1d4e2a5676f09d4",
+ "pub_key": "77cab7dd12b10259ee82c6ea4b509774e33e7078e7138f568092241bf26b99f1",
+ "signature": "ff65833b8fd1ed3ef9d0443b4f702b45a3f2dd457ba247687e8207745c3be9d2bdad0ab3f07118f8b2efc6a04b95f7b3e218daf8a64137ec91bd2fc67fc137a5"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Single recipient: taproot input with even y-value and non-taproot input",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "463044021f24e010c6e475814740ba24c8cf9362c4db1276b7f46a7b1e63473159a80ec30221008198e8ece7b7f88e6c6cc6bb8c86f9f00b7458222a8c91addf6e1577bcf7697e2103e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9148cbc7dfe44f1579bff3340bbef1eddeaeb1fc97788ac"
+ }
+ },
+ "private_key": "8d4751f6e8a3586880fb66c19ae277969bd5aa06f61c4ee2f1e2486efdf666d3"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "30523cca96b2a9ae3c98beb5e60f7d190ec5bc79b2d11a0b2d4d09a608c448f0"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "463044021f24e010c6e475814740ba24c8cf9362c4db1276b7f46a7b1e63473159a80ec30221008198e8ece7b7f88e6c6cc6bb8c86f9f00b7458222a8c91addf6e1577bcf7697e2103e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9148cbc7dfe44f1579bff3340bbef1eddeaeb1fc97788ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "30523cca96b2a9ae3c98beb5e60f7d190ec5bc79b2d11a0b2d4d09a608c448f0"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "b40017865c79b1fcbed68896791be93186d08f47e416b289b8c063777e14e8df",
+ "pub_key": "30523cca96b2a9ae3c98beb5e60f7d190ec5bc79b2d11a0b2d4d09a608c448f0",
+ "signature": "d1edeea28cf1033bcb3d89376cabaaaa2886cbd8fda112b5c61cc90a4e7f1878bdd62180b07d1dfc8ffee1863c525a0c7b5bcd413183282cfda756cb65787266"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Single recipient: taproot input with odd y-value and non-taproot input",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "01400a4d0dca6293f40499394d7eefe14a1de11e0e3454f51de2e802592abf5ee549042a1b1a8fb2e149ee9dd3f086c1b69b2f182565ab6ecf599b1ec9ebadfda6c5",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51208c8d23d4764feffcd5e72e380802540fa0f88e3d62ad5e0b47955f74d7b283c4"
+ }
+ },
+ "private_key": "1d37787c2b7116ee983e9f9c13269df29091b391c04db94239e0d2bc2182c3bf"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "463044021f24e010c6e475814740ba24c8cf9362c4db1276b7f46a7b1e63473159a80ec30221008198e8ece7b7f88e6c6cc6bb8c86f9f00b7458222a8c91addf6e1577bcf7697e2103e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9148cbc7dfe44f1579bff3340bbef1eddeaeb1fc97788ac"
+ }
+ },
+ "private_key": "8d4751f6e8a3586880fb66c19ae277969bd5aa06f61c4ee2f1e2486efdf666d3"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "359358f59ee9e9eec3f00bdf4882570fd5c182e451aa2650b788544aff012a3a"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "01400a4d0dca6293f40499394d7eefe14a1de11e0e3454f51de2e802592abf5ee549042a1b1a8fb2e149ee9dd3f086c1b69b2f182565ab6ecf599b1ec9ebadfda6c5",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51208c8d23d4764feffcd5e72e380802540fa0f88e3d62ad5e0b47955f74d7b283c4"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "463044021f24e010c6e475814740ba24c8cf9362c4db1276b7f46a7b1e63473159a80ec30221008198e8ece7b7f88e6c6cc6bb8c86f9f00b7458222a8c91addf6e1577bcf7697e2103e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9148cbc7dfe44f1579bff3340bbef1eddeaeb1fc97788ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "359358f59ee9e9eec3f00bdf4882570fd5c182e451aa2650b788544aff012a3a"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "a2f9dd05d1d398347c885d9c61a64d18a264de6d49cea4326bafc2791d627fa7",
+ "pub_key": "359358f59ee9e9eec3f00bdf4882570fd5c182e451aa2650b788544aff012a3a",
+ "signature": "96038ad233d8befe342573a6e54828d863471fb2afbad575cc65271a2a649480ea14912b6abbd3fbf92efc1928c036f6e3eef927105af4ec1dd57cb909f360b8"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Multiple outputs: multiple outputs, same recipient",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "d97e442d110c0bdd31161a7bb6e7862e038d02a09b1484dfbb463f2e0f7c9230",
+ "pub_key": "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca",
+ "signature": "29bd25d0f808d7fcd2aa6d5ed206053899198397506c301b218a9e47a3d7070af03e903ff718978d50d1b6b9af8cc0e313d84eda5d5b1e8e85e5516d630bbeb9"
+ },
+ {
+ "priv_key_tweak": "33ce085c3c11eaad13694aae3c20301a6c83382ec89a7cde96c6799e2f88805a",
+ "pub_key": "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac",
+ "signature": "335667ca6cae7a26438f5cfdd73b3d48fa832fa9768521d7d5445f22c203ab0d74ed85088f27d29959ba627a4509996676f47df8ff284d292567b1beef0e3912"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Multiple outputs: multiple outputs, multiple recipients",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqgrz6j0lcqnc04vxccydl0kpsj4frfje0ktmgcl2t346hkw30226xqupawdf48k8882j0strrvcmgg2kdawz53a54dd376ngdhak364hzcmynqtn",
+ "sp1qqgrz6j0lcqnc04vxccydl0kpsj4frfje0ktmgcl2t346hkw30226xqupawdf48k8882j0strrvcmgg2kdawz53a54dd376ngdhak364hzcmynqtn"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "2e847bb01d1b491da512ddd760b8509617ee38057003d6115d00ba562451323a",
+ "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "2e847bb01d1b491da512ddd760b8509617ee38057003d6115d00ba562451323a",
+ "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ],
+ "key_material": {
+ "spend_priv_key": "9902c3c56e84002a7cd410113a9ab21d142be7f53cf5200720bb01314c5eb920",
+ "scan_priv_key": "060b751d7892149006ed7b98606955a29fe284a1e900070c0971f5fb93dbf422"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgrz6j0lcqnc04vxccydl0kpsj4frfje0ktmgcl2t346hkw30226xqupawdf48k8882j0strrvcmgg2kdawz53a54dd376ngdhak364hzcmynqtn"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "72cd082cccb633bf85240a83494b32dc943a4d05647a6686d23ad4ca59c0ebe4",
+ "pub_key": "2e847bb01d1b491da512ddd760b8509617ee38057003d6115d00ba562451323a",
+ "signature": "38745f3d9f5eef0b1cfb17ca314efa8c521efab28a23aa20ec5e3abb561d42804d539906dce60c4ee7977966184e6f2cab1faa0e5377ceb7148ec5218b4e7878"
+ },
+ {
+ "priv_key_tweak": "2f17ea873a0047fc01ba8010fef0969e76d0e4283f600d48f735098b1fee6eb9",
+ "pub_key": "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8",
+ "signature": "c26f4e3cf371b90b840f48ea0e761b5ec31883ed55719f9ef06a90e282d85f565790ab780a3f491bc2668cc64e944dca849d1022a878cdadb8d168b8da4a6da3"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Receiving with labels: label with even parity",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjex54dmqmmv6rw353tsuqhs99ydvadxzrsy9nuvk74epvee55drs734pqq"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "d014d4860f67d607d60b1af70e0ee236b99658b61bb769832acbbe87c374439a"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "d014d4860f67d607d60b1af70e0ee236b99658b61bb769832acbbe87c374439a"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": [
+ 2,
+ 3,
+ 1001337
+ ]
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjex54dmqmmv6rw353tsuqhs99ydvadxzrsy9nuvk74epvee55drs734pqq",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqsg59z2rppn4qlkx0yz9sdltmjv3j8zgcqadjn4ug98m3t6plujsq9qvu5n",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgq7c2zfthc6x3a5yecwc52nxa0kfd20xuz08zyrjpfw4l2j257yq6qgnkdh5"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "51d4e9d0d482b5700109b4b2e16ff508269b03d800192a043d61dca4a0a72a52",
+ "pub_key": "d014d4860f67d607d60b1af70e0ee236b99658b61bb769832acbbe87c374439a",
+ "signature": "c30fa63bad6f0a317f39a773a5cbf0b0f8193c71dfebba05ee6ae4ed28e3775e6e04c3ea70a83703bb888122855dc894cab61692e7fd10c9b3494d479a60785e"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Receiving with labels: label with odd parity",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqsg59z2rppn4qlkx0yz9sdltmjv3j8zgcqadjn4ug98m3t6plujsq9qvu5n"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "67626aebb3c4307cf0f6c39ca23247598fabf675ab783292eb2f81ae75ad1f8c"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "67626aebb3c4307cf0f6c39ca23247598fabf675ab783292eb2f81ae75ad1f8c"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": [
+ 2,
+ 3,
+ 1001337
+ ]
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjex54dmqmmv6rw353tsuqhs99ydvadxzrsy9nuvk74epvee55drs734pqq",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqsg59z2rppn4qlkx0yz9sdltmjv3j8zgcqadjn4ug98m3t6plujsq9qvu5n",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgq7c2zfthc6x3a5yecwc52nxa0kfd20xuz08zyrjpfw4l2j257yq6qgnkdh5"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "6024ae214876356b8d917716e7707d267ae16a0fdb07de2a786b74a7bbcddead",
+ "pub_key": "67626aebb3c4307cf0f6c39ca23247598fabf675ab783292eb2f81ae75ad1f8c",
+ "signature": "a86d554d0d6b7aa0907155f7e0b47f0182752472fffaeddd68da90e99b9402f166fd9b33039c302c7115098d971c1399e67c19e9e4de180b10ea0b9d6f0db832"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Receiving with labels: large label integer",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgq7c2zfthc6x3a5yecwc52nxa0kfd20xuz08zyrjpfw4l2j257yq6qgnkdh5"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "7efa60ce78ac343df8a013a2027c6c5ef29f9502edcbd769d2c21717fecc5951"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "7efa60ce78ac343df8a013a2027c6c5ef29f9502edcbd769d2c21717fecc5951"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": [
+ 2,
+ 3,
+ 1001337
+ ]
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjex54dmqmmv6rw353tsuqhs99ydvadxzrsy9nuvk74epvee55drs734pqq",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqsg59z2rppn4qlkx0yz9sdltmjv3j8zgcqadjn4ug98m3t6plujsq9qvu5n",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgq7c2zfthc6x3a5yecwc52nxa0kfd20xuz08zyrjpfw4l2j257yq6qgnkdh5"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "e336b92330c33030285ce42e4115ad92d5197913c88e06b9072b4a9b47c664a2",
+ "pub_key": "7efa60ce78ac343df8a013a2027c6c5ef29f9502edcbd769d2c21717fecc5951",
+ "signature": "c9e80dd3bdd25ca2d352ce77510f1aed37ba3509dc8cc0677f2d7c2dd04090707950ce9dd6c83d2a428063063aff5c04f1744e334f661f2fc01b4ef80b50f739"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Multiple outputs with labels: un-labeled and labeled address; same recipient",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ],
+ [
+ "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c",
+ "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": [
+ 1
+ ]
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "43100f89f1a6bf10081c92b473ffc57ceac7dbed600b6aba9bb3976f17dbb914",
+ "pub_key": "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "signature": "15c92509b67a6c211ebb4a51b7528d0666e6720de2343b2e92cfb97942ca14693c1f1fdc8451acfdb2644039f8f5c76114807fdc3d3a002d8a46afab6756bd75"
+ },
+ {
+ "priv_key_tweak": "33ce085c3c11eaad13694aae3c20301a6c83382ec89a7cde96c6799e2f88805a",
+ "pub_key": "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac",
+ "signature": "335667ca6cae7a26438f5cfdd73b3d48fa832fa9768521d7d5445f22c203ab0d74ed85088f27d29959ba627a4509996676f47df8ff284d292567b1beef0e3912"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Multiple outputs with labels: multiple outputs for labeled address; same recipient",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": [
+ 1
+ ]
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "43100f89f1a6bf10081c92b473ffc57ceac7dbed600b6aba9bb3976f17dbb914",
+ "pub_key": "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "signature": "15c92509b67a6c211ebb4a51b7528d0666e6720de2343b2e92cfb97942ca14693c1f1fdc8451acfdb2644039f8f5c76114807fdc3d3a002d8a46afab6756bd75"
+ },
+ {
+ "priv_key_tweak": "9d5fd3b91cac9ddfea6fc2e6f9386f680e6cee623cda02f53706306c081de87f",
+ "pub_key": "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c",
+ "signature": "db0dfacc98b6a6fcc67cc4631f080b1ca38c60d8c397f2f19843f8f95ec91594b24e47c5bd39480a861c1209f7e3145c440371f9191fb96e324690101eac8e8e"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Multiple outputs with labels: un-labeled, labeled, and multiple outputs for labeled address; same recipients",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjyh2ju7hd5gj57jg5r9lev3pckk4n2shtzaq34467erzzdfajfggty6aa5",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjyh2ju7hd5gj57jg5r9lev3pckk4n2shtzaq34467erzzdfajfggty6aa5"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae",
+ "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701",
+ "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa"
+ ],
+ [
+ "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae",
+ "3edf1ff6657c6e69568811bd726a7a7f480493aa42161acfe8dd4f44521f99ed",
+ "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3",
+ "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa"
+ ],
+ [
+ "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae",
+ "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3",
+ "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c",
+ "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701"
+ ],
+ [
+ "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "3c54444944d176437644378c23efb999ab6ab1cacdfe1dc1537b607e3df330e2",
+ "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa",
+ "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b"
+ ],
+ [
+ "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac",
+ "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b"
+ ],
+ [
+ "3c54444944d176437644378c23efb999ab6ab1cacdfe1dc1537b607e3df330e2",
+ "602e10e6944107c9b48bd885b493676578c935723287e0ab2f8b7f136862568e",
+ "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3",
+ "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa"
+ ],
+ [
+ "3c54444944d176437644378c23efb999ab6ab1cacdfe1dc1537b607e3df330e2",
+ "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3",
+ "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c",
+ "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b"
+ ],
+ [
+ "3edf1ff6657c6e69568811bd726a7a7f480493aa42161acfe8dd4f44521f99ed",
+ "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac",
+ "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b"
+ ],
+ [
+ "3edf1ff6657c6e69568811bd726a7a7f480493aa42161acfe8dd4f44521f99ed",
+ "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa",
+ "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca",
+ "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b"
+ ],
+ [
+ "602e10e6944107c9b48bd885b493676578c935723287e0ab2f8b7f136862568e",
+ "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3",
+ "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ],
+ [
+ "602e10e6944107c9b48bd885b493676578c935723287e0ab2f8b7f136862568e",
+ "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701",
+ "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa",
+ "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca"
+ ],
+ [
+ "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c",
+ "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701",
+ "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca",
+ "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae",
+ "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701",
+ "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": [
+ 1,
+ 1337
+ ]
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj",
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjyh2ju7hd5gj57jg5r9lev3pckk4n2shtzaq34467erzzdfajfggty6aa5"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "4e3352fbe0505c25e718d96007c259ef08db34f8c844e4ff742d9855ff03805a",
+ "pub_key": "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae",
+ "signature": "6eeae1ea9eb826e3d0e812f65937100e0836ea188c04f36fabc4981eda29de8d3d3529390a0a8b3d830f7bca4f5eae5994b9788ddaf05ad259ffe26d86144b4b"
+ },
+ {
+ "priv_key_tweak": "43100f89f1a6bf10081c92b473ffc57ceac7dbed600b6aba9bb3976f17dbb914",
+ "pub_key": "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c",
+ "signature": "15c92509b67a6c211ebb4a51b7528d0666e6720de2343b2e92cfb97942ca14693c1f1fdc8451acfdb2644039f8f5c76114807fdc3d3a002d8a46afab6756bd75"
+ },
+ {
+ "priv_key_tweak": "bf709f98d4418f8a67e738154ae48818dad44689cd37fbc070891a396dd1c633",
+ "pub_key": "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701",
+ "signature": "42a19fd8a63dde1824966a95d65a28203e631e49bf96ca5dae1b390e7a0ace2cc8709c9b0c5715047032f57f536a3c80273cbecf4c05be0b5456c183fa122c06"
+ },
+ {
+ "priv_key_tweak": "736f05e4e3072c3b8656bedef2e9bf54cbcaa2b6fe5320d3e86f5b96874dda71",
+ "pub_key": "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa",
+ "signature": "2e61bb3d79418ecf55f68847cf121bfc12d397b39d1da8643246b2f0a9b96c3daa4bfe9651beb5c9ce20e1f29282c4566400a4b45ee6657ec3b18fdc554da0b4"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Single recipient: use silent payments for sender change",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv",
+ "sp1qqw6vczcfpdh5nf5y2ky99kmqae0tr30hgdfg88parz50cp80wd2wqqlv6saelkk5snl4wfutyxrchpzzwm8rjp3z6q7apna59z9huq4x754e5atr"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "be368e28979d950245d742891ae6064020ba548c1e2e65a639a8bb0675d95cff",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "be368e28979d950245d742891ae6064020ba548c1e2e65a639a8bb0675d95cff",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ],
+ "key_material": {
+ "spend_priv_key": "b8f87388cbb41934c50daca018901b00070a5ff6cc25a7e9e716a9d5b9e4d664",
+ "scan_priv_key": "11b7a82e06ca2648d5fded2366478078ec4fc9dc1d8ff487518226f229d768fd"
+ },
+ "labels": [
+ 0
+ ]
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqw6vczcfpdh5nf5y2ky99kmqae0tr30hgdfg88parz50cp80wd2wqqauj52ymtc4xdkmx3tgyhrsemg2g3303xk2gtzfy8h8ejet8fz8jcw23zua",
+ "sp1qqw6vczcfpdh5nf5y2ky99kmqae0tr30hgdfg88parz50cp80wd2wqqlv6saelkk5snl4wfutyxrchpzzwm8rjp3z6q7apna59z9huq4x754e5atr"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "80cd767ed20bd0bb7d8ea5e803f8c381293a62e8a073cf46fb0081da46e64e1f",
+ "pub_key": "be368e28979d950245d742891ae6064020ba548c1e2e65a639a8bb0675d95cff",
+ "signature": "7fbd5074cf1377273155eefafc7c330cb61b31da252f22206ac27530d2b2567040d9af7808342ed4a09598c26d8307446e4ed77079e6a2e61fea736e44da5f5a"
+ }
+ ]
+ }
+ },
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "be368e28979d950245d742891ae6064020ba548c1e2e65a639a8bb0675d95cff",
+ "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "33ce085c3c11eaad13694aae3c20301a6c83382ec89a7cde96c6799e2f88805a",
+ "pub_key": "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac",
+ "signature": "335667ca6cae7a26438f5cfdd73b3d48fa832fa9768521d7d5445f22c203ab0d74ed85088f27d29959ba627a4509996676f47df8ff284d292567b1beef0e3912"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Single recipient: taproot input with NUMS point",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0440c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b22205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5ac21c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00150",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "5120da6f0595ecb302bbe73e2f221f05ab10f336b06817d36fd28fc6691725ddaa85"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338"
+ }
+ },
+ "private_key": "fc8716a97a48ba9a05a98ae47b5cd201a25a7fd5d8b73c203c5f7b6b6b3b6ad7"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 1,
+ "scriptSig": "",
+ "txinwitness": "0340268d31a9276f6380107d5321cafa6d9e8e5ea39204318fdc8206b31507c891c3bbcea3c99e2208d73bd127a8e8c5f1e45a54f1bd217205414ddb566ab7eda0092220e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85dac21c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51200a3c9365ceb131f89b0a4feb6896ebd67bb15a98c31eaa3da143bb955a0f3fcb"
+ }
+ },
+ "private_key": "8d4751f6e8a3586880fb66c19ae277969bd5aa06f61c4ee2f1e2486efdf666d3"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "79e79897c52935bfd97fc6e076a6431a0c7543ca8c31e0fc3cf719bb572c842d"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0440c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b22205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5ac21c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00150",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "5120da6f0595ecb302bbe73e2f221f05ab10f336b06817d36fd28fc6691725ddaa85"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 1,
+ "scriptSig": "",
+ "txinwitness": "0340268d31a9276f6380107d5321cafa6d9e8e5ea39204318fdc8206b31507c891c3bbcea3c99e2208d73bd127a8e8c5f1e45a54f1bd217205414ddb566ab7eda0092220e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85dac21c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51200a3c9365ceb131f89b0a4feb6896ebd67bb15a98c31eaa3da143bb955a0f3fcb"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "79e79897c52935bfd97fc6e076a6431a0c7543ca8c31e0fc3cf719bb572c842d"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "3ddec3232609d348d6b8b53123b4f40f6d4f5398ca586f087b0416ec3b851496",
+ "pub_key": "79e79897c52935bfd97fc6e076a6431a0c7543ca8c31e0fc3cf719bb572c842d",
+ "signature": "d7d06e3afb68363031e4eb18035c46ceae41bdbebe7888a4754bc9848c596436869aeaecff0527649a1f458b71c9ceecec10b535c09d01d720229aa228547706"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Pubkey extraction from malleated p2pkh",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 1,
+ "scriptSig": "0075473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 2,
+ "scriptSig": "5163473045022100e7d26e77290b37128f5215ade25b9b908ce87cc9a4d498908b5bb8fd6daa1b8d022002568c3a8226f4f0436510283052bfb780b76f3fe4aa60c4c5eb118e43b187372102e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d67483046022100c0d3c851d3bd562ae93d56bcefd735ea57c027af46145a4d5e9cac113bfeb0c2022100ee5b2239af199fa9b7aa1d98da83a29d0a2cf1e4f29e2f37134ce386d51c544c2102ad0f26ddc7b3fcc340155963b3051b85289c1869612ecb290184ac952e2864ec68",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914c82c5ec473cbc6c86e5ef410e36f9495adcf979988ac"
+ }
+ },
+ "private_key": "72b8ae09175ca7977f04993e651d88681ed932dfb92c5158cdf0161dd23fda6e"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "4612cdbf845c66c7511d70aab4d9aed11e49e48cdb8d799d787101cdd0d53e4f"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 1,
+ "scriptSig": "0075473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 2,
+ "scriptSig": "5163473045022100e7d26e77290b37128f5215ade25b9b908ce87cc9a4d498908b5bb8fd6daa1b8d022002568c3a8226f4f0436510283052bfb780b76f3fe4aa60c4c5eb118e43b187372102e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d67483046022100c0d3c851d3bd562ae93d56bcefd735ea57c027af46145a4d5e9cac113bfeb0c2022100ee5b2239af199fa9b7aa1d98da83a29d0a2cf1e4f29e2f37134ce386d51c544c2102ad0f26ddc7b3fcc340155963b3051b85289c1869612ecb290184ac952e2864ec68",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914c82c5ec473cbc6c86e5ef410e36f9495adcf979988ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "4612cdbf845c66c7511d70aab4d9aed11e49e48cdb8d799d787101cdd0d53e4f"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "10bde9781def20d7701e7603ef1b1e5e71c67bae7154818814e3c81ef5b1a3d3",
+ "pub_key": "4612cdbf845c66c7511d70aab4d9aed11e49e48cdb8d799d787101cdd0d53e4f",
+ "signature": "6137969f810e9e8ef6c9755010e808f5dd1aed705882e44d7f0ae64eb0c509ec8b62a0671bee0d5914ac27d2c463443e28e999d82dc3d3a4919f093872d947bb"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "P2PKH and P2WPKH Uncompressed Keys are skipped",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9144b92ac4ac6fe6212393894addda332f2e47a315688ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 1,
+ "scriptSig": "",
+ "txinwitness": "02473045022100e7d26e77290b37128f5215ade25b9b908ce87cc9a4d498908b5bb8fd6daa1b8d022002568c3a8226f4f0436510283052bfb780b76f3fe4aa60c4c5eb118e43b187374104e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d6fe8190e189be57d0d5bcd17dbcbcd04c9b4a1c5f605b10d5c90abfcc0d12884",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "00140423f731a07491364e8dce98b7c00bda63336950"
+ }
+ },
+ "private_key": "72b8ae09175ca7977f04993e651d88681ed932dfb92c5158cdf0161dd23fda6e"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac"
+ }
+ }
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9144b92ac4ac6fe6212393894addda332f2e47a315688ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 1,
+ "scriptSig": "",
+ "txinwitness": "02473045022100e7d26e77290b37128f5215ade25b9b908ce87cc9a4d498908b5bb8fd6daa1b8d022002568c3a8226f4f0436510283052bfb780b76f3fe4aa60c4c5eb118e43b187374104e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d6fe8190e189be57d0d5bcd17dbcbcd04c9b4a1c5f605b10d5c90abfcc0d12884",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "00140423f731a07491364e8dce98b7c00bda63336950"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "688fa3aeb97d2a46ae87b03591921c2eaf4b505eb0ddca2733c94701e01060cf",
+ "pub_key": "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6",
+ "signature": "72e7ad573ac23255d4651d5b0326a200496588acb7a4894b22092236d5eda6a0a9a4d8429b022c2219081fefce5b33795cae488d10f5ea9438849ed8353624f2"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Skip invalid P2SH inputs",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "16001419c2f3ae0ca3b642bd3e49598b8da89f50c14161",
+ "txinwitness": "02483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "a9148629db5007d5fcfbdbb466637af09daf9125969387"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 1,
+ "scriptSig": "1600144b92ac4ac6fe6212393894addda332f2e47a3156",
+ "txinwitness": "02473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "a9146c9bf136fbb7305fd99d771a95127fcf87dedd0d87"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 2,
+ "scriptSig": "00493046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d601483045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b97014c695221025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be52103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233382102e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d53ae",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "a9141044ddc6cea09e4ac40fbec2ba34ad62de6db25b87"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "16001419c2f3ae0ca3b642bd3e49598b8da89f50c14161",
+ "txinwitness": "02483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "a9148629db5007d5fcfbdbb466637af09daf9125969387"
+ }
+ }
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 1,
+ "scriptSig": "1600144b92ac4ac6fe6212393894addda332f2e47a3156",
+ "txinwitness": "02473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "a9146c9bf136fbb7305fd99d771a95127fcf87dedd0d87"
+ }
+ }
+ },
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 2,
+ "scriptSig": "00493046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d601483045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b97014c695221025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be52103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233382102e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d53ae",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "a9141044ddc6cea09e4ac40fbec2ba34ad62de6db25b87"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": [
+ {
+ "priv_key_tweak": "688fa3aeb97d2a46ae87b03591921c2eaf4b505eb0ddca2733c94701e01060cf",
+ "pub_key": "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6",
+ "signature": "72e7ad573ac23255d4651d5b0326a200496588acb7a4894b22092236d5eda6a0a9a4d8429b022c2219081fefce5b33795cae488d10f5ea9438849ed8353624f2"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Recipient ignores unrelated outputs",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgrz6j0lcqnc04vxccydl0kpsj4frfje0ktmgcl2t346hkw30226xqupawdf48k8882j0strrvcmgg2kdawz53a54dd376ngdhak364hzcmynqtn"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ [
+ "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8"
+ ]
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8",
+ "782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": []
+ }
+ }
+ ]
+ },
+ {
+ "comment": "No valid inputs, sender generates no outputs",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d641045a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5c61836c9b1688ba431f7ea3039742251f62f0dca3da1bee58a47fa9b456c2d52",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914460e8b41545d2dbe7e0671f0f573e2232814260a88ac"
+ }
+ },
+ "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1"
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9144b92ac4ac6fe6212393894addda332f2e47a315688ac"
+ }
+ },
+ "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a"
+ }
+ ],
+ "recipients": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ []
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
+ "vout": 0,
+ "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d641045a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5c61836c9b1688ba431f7ea3039742251f62f0dca3da1bee58a47fa9b456c2d52",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a914460e8b41545d2dbe7e0671f0f573e2232814260a88ac"
+ }
+ }
+ },
+ {
+ "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
+ "vout": 0,
+ "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab",
+ "txinwitness": "",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "76a9144b92ac4ac6fe6212393894addda332f2e47a315688ac"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338",
+ "e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d"
+ ],
+ "key_material": {
+ "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3",
+ "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv"
+ ],
+ "outputs": []
+ }
+ }
+ ]
+ },
+ {
+ "comment": "Input keys sum up to zero / point at infinity: sending fails, receiver skips tx",
+ "sending": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "024730440220085003179ce1a3a88ce0069aa6ea045e140761ab88c22a26ae2a8cfe983a6e4602204a8a39940f0735c8a4424270ac8da65240c261ab3fda9272f6d6efbf9cfea366012102557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "00149d9e24f9fab4e35bf1a6df4b46cb533296ac0792"
+ }
+ },
+ "private_key": "a6df6a0bb448992a301df4258e06a89fe7cf7146f59ac3bd5ff26083acb22ceb"
+ },
+ {
+ "txid": "3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e",
+ "vout": 1,
+ "scriptSig": "",
+ "txinwitness": "0247304402204586a68e1d97dd3c6928e3622799859f8c3b20c3c670cf654cc905c9be29fdb7022043fbcde1689f3f4045e8816caf6163624bd19e62e4565bc99f95c533e599782c012103557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "00149860538b5575962776ed0814ae222c7d60c72d7b"
+ }
+ },
+ "private_key": "592095f44bb766d5cfe20bda71f9575ed2df6b9fb9addc7e5fdffe0923841456"
+ }
+ ],
+ "recipients": [
+ "sp1qqtrqglu5g8kh6mfsg4qxa9wq0nv9cauwfwxw70984wkqnw2uwz0w2qnehen8a7wuhwk9tgrzjh8gwzc8q2dlekedec5djk0js9d3d7qhnq6lqj3s"
+ ]
+ },
+ "expected": {
+ "outputs": [
+ []
+ ]
+ }
+ }
+ ],
+ "receiving": [
+ {
+ "given": {
+ "vin": [
+ {
+ "txid": "3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e",
+ "vout": 0,
+ "scriptSig": "",
+ "txinwitness": "024730440220085003179ce1a3a88ce0069aa6ea045e140761ab88c22a26ae2a8cfe983a6e4602204a8a39940f0735c8a4424270ac8da65240c261ab3fda9272f6d6efbf9cfea366012102557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "00149d9e24f9fab4e35bf1a6df4b46cb533296ac0792"
+ }
+ }
+ },
+ {
+ "txid": "3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e",
+ "vout": 1,
+ "scriptSig": "",
+ "txinwitness": "0247304402204586a68e1d97dd3c6928e3622799859f8c3b20c3c670cf654cc905c9be29fdb7022043fbcde1689f3f4045e8816caf6163624bd19e62e4565bc99f95c533e599782c012103557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975",
+ "prevout": {
+ "scriptPubKey": {
+ "hex": "00149860538b5575962776ed0814ae222c7d60c72d7b"
+ }
+ }
+ }
+ ],
+ "outputs": [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ],
+ "key_material": {
+ "spend_priv_key": "0000000000000000000000000000000000000000000000000000000000000001",
+ "scan_priv_key": "0000000000000000000000000000000000000000000000000000000000000002"
+ },
+ "labels": []
+ },
+ "expected": {
+ "addresses": [
+ "sp1qqtrqglu5g8kh6mfsg4qxa9wq0nv9cauwfwxw70984wkqnw2uwz0w2qnehen8a7wuhwk9tgrzjh8gwzc8q2dlekedec5djk0js9d3d7qhnq6lqj3s"
+ ],
+ "outputs": []
+ }
+ }
+ ]
+ }
+]
diff --git a/bip-0353.mediawiki b/bip-0353.mediawiki
new file mode 100644
index 0000000000..ef4b6c0abc
--- /dev/null
+++ b/bip-0353.mediawiki
@@ -0,0 +1,176 @@
+
+
+
+==Copyright==
+
+This BIP is licensed under the CC0-1.0 license.
+
+==Abstract==
+This BIP proposes a standard format for encoding [[bip-0021.mediawiki|BIP 21]] URI schemes in DNS TXT records.
+
+==Motivation==
+Various Bitcoin and other cryptocurrency applications have developed human-readable names for payment instructions over time, with marketplace adoption signaling strong demand for it from users.
+
+The DNS provides a standard, global, hierarchical namespace mapping human-readable labels to records of various forms. Using DNSSEC, the DNS provides cryptographic guarantees using a straightforward PKI which follows the hierarchical nature of the DNS, allowing for stateless and even offline validation of DNS records from a single trusted root.
+
+Further, because DNS queries are generally proxied through ISP-provided or other resolvers, DNS queries usually do not directly expose the queryer's IP address. Further, because of the prevalence of open resolvers, the simplicity of the protocol, and broad availability of DNS recursive resolver implementations, finding a proxy for DNS records is trivial.
+
+Thus, using TXT records to store Bitcoin payment instructions allows for human-readable Bitcoin payment destinations which can be trivially verified on hardware wallets and which can be resolved relatively privately.
+
+==Specification==
+
+=== General rules for handling ===
+Bitcoin wallets MUST NOT prefer to use DNS-based resolving when methods with explicit public keys or addresses are available. In other words, if a standard Bitcoin address or direct BIP 21 URI is available or would suffice, Bitcoin wallets MUST prefer to use that instead.
+
+=== Records ===
+Payment instructions are indexed by both a user and a domain. Instructions for a given `user` and `domain` are stored at `user`.user._bitcoin-payment.`domain` in a single TXT record.
+
+All payment instructions MUST be DNSSEC-signed.
+
+Payment instructions MAY resolve through CNAME or DNAME records as long as all such records and the ultimate records pointed to by them are DNSSEC signed.
+
+User and domain names which are not expressible using standard printable ASCII MUST be encoded using the punycode IDN encoding defined in [[https://datatracker.ietf.org/doc/html/rfc3492|RFC 3492]] and [[https://datatracker.ietf.org/doc/html/rfc5891|RFC 5891]].
+
+Note that because resolvers are not required to support resolving non-ASCII identifiers, wallets SHOULD avoid using non-ASCII identifiers.
+
+For payment instructions that have a built-in expiry time (e.g. Lightning BOLT 12 offers), care must be taken to ensure that the DNS records expire prior to the expiry of the payment instructions. Otherwise, senders may have payment instructions cached locally which have expired, preventing payment.
+
+=== Resolution ===
+
+Clients resolving Bitcoin payment instructions MUST ignore any TXT records at the same label which do not begin with (ignoring case) "bitcoin:". Resolvers encountering multiple "bitcoin:"-matching TXT records at the same label MUST treat the records as invalid and refuse to use any payment instructions therein.
+
+Clients resolving Bitcoin payment instructions MUST concatenate all strings in the TXT record before processing the complete URI.TXT records are defined as "one or more character-strings" in [[https://www.rfc-editor.org/rfc/rfc1035#section-3.3.14|RFC 1035]], and a "character-string" is a single byte (with a max value of 255) followed by that many characters.
+
+Clients resolving Bitcoin payment instructions MUST fully validate DNSSEC signatures leading to the DNS root (including any relevant CNAME or DNAME records) and MUST NOT accept DNSSEC signatures which use SHA-1 or RSA with keys shorter than 1024 bits. Resolvers MAY accept SHA-1 DS records.
+
+Clients resolving Bitcoin payment instructions MUST NOT trust a remote resolver to validate DNSSEC records on their behalf.
+
+Clients resolving Bitcoin payment instructions MUST support resolving through CNAME or DNAME records.
+
+Resolvers MAY support resolving non-ASCII user and domain identifiers. Resolvers which do support non-ASCII user and domain identifiers MUST take precautions to prevent homograph attacks and SHOULD consider denying paste functionality when entering non-ASCII identifiers. Wallets which do not take any such precautions MUST instead display non-ASCII user and domain identifiers using their raw punycode. As such, wallets SHOULD NOT create identifiers which are not entirely printable ASCII.
+
+While clients MAY cache the payment instructions they receive from the DNS, clients MUST NOT cache the payment instructions received from the DNS for longer than the TTL provided by their DNS resolver, and further MUST NOT cache the payment instructions for longer than the lowest initial TTL (which is signed as a part of DNSSEC signatures) received in the full DNSSEC chain leading from the DNS root to the resolved TXT record.
+
+=== Address Reuse ===
+
+Payment instructions with on-chain addresses which will be re-used SHOULD be rotated as regularly as possible to reduce address reuse. Such payment instructions SHOULD also use a relatively short DNS TTL to ensure regular rotation takes effect quickly. In cases where this is not practical, payment instructions SHOULD NOT contain on-chain addresses (i.e. the URI path SHOULD be empty).
+
+Payment instructions which do contain on-chain addresses which will be re-used SHOULD be rotated after any transaction to such an address is confirmed on-chain.
+
+=== Display ===
+
+When displaying a verified human-readable name, wallets SHOULD prefix it with ₿, i.e. ₿`user`@`domain`. They SHOULD parse recipient information in both `user`@`domain` and ₿`user`@`domain` forms and resolve such an entry into recipient information using the above record. For the avoidance of doubt, the ₿ is *not* included in the DNS label which is resolved.
+
+Wallets providing the ability for users to "copy" their address information SHOULD copy the underlying URI directly, rather than the human-readable name. This avoids an additional DNS lookup by the application in which it is pasted. Wallets that nevertheless provide users the ability to copy their human-readable name, MUST include the ₿ prefix (i.e. copy it in the form ₿`user`@`domain`).
+
+Wallets accepting payment information from external devices (e.g. hardware wallets) SHOULD accept RFC 9102-formatted proofs (as a series of unsorted `AuthenticationChain` records) and, if verification succeeds, SHOULD display the recipient in the form ₿`user`@`domain`.
+
+=== PSBT types ===
+
+Wallets accepting payment information from external devices (e.g. hardware wallets) MAY examine the following per-output PSBT fields to fetch RFC 9102-formatted proofs. Wallets creating PSBTs with recipient information derived from human-readable names SHOULD include the following fields.
+
+When validating the contained proof, clients MUST enforce the inception on all contained RRSigs is no later than the current time and that the expiry of all RRSigs is no earlier than an hour in the past. Clients MAY allow for an expiry up to an hour in the past to allow for delays between PSBT construction and signing only if such a delay is likely to occur in their intended usecase.
+
+{|
+! Name
+!
+!
+!
+! Description
+! Versions Requiring Inclusion
+! Versions Requiring Exclusion
+! Versions Allowing Inclusion
+|-
+| BIP 353 DNSSEC proof
+| PSBT_OUT_DNSSEC_PROOF = 0x35
+| None
+| <1-byte-length-prefixed BIP 353 human-readable name without the ₿ prefix>
+| A BIP 353 human-readable name (without the ₿ prefix), prefixed by a 1-byte length.
+Followed by an [[https://www.rfc-editor.org/rfc/rfc9102.html#name-dnssec-authentication-chain|RFC 9102 DNSSEC AuthenticationChain]] (i.e. a series of DNS Resource Records in no particular order) providing a DNSSEC proof to a BIP 353 DNS TXT record.
+|
+|
+| 0, 2
+|}
+
+== Rationale ==
+
+=== Display ===
+
+There are several ways in which human-readable payment instructions could be displayed in wallets. In order to ensure compatibility with existing human-readable names schemes, @ is used as the separator between the `user` and `domain` parts. However, simply using the @ separator can lead to confusion between email addresses on a given domain and payment instructions on a domain. In order to somewhat reduce the incidence of such confusion, a ₿ prefix is used.
+
+=== Rotation ===
+
+On-chain addresses which are re-used (i.e. not including schemes like [[bip-0352.mediawiki|Silent Payments]]) need to be rotated to avoid contributing substantially to address reuse. However, rotating them on a timer or any time a transaction enters the mempool could lead to substantial overhead from excess address generation. Instead, rotating addresses any time a transaction is confirmed on-chain ensures address rotation happens often while bounding the maximum number of addresses needed to one per block, which grows very slowly and will not generate an address set too large to handle while scanning the chain going forward.
+
+=== Alternatives ===
+There are many existing schemes to resolve human-readable names to cryptocurrency payment instructions. Sadly, these current schemes suffer from a myriad of drawbacks, including (a) lacking succinct proofs of namespace to public key mappings, (b) revealing sender IP addresses to recipients or other intermediaries as a side-effect of payment, (c) relying on the bloated TLS Certificate Authority infrastructure, or (d) lacking open access, not allowing anyone to create a namespace mapping.
+
+==== DNS Rather than blockchain-based solutions ====
+There are many blockchain-based alternatives to the DNS which feature better censorship-resistance and, in many cases, security. However, here we chose to use the standard ICANN-managed DNS namespace as many blockchain-based schemes suffer from (a), above (though in some cases this could be addressed with cryptographic SNARK schemes). Further, because they do not have simple client-side querying ability, many of these schemes use trusted intermediaries which resolve names on behalf of clients. This reintroduces drawbacks (b) and often (c) as well.
+
+Finally, it is worth noting that none of the blockchain-based alternatives to the DNS have had material adoption outside of their specific silos, and committing Bitcoin wallets to rely on a separate system which doesn't see broad adoption may not be sustainable.
+
+==== DNS Rather than HTTP-based solutions ====
+HTTP(s)-based payment instruction resolution protocols suffer from drawbacks (a), (b), and (c), above, and generally shouldn't be considered a serious alternative for payment instruction resolution.
+
+==== Private DNS Querying ====
+While public recursive DNS resolvers are very common (e.g. 1.1.1.1, 8.8.8.8, and 9.9.9.9), using such resolvers directly (even after validating DNSSEC signatures) introduces drawback (b), at least in regard to a centralized intermediary. Resolving payment instructions recursively locally using a resolver on the same local network or in the paying application would instead introduce drawback (b) directly to the recipient, which may well be worse.
+
+For payers not using VPN or other proxying technologies, they generally trust their ISP to not snoop on their DNS requests anyway, so using ISP-provided recursive DNS resolvers is likely the best option.
+
+However, for the best privacy, payers are encouraged to perform DNS resolution over Tor or another VPN technology.
+
+Lightning payers should consider utilizing DNS resolution over native onion messages, using the protocol described in [[https://github.com/lightning/blips/blob/master/blip-0032.md|BLIP 32]]
+
+=== DNS Enumeration ===
+
+In most cases where payments are accepted from any third-party, user enumeration is practical by simply attempting to send small value payments to a list of possible user names. However, storing all valid users in the DNS directly may make such enumeration marginally more practical. Thus, those wishing to avoid such enumeration should carefully ensure all DNS names return valid payment instructions. Note when doing so that wildcard records are identified as such by the DNSSEC RRSIG labels counter and are differentiable from non-wildcard records.
+
+== Backwards Compatibility ==
+
+This work is intended to extend and subsume the existing "Lightning Address" scheme, which maps similar names (without the ₿ prefix) using HTTPS servers to Lightning BOLT 11 payment instructions. Wallets implementing this scheme MAY fall back to existing "Lightning Address" logic if DNS resolution fails but SHOULD NOT do so after this scheme is sufficiently broadly deployed to avoid leaking sender IP address information.
+
+== Examples ==
+
+matt@mattcorallo.com resolves to
+
+
+
+* Note that `lno` indicates a value containing a lightning BOLT12 offer.
+* Note that the complete URI is broken into two strings with maximum 255 characters each
+
+== Reference Implementations ==
+* A DNSSEC proof generation and validation implementation can be found at https://git.bitcoin.ninja/index.cgi?p=dnssec-prover;a=summary
+* A lightning-specific name to payment instruction resolver can be found at https://git.bitcoin.ninja/index.cgi?p=lightning-resolver;a=summary
+* Reference implementations for parsing the URI contents can be found in [[bip-0021.mediawiki|BIP 21]].
+
+
+== Footnotes ==
+
+
+
+== Acknowledgements ==
+
+Thanks to Rusty Russell for the concrete address rotation suggestion.
+
+Thanks to the Bitcoin Design Community, and especially Christoph Ono for lots of discussion, analysis, and UX mockups in how human-readable payment instructions should be displayed.
+
+Thanks to Andrew Kaizer for the suggestion to explicitly restrict cache lifetime to the relevant DNS TTLs.
diff --git a/bip-0370.mediawiki b/bip-0370.mediawiki
index d906a40f24..05d4e50773 100644
--- a/bip-0370.mediawiki
+++ b/bip-0370.mediawiki
@@ -2,10 +2,10 @@
BIP: 370
Layer: Applications
Title: PSBT Version 2
- Author: Andrew Chow
+ Author: Ava Chow
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0370
- Status: Draft
+ Status: Final
Type: Standards Track
Created: 2021-01-14
License: BSD-2-Clause
@@ -29,7 +29,7 @@ inputs and outputs be added to the transaction. The fixed global unsigned transa
cannot be changed which prevents any additional inputs or outputs to be added.
PSBT Version 2 is intended to rectify this problem.
-An additional benficial side effect is that all information for a given input or output will be
+An additional beneficial side effect is that all information for a given input or output will be
provided by its or . With Version 0, to retrieve
all of the information for an input or output, data would need to be found in two locations:
the / and the global unsigned transaction. PSBT
@@ -42,7 +42,7 @@ PSBT Version 2 (PSBTv2) only specifies new fields and field inclusion/exclusion
PSBT_GLOBAL_UNSIGNED_TX must be excluded in PSBTv2.
PSBT_GLOBAL_VERSION must be included in PSBTv2 and set to version number 2'''What happened to version number 1?'''
Version number 1 is skipped because PSBT Version 0 has been colloquially referred to as version 1. Originally this BIP was to be
-version 1, but because it has been colloquially referred to as version 2 during its design phrase, it was decided to change the
+version 1, but because it has been colloquially referred to as version 2 during its design phase, it was decided to change the
version number to 2 so that there would not be any confusion.
The new global types for PSBT Version 2 are as follows:
@@ -62,7 +62,7 @@ The new global types for PSBT Version 2 are as follows:
| PSBT_GLOBAL_TX_VERSION = 0x02
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian int version>
| The 32-bit little endian signed integer representing the version number of the transaction being created. Note that this is not the same as the PSBT version number specified by the PSBT_GLOBAL_VERSION field.
| 2
| 0
@@ -72,7 +72,7 @@ The new global types for PSBT Version 2 are as follows:
| PSBT_GLOBAL_FALLBACK_LOCKTIME = 0x03
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint locktime>
| The 32-bit little endian unsigned integer representing the transaction locktime to use if no inputs specify a required locktime.
|
| 0
@@ -82,7 +82,7 @@ The new global types for PSBT Version 2 are as follows:
| PSBT_GLOBAL_INPUT_COUNT = 0x04
| None
| No key data
-|
+|
| Compact size unsigned integer representing the number of inputs in this PSBT.
| 2
| 0
@@ -92,7 +92,7 @@ The new global types for PSBT Version 2 are as follows:
| PSBT_GLOBAL_OUTPUT_COUNT = 0x05
| None
| No key data
-|
+|
| Compact size unsigned integer representing the number of outputs in this PSBT.
| 2
| 0
@@ -102,8 +102,8 @@ The new global types for PSBT Version 2 are as follows:
| PSBT_GLOBAL_TX_MODIFIABLE = 0x06
| None
| No key data
-| <8-bit uint>
-| An 8 bit little endian unsigned integer as a bitfield for various transaction modification flags. Bit 0 is the Inputs Modifiable Flag and indicates whether inputs can be modified. Bit 1 is the Outputs Modifiable Flag and indicates whether outputs can be modified. Bit 2 is the Has SIGHASH_SINGLE flag and indicates whether the transaction has a SIGHASH_SINGLE signature who's input and output pairing must be preserved. Bit 2 essentially indicates that the Constructor must iterate the inputs to determine whether and how to add an input.
+| <8-bit uint flags>
+| An 8 bit unsigned integer as a bitfield for various transaction modification flags. Bit 0 is the Inputs Modifiable Flag, set to 1 to indicate whether inputs can be added or removed. Bit 1 is the Outputs Modifiable Flag, set to 1 to indicate whether outputs can be added or removed. Bit 2 is the Has SIGHASH_SINGLE flag, set to 1 to indicate whether the transaction has a SIGHASH_SINGLE signature who's input and output pairing must be preserved. Bit 2 essentially indicates that the Constructor must iterate the inputs to determine whether and how to add or remove an input.
|
| 0
| 2
@@ -126,7 +126,7 @@ The new per-input types for PSBT Version 2 are defined as follows:
| PSBT_IN_PREVIOUS_TXID = 0x0e
| None
| No key data
-|
+| <32 byte txid>
| 32 byte txid of the previous transaction whose output at PSBT_IN_OUTPUT_INDEX is being spent.
| 2
| 0
@@ -136,7 +136,7 @@ The new per-input types for PSBT Version 2 are defined as follows:
| PSBT_IN_OUTPUT_INDEX = 0x0f
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint index>
| 32 bit little endian integer representing the index of the output being spent in the transaction with the txid of PSBT_IN_PREVIOUS_TXID.
| 2
| 0
@@ -146,7 +146,7 @@ The new per-input types for PSBT Version 2 are defined as follows:
| PSBT_IN_SEQUENCE = 0x10
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint sequence>
| The 32 bit unsigned little endian integer for the sequence number of this input. If omitted, the sequence number is assumed to be the final sequence number (0xffffffff).
|
| 0
@@ -156,7 +156,7 @@ The new per-input types for PSBT Version 2 are defined as follows:
| PSBT_IN_REQUIRED_TIME_LOCKTIME = 0x11
| None
| No key data
-| <32-bit uint>
+| <32-bit little endian uint locktime>
| 32 bit unsigned little endian integer greater than or equal to 500000000 representing the minimum Unix timestamp that this input requires to be set as the transaction's lock time.
|
| 0
@@ -166,8 +166,8 @@ The new per-input types for PSBT Version 2 are defined as follows:
| PSBT_IN_REQUIRED_HEIGHT_LOCKTIME = 0x12
| None
| No key data
-| <32-bit uiht>
-| 32 bit unsigned little endian integer less than 500000000 representing the minimum block height that this input requires to be set as the transaction's lock time.
+| <32-bit uint locktime>
+| 32 bit unsigned little endian integer greater than 0 and less than 500000000 representing the minimum block height that this input requires to be set as the transaction's lock time.
|
| 0
| 2
@@ -190,7 +190,7 @@ The new per-output types for PSBT Version 2 are defined as follows:
| PSBT_OUT_AMOUNT = 0x03
| None
| No key data
-| <64-bit int>
+| <64-bit little endian int amount>
| 64 bit signed little endian integer representing the output's amount in satoshis.
| 2
| 0
@@ -200,7 +200,7 @@ The new per-output types for PSBT Version 2 are defined as follows:
| PSBT_OUT_SCRIPT = 0x04
| None
| No key data
-|
+|
| The script for this output, also known as the scriptPubKey. Must be omitted in PSBTv0. Must be provided in PSBTv2.
| 2
| 0
@@ -209,18 +209,22 @@ The new per-output types for PSBT Version 2 are defined as follows:
===Determining Lock Time===
-The nLockTime field of a transaction is determined by inspecting the PSBT_GLOBAL_PREFERRED_LOCKTIME and each input's PSBT_IN_REQUIRED_TIME_LOCKTIME and PSBT_IN_REQUIRED_HEIGHT_LOCKTIME fields.
-If none of the inputs have a PSBT_IN_REQUIRED_TIME_LOCKTIME and PSBT_IN_REQUIRED_HEIGHT_LOCKTIME, then PSBT_GLOBAL_PREFERRED_LOCKTIME must be used.
-If PSBT_GLOBAL_PREFERRED_LOCKTIME is not provided, then it is assumed to be 0.
+The nLockTime field of a transaction is determined by inspecting the PSBT_GLOBAL_FALLBACK_LOCKTIME and each input's PSBT_IN_REQUIRED_TIME_LOCKTIME and PSBT_IN_REQUIRED_HEIGHT_LOCKTIME fields.
+If none of the inputs have a PSBT_IN_REQUIRED_TIME_LOCKTIME and PSBT_IN_REQUIRED_HEIGHT_LOCKTIME, then PSBT_GLOBAL_FALLBACK_LOCKTIME must be used.
+If PSBT_GLOBAL_FALLBACK_LOCKTIME is not provided, then it is assumed to be 0.
-If one or more inuts have a PSBT_IN_REQUIRED_TIME_LOCKTIME or PSBT_IN_REQUIRED_HEIGHT_LOCKTIME, then the field chosen is the one which is supported by all of the inputs.
+If one or more inputs have a PSBT_IN_REQUIRED_TIME_LOCKTIME or PSBT_IN_REQUIRED_HEIGHT_LOCKTIME, then the field chosen is the one which is supported by all of the inputs.
This can be determined by looking at all of the inputs which specify a locktime in either of those fields, and choosing the field which is present in all of those inputs.
Inputs not specifying a lock time field can take both types of lock times, as can those that specify both.
The lock time chosen is then the maximum value of the chosen type of lock time.
+If a PSBT has both types of locktimes possible because one or more inputs specify both PSBT_IN_REQUIRED_TIME_LOCKTIME and PSBT_IN_REQUIRED_HEIGHT_LOCKTIME, then locktime determined by looking at the PSBT_IN_REQUIRED_HEIGHT_LOCKTIME fields of the inputs must be chosen.'''Why choose the height based locktime?'''
+In the event of a tie for the locktime type, signers need to be able to know which locktime to use as their signatures will commit to the locktime in the transaction, so choosing the wrong one will result in an invalid transaction.
+Height based locktime is preferred over time based as Bitcoin's unit of time is the block height, so a height makes more sense in the context of Bitcoin.
+
===Unique Identification===
-PSBTv2s can be uniquely identified by constructing an unsigned transaction given the information provided in the PSBT and computing the transaction ID of that transaction.
+PSBTv2s can be uniquely identified by constructing an unsigned transaction given the information provided in the PSBT, and computing the transaction ID of that transaction.
Since PSBT_IN_SEQUENCE can be changed by Updaters and Combiners, the sequence number in this unsigned transaction must be set to 0 (not final, nor the sequence in PSBT_IN_SEQUENCE).
The lock time in this unsigned transaction must be computed as described previously.
@@ -231,9 +235,9 @@ PSBTv2 introduces new roles and modifies some existing roles.
===Creator===
In PSBTv2, the Creator initializes the PSBT with 0 inputs and 0 outputs.
-The PSBT version number is set to 2. The transaction version number must be set to at least 2. '''Why does the transaction version number need to be at least 2?''' The transaction version number is part of the validation rules for some features such as OP_CHECKSEQUENCEVERIFY. Since it is backwards compatible, and there are other ways to disable those features (e.g. through sequence numbers), it is easier to require transactions be able to support these features than to try to negotiate the transaction version number.
-The Creator should also set PSBT_GLOBAL_PREFERRED_LOCKTIME.
-If the Creator is not also a Constructor and will be giving the PSBT to others to add inputs and outputs, the PSBT_GLOBAL_TX_MODIFIABLE field must be present and and the Inputs Modifiable and Outputs Modifiable flags set appropriately.
+The PSBT version number is set to 2.
+The Creator should also set PSBT_GLOBAL_FALLBACK_LOCKTIME.
+If the Creator is not also a Constructor and will be giving the PSBT to others to add inputs and outputs, the PSBT_GLOBAL_TX_MODIFIABLE field must be present and the Inputs Modifiable and Outputs Modifiable flags set appropriately; moreover, the transaction version number must be set to at least 2. '''Why does the transaction version number need to be at least 2?''' The transaction version number is part of the validation rules for some features such as OP_CHECKSEQUENCEVERIFY. Since it is backwards compatible, and there are other ways to disable those features (e.g. through sequence numbers), it is easier to require transactions be able to support these features than to try to negotiate the transaction version number.
If the Creator is a Constructor and no inputs and outputs will be added by other entities, PSBT_GLOBAL_TX_MODIFIABLE may be omitted.
===Constructor===
@@ -244,11 +248,11 @@ Before any input or output may be added, the constructor must check the PSBT_GLO
Inputs may only be added if the Inputs Modifiable flag is True.
Outputs may only be added if the Outputs Modifiable flag is True.
-When an input or output is added, the corresponding PSBT_GLOBAL_INPUT_COUNT or PSBT_GLOBAL_OUTPUT_COUNT must be incremeted to reflect the number of inputs and outputs in the PSBT.
+When an input or output is added, the corresponding PSBT_GLOBAL_INPUT_COUNT or PSBT_GLOBAL_OUTPUT_COUNT must be incremented to reflect the number of inputs and outputs in the PSBT.
When an input is added, it must have PSBT_IN_PREVIOUS_TXID and PSBT_IN_OUTPUT_INDEX set.
When an output is added, it must have PSBT_OUT_VALUE and PSBT_OUT_OUTPUT_SCRIPT set.
If the input has a required timelock, Constructors must set the requisite timelock field.
-If the input has a required time based timelock, then PSBT_IN_REQUIRED_TIME_TIMELOCK must be set
+If the input has a required time based timelock, then PSBT_IN_REQUIRED_TIME_TIMELOCK must be set.
If the input has a required height based timelock, then PSBT_IN_REQUIRED_HEIGHT_TIMELOCK must be set.
If an input has both types of timelocks, then both may be set.
In some cases, an input that can allow both types, but a particular branch supporting only one type of timelock will be taken, then the type of timelock that will be used can be the only one set.
@@ -261,7 +265,7 @@ If it changes the transaction's locktime when there are existing signatures, it
If the Has SIGHASH_SINGLE flag is True, then the Constructor must iterate through the inputs and find the inputs which have signatures that use SIGHASH_SINGLE.
The same number of inputs and outputs must be added before those inputs and their corresponding outputs.
-A Constructor may choose to declare that no further inputs and outputs can be added to the transaction by setting the booleans in PSBT_GLOBAL_TX_MODIFIABLE to False or by removing this field entirely.
+A Constructor may choose to declare that no further inputs and outputs can be added to the transaction by setting the appropriate bits in PSBT_GLOBAL_TX_MODIFIABLE to 0 or by removing the field entirely.
A single entity is likely to be both a Creator and Constructor.
@@ -284,7 +288,7 @@ The Extractor should produce a fully valid, network serialized transaction if al
==Backwards Compatibility==
-PSBTv2 shares the same gemeric format as PSBTv0 as defined in BIP 174. Parsers for PSBTv0 should
+PSBTv2 shares the same generic format as PSBTv0 as defined in BIP 174. Parsers for PSBTv0 should
be able to deserialize PSBTv2 with only changes to support the new fields.
However PSBTv2 is incompatible with PSBTv0, and vice versa due to the use of the PSBT_GLOBAL_VERSION.
@@ -294,7 +298,198 @@ transaction from the PSBTv2 fields.
==Test Vectors==
-TBD
+The following are invalid PSBTs:
+
+* Case: PSBTv0 but with PSBT_GLOBAL_VERSION set to 2.
+** Bytes in Hex:
+
+* Case: 1 input, 2 output updated PSBTv2, with both Inputs Modifiable Flag (bit 0) and Outputs Modifiable Flag (bit 1) of PSBT_GLOBAL_TX_MODIFIABLE set
+** Bytes in Hex:
+
+* Case: 1 input, 2 output updated PSBTv2, with both Inputs Modifiable Flag (bit 0) and Has SIGHASH_SINGLE Flag (bit 2) of PSBT_GLOBAL_TX_MODIFIABLE set
+** Bytes in Hex:
+
+* Case: 1 input, 2 output updated PSBTv2, with both Outputs Modifiable Flag (bit 1) and Has SIGHASH_SINGLE FLag (bit 2) of PSBT_GLOBAL_TX_MODIFIABLE set
+** Bytes in Hex:
+
+The following tests are the timelock determination algorithm.
+
+The timelock for the following PSBTs should be computed to be 0:
+
+* Case: No locktimes specified
+** Bytes in Hex:
+
+The timelock for the following PSBTs should be computed to be 10000:
+
+* Case: Input 1 has PSBT_IN_REQUIRED_HEIGHT_LOCKTIME of 10000, Input 2 has no locktime fields
+** Bytes in Hex:
+
+* Case: Input 1 has PSBT_IN_REQUIRED_HEIGHT_LOCKTIME of 10000, Input 2 has PSBT_IN_REQUIRED_HEIGHT_LOCKTIME of 9000 and PSBT_IN_REQUIRED_TIME_LOCKTIME of 1657048460
+** Bytes in Hex:
+
+* Case: Input 1 has PSBT_IN_REQUIRED_HEIGHT_LOCKTIME of 10000 and PSBT_IN_REQUIRED_TIME_LOCKTIME of 1657048459, Input 2 has PSBT_IN_REQUIRED_HEIGHT_LOCKTIME of 9000 and PSBT_IN_REQUIRED_TIME_LOCKTIME of 1657048460
+** Bytes in Hex:
+
+The timelock for the following PSBTs should be computed to be 1657048460:
+
+* Case: Input 1 has PSBT_IN_REQUIRED_TIME_LOCKTIME of 1657048459, Input 2 has PSBT_IN_REQUIRED_HEIGHT_LOCKTIME of 9000 and PSBT_IN_REQUIRED_TIME_LOCKTIME of 1657048460
+** Bytes in Hex:
+
+* Case: Input 1 has PSBT_IN_REQUIRED_HEIGHT_LOCKTIME of 10000 and PSBT_IN_REQUIRED_TIME_LOCKTIME of 1657048459, Input 2 has PSBT_IN_REQUIRED_TIME_LOCKTIME of 1657048460
+** Bytes in Hex:
+
+The timelock for the following PSBTs cannot be computed:
+
+* Case: Input 1 has PSBT_IN_REQUIRED_HEIGHT_LOCKTIME of 10000, Input 2 has PSBT_IN_REQUIRED_TIME_LOCKTIME of 1657048460
+** Bytes in Hex:
==Rationale==
@@ -302,4 +497,4 @@ TBD
==Reference implementation==
-The reference implementation of the PSBT format is available at https://github.com/achow101/bitcoin/tree/psbt2.
+The reference implementation of the PSBT format is available in [https://github.com/bitcoin/bitcoin/pull/21283 Bitcoin Core PR 21283].
diff --git a/bip-0371.mediawiki b/bip-0371.mediawiki
new file mode 100644
index 0000000000..92275698a4
--- /dev/null
+++ b/bip-0371.mediawiki
@@ -0,0 +1,250 @@
+
+ BIP: 371
+ Layer: Applications
+ Title: Taproot Fields for PSBT
+ Author: Ava Chow
+ Comments-Summary: No comments yet.
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0371
+ Status: Final
+ Type: Standards Track
+ Created: 2021-06-21
+ License: BSD-2-Clause
+
+
+==Introduction==
+
+===Abstract===
+
+This document proposes additional fields for BIP 174 PSBTv0 and BIP 370 PSBTv2 that allow for
+BIP 340/341/342 Taproot data to be included in a PSBT of any version. These will be fields for
+signatures and scripts that are relevant to the creation of Taproot inputs.
+
+===Copyright===
+
+This BIP is licensed under the 2-clause BSD license.
+
+===Motivation===
+
+BIPs 340, 341, and 342 specify Taproot which provides a wholly new way to create and spend Bitcoin outputs.
+The existing PSBT fields are unable to support Taproot due to the new signature algorithm and the method
+by which scripts are embedded inside of a Taproot output. Therefore new fields must be defined to allow
+PSBTs to carry the information necessary for signing Taproot inputs.
+
+==Specification==
+
+The new per-input types are defined as follows:
+
+{|
+! Name
+!
+!
+! Description
+!
+! Description
+! Versions Requiring Inclusion
+! Versions Requiring Exclusion
+! Versions Allowing Inclusion
+|-
+| Taproot Key Spend Signature
+| PSBT_IN_TAP_KEY_SIG = 0x13
+| None
+| No key data '''Why is there no key data for PSBT_IN_TAP_KEY_SIG'''The signature in a key path spend corresponds directly with the pubkey provided in the output script. Thus it is not necessary to provide any metadata that attaches the key path spend signature to a particular pubkey.
+| <64 or 65 byte signature>
+| The 64 or 65 byte Schnorr signature for key path spending a Taproot output. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+|-
+| Taproot Script Spend Signature
+| PSBT_IN_TAP_SCRIPT_SIG = 0x14
+|
+| A 32 byte X-only public key involved in a leaf script concatenated with the 32 byte hash of the leaf it is part of.
+| <64 or 65 byte signature>
+| The 64 or 65 byte Schnorr signature for this pubkey and leaf combination. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+|-
+| Taproot Leaf Script
+| PSBT_IN_TAP_LEAF_SCRIPT = 0x15
+|
+| The control block for this leaf as specified in BIP 341. The control block contains the merkle tree path to this leaf.
+| <8-bit uint leaf version>
+| The script for this leaf as would be provided in the witness stack followed by the single byte leaf version. Note that the leaves included in this field should be those that the signers of this input are expected to be able to sign for. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+|-
+| Taproot Key BIP 32 Derivation Path
+| PSBT_IN_TAP_BIP32_DERIVATION = 0x16
+| <32 byte xonlypubkey>
+| A 32 byte X-only public key involved in this input. It may be the output key, the internal key, or a key present in a leaf script.
+| <32 byte leaf hash>* <4 byte fingerprint> <32-bit little endian uint path element>*
+| A compact size unsigned integer representing the number of leaf hashes, followed by a list of leaf hashes, followed by the 4 byte master key fingerprint concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. Public keys are those needed to spend this output. The leaf hashes are of the leaves which involve this public key. The internal key does not have leaf hashes, so can be indicated with a hashes len of 0. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+|-
+| Taproot Internal Key
+| PSBT_IN_TAP_INTERNAL_KEY = 0x17
+| None
+| No key data
+| <32 byte xonlypubkey>
+| The X-only pubkey used as the internal key in this output.'''Why is the internal key provided?'''The internal key is not necessarily the same key as in the Taproot output script. BIP 341 recommends tweaking the key with the hash of itself. It may be necessary for signers to know what the internal key actually is so that they are able to determine whether an input can be signed by it. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+|-
+| Taproot Merkle Root
+| PSBT_IN_TAP_MERKLE_ROOT = 0x18
+| None
+| No key data
+| <32-byte hash>
+| The 32 byte Merkle root hash. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+|}
+
+The new per-output types are defined as follows:
+
+{|
+! Name
+!
+!
+! Description
+!
+! Description
+! Versions Requiring Inclusion
+! Versions Requiring Exclusion
+! Versions Allowing Inclusion
+|-
+| Taproot Internal Key
+| PSBT_OUT_TAP_INTERNAL_KEY = 0x05
+| None
+| No key data
+| <32 byte xonlypubkey>
+| The X-only pubkey used as the internal key in this output.
+|
+|
+| 0, 2
+|-
+| Taproot Tree
+| PSBT_OUT_TAP_TREE = 0x06
+| None
+| No key data
+| {<8-bit uint depth> <8-bit uint leaf version> }*
+| One or more tuples representing the depth, leaf version, and script for a leaf in the Taproot tree, allowing the entire tree to be reconstructed. The tuples must be in depth first search order so that the tree is correctly reconstructed. Each tuple is an 8-bit unsigned integer representing the depth in the Taproot tree for this script, an 8-bit unsigned integer representing the leaf version, the length of the script as a compact size unsigned integer, and the script itself.
+|
+|
+| 0, 2
+|-
+| Taproot Key BIP 32 Derivation Path
+| PSBT_OUT_TAP_BIP32_DERIVATION = 0x07
+| <32 byte xonlypubkey>
+| A 32 byte X-only public key involved in this output. It may be the output key, the internal key, or a key present in a leaf script.
+| <32 byte leaf hash>* <4 byte fingerprint> <32-bit little endian uint path element>*
+| A compact size unsigned integer representing the number of leaf hashes, followed by a list of leaf hashes, followed by the 4 byte master key fingerprint concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. Public keys are those needed to spend this output. The leaf hashes are of the leaves which involve this public key. The internal key does not have leaf hashes, so can be indicated with a hashes len of 0. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed.
+|
+|
+| 0, 2
+|}
+
+===UTXO Types===
+
+BIP 174 recommends using PSBT_IN_NON_WITNESS_UTXO for all inputs because of potential attacks involving
+an updater lying about the amounts in an output. Because a Taproot signature will commit to all of the amounts
+and output scripts spent by the inputs of the transaction, such attacks are prevented as any such lying would
+result in an invalid signature. Thus Taproot inputs can use just PSBT_IN_WITNESS_UTXO.
+
+==Compatibility==
+
+These are simply new fields added to the existing PSBT format. Because PSBT is designed to be extensible, old
+software will ignore the new fields.
+
+==Test Vectors==
+
+The following are invalid PSBTs:
+
+* Case: PSBT With PSBT_IN_TAP_INTERNAL_KEY key that is too long (incorrectly serialized as compressed DER)
+** Bytes in Hex:
+
+* Case: PSBT with one P2TR script path only input with dummy internal key, scripts, derivation paths for keys in the scripts, and merkle root
+** Bytes in Hex:
+
+* Case: PSBT with one P2TR script path only input with dummy internal key, scripts, script key derivation paths, merkle root, and script path signatures
+** Bytes in Hex:
+
+==Introduction==
+
+===Abstract===
+
+This document proposes additional fields for BIP 174 PSBTv0 and BIP 370 PSBTv2
+that allow for pay-to-contract (P2C) key tweaking data to be included in a PSBT
+of any version. These will represent extra-transaction information required
+for the signer to produce valid signatures spending previous outputs.
+
+===Copyright===
+
+This BIP is licensed under the 2-clause BSD license.
+
+===Background===
+
+Key tweaking is a procedure for creating a cryptographic commitment to a
+message using elliptic curve properties. The procedure uses the discrete log
+problem (DLP) to commit to an extra-transaction message. This is done by adding
+to a public key (for which the output owner knows the corresponding private key)
+a hash of the message multiplied by the generator point G of the elliptic curve.
+This produces a tweaked public key containing the commitment. Later, in order
+to spend an output containing the P2C commitment, the same commitment should be
+added to the corresponding private key.
+
+This type of commitment was originally proposed as a part of the pay to contract
+concept by Ilja Gerhardt and Timo Hanke in [1] and later used by Eternity Wall
+[2] for the same purpose. Since that time, multiple different protocols for P2C
+have been developed, including OpenTimeStamps [3], Elements sidechain P2C tweaks
+[4] and LNPBP-1 [5], used for constructing Peter Todd's single-use-seals [6]
+in client-side-validation protocols like RGB.
+
+===Motivation===
+
+P2C outputs can be detected onchain and spent only if the output owner
+not only knows the corresponding original private key, but also is aware of
+a P2C tweak applied to the public key. In order to produce a valid signature, the
+same tweak value must be added (modulo group order) to the original private key
+by a signer device. This represents a challenge for external signers, which may
+not have any information about such commitment. This proposal addresses this
+issue by adding relevant fields to the PSBT input information.
+
+The proposal abstracts details of specific P2C protocols and provides a universal
+method for spending previous outputs containing P2C tweaks, applied to the public
+key contained within any standard form of the scriptPubkey, including
+bare scripts and P2PK, P2PKH, P2SH, witness v0 P2WPKH, P2WSH, nested witness v0
+P2WPKH-P2SH, P2WSH-P2SH and witness v1 P2TR outputs.
+
+
+==Design==
+
+P2C-tweaked public keys are already exposed in the
+PSBT_IN_REDEEM_SCRIPT, PSBT_IN_WITNESS_SCRIPT,
+PSBT_IN_TAP_INTERNAL_KEY and PSBT_IN_TAP_LEAF_SCRIPT fields;
+the only information signer is needed to recognize which keys it should sign
+with is from which of the original keys they were generated. This is achieved by
+introducing a new `PSBT_IN_P2C_TWEAK` field, which has the original key as a field
+key and the tweak as a field value. The signer will recognize the keys which are
+available to it, apply the tweak to them and see in which scripts it was used --
+and use this information to apply tweaks for the corresponding private keys and
+produce valid signatures.
+
+
+==Specification==
+
+The new per-input type is defined as follows:
+
+{|
+! Name
+!
+!
+! Description
+!
+! Description
+! Versions Requiring Inclusion
+! Versions Requiring Exclusion
+! Versions Allowing Inclusion
+|-
+| P2C Key Tweak
+| PSBT_IN_P2C_TWEAK = 0x19
+|
+| 33 bytes of compact public key serialization specifying to which keys the
+P2C tweak may be applied (i.e. this MUST be a value of a public key before the
+tweak is applied). BIP-340 keys are serialized by appending `0x02`
+byte.'''Why compressed public keys are not distinguished from BIP-340
+public keys''' We follow the logic of BIP32 key derivation, which does not
+distinguish them. The type of the key is defined by the input type,
+and adding additional PSBT field types will just create the need for handling
+errors when the input type does not match the provided key type.
+|
+| The 32 byte value which MUST be added to a private key to produce a correct
+ECDSA and/or Schnorr signature ("key tweak"). Signers SHOULD remove this field
+after PSBT_IN_PARTIAL_SIG is constructed.
+|
+|
+| 0, 2
+| BIP-P2C
+|}
+
+
+==Security considerations==
+
+The scope of this proposal is deliberately kept narrow; it addresses
+only spending of transaction outputs containing P2C tweaks - and does not
+address construction of new P2C commitments or transactions containing them
+in their outputs.'''Why only spending of P2C tweaked outputs is covered'''
+P2C tweaks commit to external data, some of which may represent certain values
+(like in some sidechains, single-use-seal applications like RGB, etc). Creation
+of such outputs may allow hardware devices to understand the structure of such
+extra-transaction data, which may be in different formats and constantly
+evolve. Thus, this should be addressed with separate standards (or be
+vendor-based). The current proposal only touches the question of spending an
+output that contained a previously created P2C commitment, which does not create
+a new commitment and does not provide that kind of risk of extra-blockchain
+value losses.
+
+
+==Rationale==
+
+
+
+
+==Compatibility==
+
+The proposal is compatible with the existing consensus rules and does not
+require any modification to them.
+
+The proposed P2C PSBT fields provide sufficient information for creating
+valid signatures for spending the following output types containing tweaked
+public keys:
+- bare scripts,
+- P2PK,
+- P2PKH,
+- P2SH,
+- witness v0 P2WPKH and P2WSH,
+- nested witness v0 P2WPKH-P2SH and P2WSH-P2SH
+
+Post-0 witness versions, including taproot outputs and future witness versions,
+may not be supported or covered by this BIP and may require the addition of new
+fields to the PSBT inputs.
+
+
+==Reference implementation==
+
+WIP
+
+
+==Acknowledgements==
+
+The author is grateful to Andrew Poelstra, who provided an initial set of ideas
+and information with his previous work on the topic, on which this standard
+was designed.
+
+
+==Test vectors==
+
+TBD
+
+
+==References==
+
+[1] Ilja Gerhardt, Timo Hanke. ''Homomorphic Payment Addresses and the Pay-to-Contract Protocol.'' arXiv:1212.3257 [cs.CR]. [https://arxiv.org/pdf/1212.3257.pdf arxiv.org/pdf/1212.3257.pdf]
+
+[2] Eternity Wall. ''Sign-to-contract.'' [https://blog.eternitywall.com/2018/04/13/sign-to-contract/ blog.eternitywall.com]
+
+[3] Peter Todd. ''OpenTimestamps: Scalable, Trust-Minimized, Distributed Timestamping with Bitcoin.'' [https://petertodd.org/2016/opentimestamps-announcement petertodd.org]
+
+[4] Adam Back, Matt Corallo, Luke Dashjr, et al. ''Enabling Blockchain Innovations with Pegged Sidechains (commit5620e43). Appendix A.'' [https://blockstream.com/sidechains.pdf blockstream.com/sidechains.pdf]
+
+[5] Maxim Orlovsky, Rene Pickhardt, Federico Tenga, et al. ''Key tweaking: collision-resistant elliptic curve-based commitments. LNPBP-1 Standard.'' [https://github.com/LNP-BP/LNPBPs/blob/master/lnpbp-0001.md LNPBP-1 on GitHub]
+
+[6] Peter Todd. ''Single-use-seals. LNPBP-8 Standard.'' [https://github.com/LNP-BP/LNPBPs/blob/master/lnpbp-0008.md LNPBP-8 on GitHub]
+
+
diff --git a/bip-0373.mediawiki b/bip-0373.mediawiki
new file mode 100644
index 0000000000..2c8b85e88d
--- /dev/null
+++ b/bip-0373.mediawiki
@@ -0,0 +1,305 @@
+
+
+==Introduction==
+
+===Abstract===
+
+This document proposes additional fields for BIP 174 PSBTv0 and BIP 370 PSBTv2 that allow for BIP
+327 MuSig2 Multi-Signature data to be included in a PSBT of any version. These will be fields for
+the participants' keys, the public nonces, and the partial signatures produced with MuSig2.
+
+===Copyright===
+
+This BIP is licensed under the Creative Commons CC0 1.0 Universal license.
+
+===Motivation===
+
+BIP 327 specifies a way to create BIP 340 compatible public keys and signatures using the MuSig2
+Multi-Signature scheme. The existing PSBT fields are unable to support MuSig2 as it introduces new
+concepts and additional rounds of communication. Therefore new fields must be defined to allow PSBTs
+to carry the information necessary to produce a valid signature with MuSig2.
+
+==Specification==
+
+The new per-input types are defined as follows:
+
+{|
+! Name
+!
+!
+!
+! Versions Requiring Inclusion
+! Versions Requiring Exclusion
+! Versions Allowing Inclusion
+|-
+| rowspan="2"|MuSig2 Participant Public Keys
+| rowspan="2"|PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1a
+| <33 byte aggregate pubkey (compressed)>
+| <33 byte participant pubkey (compressed)>*
+| rowspan="2"|
+| rowspan="2"|
+| rowspan="2"| 0, 2
+|-
+| The MuSig2 aggregate public key (compressed) '''Why the compressed aggregate public key instead of x-only?'''
+BIP 32 public keys can be derived from a BIP 327 MuSig2 aggregate public key (see: [[bip-0328.mediawiki|BIP 328]]).
+But since BIP 32 requires public keys to include their evenness byte, BIP 327 MuSig2 aggregate public keys must
+include their evenness byte as well. Furthermore, PSBT_IN_TAP_BIP32_DERIVATION fields include fingerprints to identify
+master keys, and these fingerprints require the y-coordinate of the public key, so x-only serialization can't be used.
+By including the aggregate key as a full public key, signers that are unaware of the MuSig2 outside of the PSBT will
+still be able to identify which keys are derived from the aggregate key by computing and then comparing the
+fingerprints. This is necessary for the signer to apply the correct tweaks to their partial signature. from the
+KeyAgg algorithm. This key may or may not appear (as x-only) in the Taproot output key, the internal key, or
+in a script. It may instead be a parent public key from which the Taproot output key, internal key, or keys in a script
+were derived.
+| A list of the compressed public keys of the participants in the MuSig2 aggregate key in the order
+required for aggregation. If sorting was done, then the keys must be in the sorted order.
+|-
+| rowspan="2"|MuSig2 Public Nonce
+| rowspan="2"|PSBT_IN_MUSIG2_PUB_NONCE = 0x1b
+| <33 byte participant pubkey (compressed)> <33 byte aggregate pubkey (compressed)> <32 byte hash or omitted>
+| <66 byte public nonce>
+| rowspan="2"|
+| rowspan="2"|
+| rowspan="2"| 0, 2
+|-
+| The compressed public key of the participant providing this nonce, followed by the compressed aggregate public
+key the participant is providing the nonce for, followed by the BIP 341 tapleaf hash of
+the Taproot leaf script that will be signed. If the aggregate key is the Taproot internal key or the
+Taproot output key, then the tapleaf hash must be omitted. The compressed participant public key must be
+the Taproot output key or found in a script. It is not the internal key nor the aggregate public key that
+it was derived from, if it was derived from an aggregate key.
+| The public nonce produced by the NonceGen algorithm.
+|-
+| rowspan="2"|MuSig2 Participant Partial Signature
+| rowspan="2"|PSBT_IN_MUSIG2_PARTIAL_SIG = 0x1c
+| <33 byte participant pubkey (compressed)> <33 byte aggregate pubkey (compressed)> <32 byte hash or omitted>
+| <32 byte partial signature>
+| rowspan="2"|
+| rowspan="2"|
+| rowspan="2"| 0, 2
+|-
+| The compressed public key of the participant providing this partial signature, followed by the
+compressed public key the participant is providing the signature for, followed by the BIP 341 tapleaf hash
+of the Taproot leaf script that will be signed. If the aggregate key is the Taproot internal key or
+the Taproot output key, then the tapleaf hash must be omitted. Note that the compressed participant public key must be
+the Taproot output key or found in a script. It is not the internal key nor the aggregate public key that
+it was derived from, if it was derived from an aggregate key.
+| The partial signature produced by the Sign algorithm.
+|}
+
+The new per-output types are defined as follows:
+
+{|
+! Name
+!
+!
+!
+! Versions Requiring Inclusion
+! Versions Requiring Exclusion
+! Versions Allowing Inclusion
+|-
+| rowspan="2"|MuSig2 Participant Public Keys
+| rowspan="2"|PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS = 0x08
+| <33 byte aggregate pubkey (compressed)>
+| <33 byte participant pubkey (compressed)>*
+| rowspan="2"|
+| rowspan="2"|
+| rowspan="2"|0, 2
+|-
+| The MuSig2 compressed aggregate public key from the KeyAgg algorithm. This key may or may not
+appear (as x-only) in the Taproot output key, the internal key, or in a script. It may instead be a parent
+public key from which the Taproot output key, internal key, or keys in a script were derived.
+| A list of the compressed public keys of the participants in the MuSig2 aggregate key in the order
+required for aggregation. If sorting was done, then the keys must be in the sorted order.
+|}
+
+==Roles==
+
+===Updater===
+
+When an updater observes a Taproot output which involves a MuSig2 aggregate public key that it is
+aware of, it can add a PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS field containing the public keys
+of the participants. This aggregate public key may be directly in the script, the Taproot internal
+key, the Taproot output key, or a public key from which the key in the script was derived from.
+
+An aggregate public key that appears directly in the script or internal key may be from the result
+of deriving child pubkeys from participant xpubs. If the updater has this derivation information, it
+should also add PSBT_IN_TAP_BIP32_DERIVATION for each participant public key.
+
+If the public key found was derived from an aggregate public key, then all MuSig2 PSBT fields for
+that public key should contain the aggregate public key rather than the found pubkey itself. The
+updater should also add PSBT_IN_TAP_BIP32_DERIVATION that contains the derivation path used
+to derive the found pubkey from the aggregate pubkey.
+Derivation from the aggregate pubkey can be assumed to follow [[bip-0328.mediawiki|BIP 328]]
+if there is no PSBT_IN_GLOBAL_XPUB that specifies the synthetic xpub for the aggregate
+public key.
+
+Updaters should add PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS and
+PSBT_OUT_TAP_BIP32_DERIVATION similarly to inputs to aid in change detection.
+
+===Signer===
+
+To determine whether a signer is a participant in the MuSig2 aggregate key, the signer should first
+look at all PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS and see if any key which it knows the
+private key for appears as a participant in any aggregate pubkey. Signers should also check whether
+any of the keys in PSBT_IN_TAP_BIP32_DERIVATION belong to it, and if any of those keys
+appear in as a participant in PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS.
+
+For each aggregate public key that the signer is a participant of that it wants
+to produce a signature for, if the signer does not find an existing
+PSBT_IN_MUSIG2_PUB_NONCE field for its key, then it should add one using
+the NonceGen algorithm (or one of its variations) to produce a public
+nonce that is added in a PSBT_IN_MUSIG2_PUB_NONCE field. However
+signers must keep in mind that '''improper nonce usage can compromise private
+keys.''' Please see BIP 327 for best practices on nonce generation and usage.
+
+Once all signers have added their PSBT_IN_MUSIG2_PUB_NONCE fields, each signer will perform
+the NonceAgg algorithm followed by the Sign algorithm in order to produce the
+partial signature for their key. The result will be added to the PSBT in a
+PSBT_IN_MUSIG2_PARTIAL_SIG field.
+
+Signers must remember to apply any relevant tweaks such as a tweak that is the result of performing
+BIP 32 unhardened derivation with the aggregate public key as the parent key.
+
+If all other signers have provided a PSBT_IN_MUSIG2_PARTIAL_SIG, then the final signer may
+perform the PartialSigAgg algorithm and produce a BIP 340 compatible signature that can be
+placed into a PSBT_IN_TAP_KEY_SIG or a PSBT_IN_TAP_SCRIPT_SIG.
+
+===Finalizer===
+
+A finalizer may perform the same PartialSigAgg step as the final signer if it has not
+already been done.
+
+Otherwise, the resulting signature is a BIP 340 compatible signature and finalizers should treat it
+as such.
+
+==Backwards Compatibility==
+
+These are simply new fields added to the existing PSBT format. Because PSBT is designed to be
+extensible, old software will ignore the new fields.
+
+Reusing PSBT_IN_TAP_BIP32_DERIVATION to provide derivation paths for participant public
+keys may cause software unaware of MuSig2 to produce a signature for that public key. This is still
+safe. If that public key does not directly appear in the leaf script that was signed, then the
+signature produced will not be useful and so cannot be replayed. If the public key does directly
+appear in the leaf script, then the signer will have validated the script as if it did not involve a
+MuSig2 and will have found it acceptable in order for it to have produced a signature. In either
+case, producing a signature does not give rise to the possibility of losing funds.
+
+==Test Vectors==
+
+The following are valid PSBTs
+
+All of the following test cases use the aggregate pubkey 030b58e337aa4d3852a8c29387c42408d8cfbe3a613a5e397e0a9f01a5fb7107d4
+which has the following participant keys:
+
+# 02346B99593357107C9D3459E9DEBA8D3EAF44E6636C85C7F853EB90BA52E8CD00, L2XJhGmS9rkNwzn1eFJVD5ydKpA5K5p54uk9qqWpURj85VkEPuNE, cStJABmHavSe7SFH2f7caQUgx3TUyXum8wtcxFyKyYP8LEqnMiEh
+# 024fafd65f8169186fc2bfdb2233c77e630d10be280a24c7165c09a27611775c2c, L19kEzCkrce5E3v7CWKn9pTceVzFwwdorjNXfqtUc5nKLXz4qXSX, cRWjhuCcHgLLPVPNav8uX8xgGjHfcPjVvmWznGLz7CSKbGzmfvRQ
+# 02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9, KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74sHUHy8S, cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87KcLPVfXz
+
+* Case: Spend of a Taproot output where the output key is a MuSig2 Aggregate Pubkey
+** With participant pubkeys only
+*** Bytes in Hex:
+* Case: Spend of a Taproot output where the internal key is derived from a MuSig2 Aggregate Pubkey
+** With participant pubkeys only
+*** Bytes in Hex:
+
+==Rationale==
+
+
+
+==Reference implementation==
+
+The reference implementation of the PSBT format is available at Bitcoin Core [[https://github.com/bitcoin/bitcoin/pull/31247|PR #31247]].
+
+==Acknowledgements==
+
+Thanks to Sanket Kanjalkar whose notes on this topic formed the initial basis of this BIP. Also
+thanks to Pieter Wuille, Jonas Nick, Tim Ruffing, Marko Bencun, Salvatore Ingala, and all others who
+have participated in discussions about these fields.
diff --git a/bip-0374.mediawiki b/bip-0374.mediawiki
new file mode 100644
index 0000000000..0abb895776
--- /dev/null
+++ b/bip-0374.mediawiki
@@ -0,0 +1,135 @@
+
+
+== Introduction ==
+
+=== Abstract ===
+
+This document proposes a standard for 64-byte zero-knowledge ''discrete logarithm equality proofs'' (DLEQ proofs) over an elliptic curve. For given elliptic curve points ''A'', ''B'', ''C'', ''G'', and a scalar ''a'' known only to the prover where ''A = a⋅G'' and ''C = a⋅B'', the prover proves knowledge of ''a'' without revealing anything about ''a''. This can, for instance, be useful in ECDH: if ''A'' and ''B'' are ECDH public keys, and ''C'' is their ECDH shared secret computed as ''C = a⋅B'', the proof establishes that the same secret key ''a'' is used for generating both ''A'' and ''C'' without revealing ''a''.
+
+=== Copyright ===
+
+This document is licensed under the 2-clause BSD license.
+
+=== Motivation ===
+
+[https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#specification BIP352] requires senders to compute output scripts using ECDH shared secrets from the same secret keys used to sign the inputs. Generating an incorrect signature will produce an invalid transaction that will be rejected by consensus. An incorrectly generated output script can still be consensus-valid, meaning funds may be lost if it gets broadcast.
+By producing a DLEQ proof for the generated ECDH shared secrets, the signing entity can prove to other entities that the output scripts have been generated correctly without revealing the private keys.
+
+== Specification ==
+
+All conventions and notations are used as defined in [https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki#user-content-Notation BIP327].
+
+=== Description ===
+
+The basic proof generation uses a random scalar ''k'', the secret ''a'', and the point being proven ''C = a⋅B''.
+
+* Let ''R1 = k⋅G''.
+* Let ''R2 = k⋅B''.
+* Let ''e = hash(R1 || R2)''.
+* Let ''s = (k + e⋅a)''.
+
+Providing only ''C'', ''e'' and ''s'' as a proof does not reveal ''a'' or ''k''.
+
+Verifying the proof involves recreating ''R1'' and ''R2'' with only ''e'' and ''s'' as follows:
+
+* Let ''R1 = s⋅G - e⋅A''.
+* Let ''R2 = s⋅B - e⋅C''.
+
+This can be verified by substituting ''s = (k + e⋅a)'':
+
+* ''s⋅G - e⋅A = (k + e⋅a)⋅G - e⋅A = k⋅G + e⋅(a⋅G) - e⋅A = k⋅G + e⋅A - e⋅A = k⋅G''.
+* ''s⋅B - e⋅C = (k + e⋅a)⋅B - e⋅C = k⋅B + e⋅(a⋅B) - e⋅C = k⋅B + e⋅C - e⋅C = k⋅B''.
+
+Thus verifying ''e = hash(R1 || R2)'' proves the discrete logarithm equivalency of ''A'' and ''C''.
+
+=== DLEQ Proof Generation ===
+
+The following generates a proof that the result of ''a⋅B'' and the result of ''a⋅G'' are both generated from the same scalar ''a'' without having to reveal ''a''.
+
+Input:
+* The secret key ''a'': a 256-bit unsigned integer
+* The public key ''B'': a point on the curve
+* Auxiliary random data ''r'': a 32-byte array ''' Why include auxiliary random data?''' The auxiliary random data should be set to fresh randomness for each proof. The same rationale and recommendations from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#default-signing BIP340] should be applied.
+* The generator point ''G'': a point on the curve ''' Why include the generator point G as an input?''' While all other BIPs have used the generator point from secp256k1, passing it as an input here lets this algorithm be used for other curves.
+* An optional message ''m'': a 32-byte array ''' Why include a message as an input?''' This could be useful for protocols that want to authorize on a compound statement, not just knowledge of a scalar. This allows the protocol to combine knowledge of the scalar and the statement.
+
+The algorithm ''GenerateProof(a, B, r, G, m)'' is defined as:
+* Fail if ''a = 0'' or ''a ≥ n''.
+* Fail if ''is_infinite(B)''.
+* Let ''A = a⋅G''.
+* Let ''C = a⋅B''.
+* Let ''t'' be the byte-wise xor of ''bytes(32, a)'' and ''hashBIP0374/aux(r)''.
+* Let ''m' = m if m is provided, otherwise an empty byte array''.
+* Let ''rand = hashBIP0374/nonce(t || cbytes(A) || cbytes(C) || m')''. ''' Why include the message in the rand computation?''' Not including the message in the rand computation could leak ''a'' if two proofs were constructed for the same ''a'', ''B'', and ''G'' but a different message ''m'' and an all-zero ''r''.
+* Let ''k = int(rand) mod n''.
+* Fail if ''k = 0''.
+* Let ''R1 = k⋅G''.
+* Let ''R2 = k⋅B''.
+* Let ''e = int(hashBIP0374/challenge(cbytes(A) || cbytes(B) || cbytes(C) || cbytes(G) || cbytes(R1) || cbytes(R2) || m'))''.
+* Let ''s = (k + e⋅a) mod n''.
+* Let ''proof = bytes(32, e) || bytes(32, s)''.
+* If ''VerifyProof(A, B, C, proof)'' (see below) returns failure, abort.
+* Return the proof ''proof''.
+
+=== DLEQ Proof Verification ===
+
+The following verifies the proof generated in the previous section. If the following algorithm succeeds, the points ''A'' and ''C'' were both generated from the same scalar. The former from multiplying by ''G'', and the latter from multiplying by ''B''.
+
+Input:
+* The public key of the secret key used in the proof generation ''A'': a point on the curve
+* The public key used in the proof generation ''B'': a point on the curve
+* The result of multiplying the secret and public keys used in the proof generation ''C'': a point on the curve
+* A proof ''proof'': a 64-byte array
+* The generator point used in the proof generation ''G'': a point on the curve ''' Why include the generator point G as an input?''' While all other BIPs have used the generator point from Secp256k1, passing it as an input here lets this algorithm be used for other curves.
+* An optional message ''m'': a 32-byte array ''' Why include a message as an input?''' This could be useful for protocols that want to authorize on a compound statement, not just knowledge of a scalar. This allows the protocol to combine knowledge of the scalar and the statement.
+
+The algorithm ''VerifyProof(A, B, C, proof, G, m)'' is defined as:
+* Fail if any of ''is_infinite(A)'', ''is_infinite(B)'', ''is_infinite(C)'', ''is_infinite(G)''
+* Let ''e = int(proof[0:32])''.
+* Let ''s = int(proof[32:64])''; fail if ''s ≥ n''.
+* Let ''R1 = s⋅G - e⋅A''.
+* Fail if ''is_infinite(R1)''.
+* Let ''R2 = s⋅B - e⋅C''.
+* Fail if ''is_infinite(R2)''.
+* Let ''m' = m if m is provided, otherwise an empty byte array''.
+* Fail if ''e ≠ int(hashBIP0374/challenge(cbytes(A) || cbytes(B) || cbytes(C) || cbytes(G) || cbytes(R1) || cbytes(R2) || m'))''.
+* Return success iff no failure occurred before reaching this point.
+
+==Backwards Compatibility==
+
+This proposal is compatible with all older clients.
+
+== Test Vectors and Reference Code ==
+
+A reference python implementation is included [https://github.com/bitcoin/bips/blob/master/bip-0374/reference.py here].
+Test vectors can be generated by running ./bip-0374/gen_test_vectors.py which will produce a CSV file of random test vectors for both generating and verifying proofs. These can be run against the reference implementation with ./bip-0374/run_test_vectors.py.
+
+== Changelog ==
+
+* 0.2.0 (2025-02-27):
+** Add the message to the rand computation
+* 0.1.0 (2024-12-26):
+** Initial version
+
+== Footnotes ==
+
+
+
+== Acknowledgements ==
+
+Thanks to josibake, Tim Ruffing, benma, stratospher, waxwing, Yuval Kogman and all others who
+participated in discussions on this topic.
diff --git a/bip-0374/gen_test_vectors.py b/bip-0374/gen_test_vectors.py
new file mode 100755
index 0000000000..792a59a45b
--- /dev/null
+++ b/bip-0374/gen_test_vectors.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python3
+"""Generate the BIP-0374 test vectors."""
+import csv
+import os
+import sys
+from reference import (
+ TaggedHash,
+ dleq_generate_proof,
+ dleq_verify_proof,
+)
+from secp256k1 import G as GENERATOR, GE
+
+
+NUM_SUCCESS_TEST_VECTORS = 8
+DLEQ_TAG_TESTVECTORS_RNG = "BIP0374/testvectors_rng"
+
+FILENAME_GENERATE_PROOF_TEST = os.path.join(sys.path[0], 'test_vectors_generate_proof.csv')
+FILENAME_VERIFY_PROOF_TEST = os.path.join(sys.path[0], 'test_vectors_verify_proof.csv')
+
+
+def random_scalar_int(vector_i, purpose):
+ rng_out = TaggedHash(DLEQ_TAG_TESTVECTORS_RNG, purpose.encode() + vector_i.to_bytes(4, 'little'))
+ return int.from_bytes(rng_out, 'big') % GE.ORDER
+
+
+def random_bytes(vector_i, purpose):
+ rng_out = TaggedHash(DLEQ_TAG_TESTVECTORS_RNG, purpose.encode() + vector_i.to_bytes(4, 'little'))
+ return rng_out
+
+
+def create_test_vector_data(vector_i):
+ g = random_scalar_int(vector_i, "scalar_g") if vector_i < 5 else 1
+ assert 0 < g < GE.ORDER
+ G = g * GENERATOR
+ assert not G.infinity
+ a = random_scalar_int(vector_i, "scalar_a")
+ A = a * G
+ b = random_scalar_int(vector_i, "scalar_b")
+ B = b * G
+ C = a * B # shared secret
+ assert C.to_bytes_compressed() == (b * A).to_bytes_compressed()
+ auxrand = random_bytes(vector_i, "auxrand")
+ msg = random_bytes(vector_i, "message") if vector_i != 5 else None
+ proof = dleq_generate_proof(a, B, auxrand, G=G, m=msg)
+ return (G, a, A, b, B, C, auxrand, msg, proof)
+
+TEST_VECTOR_DATA = [create_test_vector_data(i) for i in range(NUM_SUCCESS_TEST_VECTORS)]
+
+
+def gen_all_generate_proof_vectors(f):
+ writer = csv.writer(f)
+ writer.writerow(("index", "point_G", "scalar_a", "point_B", "auxrand_r", "message", "result_proof", "comment"))
+
+ # success cases with random values
+ idx = 0
+ for i in range(NUM_SUCCESS_TEST_VECTORS):
+ G, a, A, b, B, C, auxrand, msg, proof = TEST_VECTOR_DATA[i]
+ assert proof is not None and len(proof) == 64
+ if msg is None: msg = b""
+ writer.writerow((idx, G.to_bytes_compressed().hex(), f"{a:064x}", B.to_bytes_compressed().hex(), auxrand.hex(), msg.hex(), proof.hex(), f"Success case {i+1}"))
+ idx += 1
+
+ # failure cases: a is not within group order (a=0, a=N)
+ a_invalid = 0
+ assert dleq_generate_proof(a_invalid, B, auxrand, G=G, m=msg) is None
+ writer.writerow((idx, G.to_bytes_compressed().hex(), f"{a_invalid:064x}", B.to_bytes_compressed().hex(), auxrand.hex(), msg.hex(), "INVALID", f"Failure case (a=0)"))
+ idx += 1
+ a_invalid = GE.ORDER
+ assert dleq_generate_proof(a_invalid, B, auxrand, G=G, m=msg) is None
+ writer.writerow((idx, G.to_bytes_compressed().hex(), f"{a_invalid:064x}", B.to_bytes_compressed().hex(), auxrand.hex(), msg.hex(), "INVALID", f"Failure case (a=N [group order])"))
+ idx += 1
+
+ # failure case: B is point at infinity
+ B_infinity = GE()
+ B_infinity_str = "INFINITY"
+ assert dleq_generate_proof(a, B_infinity, auxrand, m=msg) is None
+ writer.writerow((idx, G.to_bytes_compressed().hex(), f"{a:064x}", B_infinity_str, auxrand.hex(), msg.hex(), "INVALID", f"Failure case (B is point at infinity)"))
+ idx += 1
+
+
+def gen_all_verify_proof_vectors(f):
+ writer = csv.writer(f)
+ writer.writerow(("index", "point_G", "point_A", "point_B", "point_C", "proof", "message", "result_success", "comment"))
+
+ # success cases (same as above)
+ idx = 0
+ for i in range(NUM_SUCCESS_TEST_VECTORS):
+ G, _, A, _, B, C, _, msg, proof = TEST_VECTOR_DATA[i]
+ assert dleq_verify_proof(A, B, C, proof, G=G, m=msg)
+ if msg is None: msg = b""
+ writer.writerow((idx, G.to_bytes_compressed().hex(), A.to_bytes_compressed().hex(), B.to_bytes_compressed().hex(),
+ C.to_bytes_compressed().hex(), proof.hex(), msg.hex(), "TRUE", f"Success case {i+1}"))
+ idx += 1
+
+ # other permutations of A, B, C should always fail
+ for i, points in enumerate(([A, C, B], [B, A, C], [B, C, A], [C, A, B], [C, B, A])):
+ assert not dleq_verify_proof(points[0], points[1], points[2], proof, m=msg)
+ writer.writerow((idx, G.to_bytes_compressed().hex(), points[0].to_bytes_compressed().hex(), points[1].to_bytes_compressed().hex(),
+ points[2].to_bytes_compressed().hex(), proof.hex(), msg.hex(), "FALSE", f"Swapped points case {i+1}"))
+ idx += 1
+
+ # modifying proof should fail (flip one bit)
+ proof_damage_pos = random_scalar_int(idx, "damage_pos") % 256
+ proof_damaged = list(proof)
+ proof_damaged[proof_damage_pos // 8] ^= (1 << (proof_damage_pos % 8))
+ proof_damaged = bytes(proof_damaged)
+ writer.writerow((idx, G.to_bytes_compressed().hex(), A.to_bytes_compressed().hex(), B.to_bytes_compressed().hex(),
+ C.to_bytes_compressed().hex(), proof_damaged.hex(), msg.hex(), "FALSE", f"Tampered proof (random bit-flip)"))
+ idx += 1
+
+ # modifying message should fail (flip one bit)
+ msg_damage_pos = random_scalar_int(idx, "damage_pos") % 256
+ msg_damaged = list(msg)
+ msg_damaged[msg_damage_pos // 8] ^= (1 << (msg_damage_pos % 8))
+ msg_damaged = bytes(msg_damaged)
+ writer.writerow((idx, G.to_bytes_compressed().hex(), A.to_bytes_compressed().hex(), B.to_bytes_compressed().hex(),
+ C.to_bytes_compressed().hex(), proof.hex(), msg_damaged.hex(), "FALSE", f"Tampered message (random bit-flip)"))
+ idx += 1
+
+
+if __name__ == "__main__":
+ print(f"Generating {FILENAME_GENERATE_PROOF_TEST}...")
+ with open(FILENAME_GENERATE_PROOF_TEST, "w", encoding="utf-8") as fil_generate_proof:
+ gen_all_generate_proof_vectors(fil_generate_proof)
+ print(f"Generating {FILENAME_VERIFY_PROOF_TEST}...")
+ with open(FILENAME_VERIFY_PROOF_TEST, "w", encoding="utf-8") as fil_verify_proof:
+ gen_all_verify_proof_vectors(fil_verify_proof)
diff --git a/bip-0374/reference.py b/bip-0374/reference.py
new file mode 100755
index 0000000000..51354bd256
--- /dev/null
+++ b/bip-0374/reference.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python3
+
+"""Reference implementation of DLEQ BIP for secp256k1 with unit tests."""
+
+from hashlib import sha256
+import random
+from secp256k1 import G, GE
+import sys
+import unittest
+
+
+DLEQ_TAG_AUX = "BIP0374/aux"
+DLEQ_TAG_NONCE = "BIP0374/nonce"
+DLEQ_TAG_CHALLENGE = "BIP0374/challenge"
+
+
+def TaggedHash(tag: str, data: bytes) -> bytes:
+ ss = sha256(tag.encode()).digest()
+ ss += ss
+ ss += data
+ return sha256(ss).digest()
+
+
+def xor_bytes(lhs: bytes, rhs: bytes) -> bytes:
+ assert len(lhs) == len(rhs)
+ return bytes([lhs[i] ^ rhs[i] for i in range(len(lhs))])
+
+
+def dleq_challenge(
+ A: GE, B: GE, C: GE, R1: GE, R2: GE, m: bytes | None, G: GE,
+) -> int:
+ if m is not None:
+ assert len(m) == 32
+ m = bytes([]) if m is None else m
+ return int.from_bytes(
+ TaggedHash(
+ DLEQ_TAG_CHALLENGE,
+ A.to_bytes_compressed()
+ + B.to_bytes_compressed()
+ + C.to_bytes_compressed()
+ + G.to_bytes_compressed()
+ + R1.to_bytes_compressed()
+ + R2.to_bytes_compressed()
+ + m,
+ ),
+ "big",
+ )
+
+
+def dleq_generate_proof(
+ a: int, B: GE, r: bytes, G: GE = G, m: bytes | None = None
+) -> bytes | None:
+ assert len(r) == 32
+ if not (0 < a < GE.ORDER):
+ return None
+ if B.infinity:
+ return None
+ if m is not None:
+ assert len(m) == 32
+ A = a * G
+ C = a * B
+ t = xor_bytes(a.to_bytes(32, "big"), TaggedHash(DLEQ_TAG_AUX, r))
+ m_prime = bytes([]) if m is None else m
+ rand = TaggedHash(
+ DLEQ_TAG_NONCE, t + A.to_bytes_compressed() + C.to_bytes_compressed() + m_prime
+ )
+ k = int.from_bytes(rand, "big") % GE.ORDER
+ if k == 0:
+ return None
+ R1 = k * G
+ R2 = k * B
+ e = dleq_challenge(A, B, C, R1, R2, m, G)
+ s = (k + e * a) % GE.ORDER
+ proof = e.to_bytes(32, "big") + s.to_bytes(32, "big")
+ if not dleq_verify_proof(A, B, C, proof, G=G, m=m):
+ return None
+ return proof
+
+
+def dleq_verify_proof(
+ A: GE, B: GE, C: GE, proof: bytes, G: GE = G, m: bytes | None = None
+) -> bool:
+ if A.infinity or B.infinity or C.infinity or G.infinity:
+ return False
+ assert len(proof) == 64
+ e = int.from_bytes(proof[:32], "big")
+ s = int.from_bytes(proof[32:], "big")
+ if s >= GE.ORDER:
+ return False
+ R1 = s * G - e * A
+ if R1.infinity:
+ return False
+ R2 = s * B - e * C
+ if R2.infinity:
+ return False
+ if e != dleq_challenge(A, B, C, R1, R2, m, G):
+ return False
+ return True
+
+
+class DLEQTests(unittest.TestCase):
+ def test_dleq(self):
+ seed = random.randrange(sys.maxsize)
+ random.seed(seed)
+ print(f"PRNG seed is: {seed}")
+ for _ in range(10):
+ # generate random keypairs for both parties
+ a = random.randrange(1, GE.ORDER)
+ A = a * G
+ b = random.randrange(1, GE.ORDER)
+ B = b * G
+
+ # create shared secret
+ C = a * B
+
+ # create dleq proof
+ rand_aux = random.randbytes(32)
+ proof = dleq_generate_proof(a, B, rand_aux)
+ self.assertTrue(proof is not None)
+ # verify dleq proof
+ success = dleq_verify_proof(A, B, C, proof)
+ self.assertTrue(success)
+
+ # flip a random bit in the dleq proof and check that verification fails
+ for _ in range(5):
+ proof_damaged = list(proof)
+ proof_damaged[random.randrange(len(proof))] ^= 1 << (
+ random.randrange(8)
+ )
+ success = dleq_verify_proof(A, B, C, bytes(proof_damaged))
+ self.assertFalse(success)
+
+ # create the same dleq proof with a message
+ message = random.randbytes(32)
+ proof = dleq_generate_proof(a, B, rand_aux, m=message)
+ self.assertTrue(proof is not None)
+ # verify dleq proof with a message
+ success = dleq_verify_proof(A, B, C, proof, m=message)
+ self.assertTrue(success)
+
+ # flip a random bit in the dleq proof and check that verification fails
+ for _ in range(5):
+ proof_damaged = list(proof)
+ proof_damaged[random.randrange(len(proof))] ^= 1 << (
+ random.randrange(8)
+ )
+ success = dleq_verify_proof(A, B, C, bytes(proof_damaged))
+ self.assertFalse(success)
diff --git a/bip-0374/run_test_vectors.py b/bip-0374/run_test_vectors.py
new file mode 100755
index 0000000000..53e5e2dc46
--- /dev/null
+++ b/bip-0374/run_test_vectors.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+"""Run the BIP-DLEQ test vectors."""
+import csv
+import os
+import sys
+from reference import (
+ dleq_generate_proof,
+ dleq_verify_proof,
+)
+from secp256k1 import GE
+
+
+FILENAME_GENERATE_PROOF_TEST = os.path.join(sys.path[0], 'test_vectors_generate_proof.csv')
+FILENAME_VERIFY_PROOF_TEST = os.path.join(sys.path[0], 'test_vectors_verify_proof.csv')
+
+
+all_passed = True
+print("-----------------------------------------")
+print("----- Proof generation test vectors -----")
+print("-----------------------------------------")
+with open(FILENAME_GENERATE_PROOF_TEST, newline='') as csvfile:
+ reader = csv.reader(csvfile)
+ next(reader)
+ for row in reader:
+ (index, point_G_hex, seckey_a_hex, point_B_hex, aux_rand_hex, msg_hex, result_str, comment) = row
+ print(seckey_a_hex)
+ G = GE() if point_G_hex == 'INFINITY' else GE.from_bytes(bytes.fromhex(point_G_hex))
+ a = int.from_bytes(bytes.fromhex(seckey_a_hex), 'big')
+ B = GE() if point_B_hex == 'INFINITY' else GE.from_bytes(bytes.fromhex(point_B_hex))
+ aux_rand = bytes.fromhex(aux_rand_hex)
+ msg = bytes.fromhex(msg_hex)
+ if msg == b"": msg = None
+ print('Test vector', ('#' + index).rjust(3, ' ') + ':' + f' ({comment})')
+ expected_result = None if result_str == 'INVALID' else bytes.fromhex(result_str)
+ actual_result = dleq_generate_proof(a, B, aux_rand, G=G, m=msg)
+ if expected_result == actual_result:
+ print(' * Passed proof generation test.')
+ else:
+ print(' * Failed proof generation test.')
+ print(' Expected proof: ', expected_result.hex() if expected_result is not None else 'INVALID')
+ print(' Actual proof: ', actual_result.hex() if actual_result is not None else 'INVALID')
+ all_passed = False
+ print()
+
+
+print("-------------------------------------------")
+print("----- Proof verification test vectors -----")
+print("-------------------------------------------")
+with open(FILENAME_VERIFY_PROOF_TEST, newline='') as csvfile:
+ reader = csv.reader(csvfile)
+ next(reader)
+ for row in reader:
+ (index, point_G_hex, point_A_hex, point_B_hex, point_C_hex, proof_hex, msg_hex, result_success, comment) = row
+ G = GE() if point_G_hex == 'INFINITY' else GE.from_bytes(bytes.fromhex(point_G_hex))
+ A = GE() if point_A_hex == 'INFINITY' else GE.from_bytes(bytes.fromhex(point_A_hex))
+ B = GE() if point_B_hex == 'INFINITY' else GE.from_bytes(bytes.fromhex(point_B_hex))
+ C = GE() if point_C_hex == 'INFINITY' else GE.from_bytes(bytes.fromhex(point_C_hex))
+ proof = bytes.fromhex(proof_hex)
+ msg = bytes.fromhex(msg_hex)
+ if msg == b"": msg = None
+ print('Test vector', ('#' + index).rjust(3, ' ') + ':' + f' ({comment})')
+ expected_result = result_success == 'TRUE'
+ actual_result = dleq_verify_proof(A, B, C, proof, G=G, m=msg)
+ if expected_result == actual_result:
+ print(' * Passed proof verification test.')
+ else:
+ print(' * Failed proof verification test.')
+ print(' Expected verification result: ', expected_result)
+ print(' Actual verification result: ', actual_result)
+ all_passed = False
+
+
+print()
+if all_passed:
+ print('All test vectors passed.')
+ sys.exit(0)
+else:
+ print('Some test vectors failed.')
+ sys.exit(1)
diff --git a/bip-0374/secp256k1.py b/bip-0374/secp256k1.py
new file mode 100755
index 0000000000..b83d028f92
--- /dev/null
+++ b/bip-0374/secp256k1.py
@@ -0,0 +1,360 @@
+#!/usr/bin/env python3
+
+# Copyright (c) 2022-2023 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+"""Test-only implementation of low-level secp256k1 field and group arithmetic
+
+It is designed for ease of understanding, not performance.
+
+WARNING: This code is slow and trivially vulnerable to side channel attacks. Do not use for
+anything but tests.
+
+Exports:
+* FE: class for secp256k1 field elements
+* GE: class for secp256k1 group elements
+* G: the secp256k1 generator point
+"""
+
+import unittest
+from hashlib import sha256
+
+class FE:
+ """Objects of this class represent elements of the field GF(2**256 - 2**32 - 977).
+
+ They are represented internally in numerator / denominator form, in order to delay inversions.
+ """
+
+ # The size of the field (also its modulus and characteristic).
+ SIZE = 2**256 - 2**32 - 977
+
+ def __init__(self, a=0, b=1):
+ """Initialize a field element a/b; both a and b can be ints or field elements."""
+ if isinstance(a, FE):
+ num = a._num
+ den = a._den
+ else:
+ num = a % FE.SIZE
+ den = 1
+ if isinstance(b, FE):
+ den = (den * b._num) % FE.SIZE
+ num = (num * b._den) % FE.SIZE
+ else:
+ den = (den * b) % FE.SIZE
+ assert den != 0
+ if num == 0:
+ den = 1
+ self._num = num
+ self._den = den
+
+ def __add__(self, a):
+ """Compute the sum of two field elements (second may be int)."""
+ if isinstance(a, FE):
+ return FE(self._num * a._den + self._den * a._num, self._den * a._den)
+ return FE(self._num + self._den * a, self._den)
+
+ def __radd__(self, a):
+ """Compute the sum of an integer and a field element."""
+ return FE(a) + self
+
+ def __sub__(self, a):
+ """Compute the difference of two field elements (second may be int)."""
+ if isinstance(a, FE):
+ return FE(self._num * a._den - self._den * a._num, self._den * a._den)
+ return FE(self._num - self._den * a, self._den)
+
+ def __rsub__(self, a):
+ """Compute the difference of an integer and a field element."""
+ return FE(a) - self
+
+ def __mul__(self, a):
+ """Compute the product of two field elements (second may be int)."""
+ if isinstance(a, FE):
+ return FE(self._num * a._num, self._den * a._den)
+ return FE(self._num * a, self._den)
+
+ def __rmul__(self, a):
+ """Compute the product of an integer with a field element."""
+ return FE(a) * self
+
+ def __truediv__(self, a):
+ """Compute the ratio of two field elements (second may be int)."""
+ return FE(self, a)
+
+ def __pow__(self, a):
+ """Raise a field element to an integer power."""
+ return FE(pow(self._num, a, FE.SIZE), pow(self._den, a, FE.SIZE))
+
+ def __neg__(self):
+ """Negate a field element."""
+ return FE(-self._num, self._den)
+
+ def __int__(self):
+ """Convert a field element to an integer in range 0..p-1. The result is cached."""
+ if self._den != 1:
+ self._num = (self._num * pow(self._den, -1, FE.SIZE)) % FE.SIZE
+ self._den = 1
+ return self._num
+
+ def sqrt(self):
+ """Compute the square root of a field element if it exists (None otherwise).
+
+ Due to the fact that our modulus is of the form (p % 4) == 3, the Tonelli-Shanks
+ algorithm (https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm) is simply
+ raising the argument to the power (p + 1) / 4.
+
+ To see why: (p-1) % 2 = 0, so 2 divides the order of the multiplicative group,
+ and thus only half of the non-zero field elements are squares. An element a is
+ a (nonzero) square when Euler's criterion, a^((p-1)/2) = 1 (mod p), holds. We're
+ looking for x such that x^2 = a (mod p). Given a^((p-1)/2) = 1, that is equivalent
+ to x^2 = a^(1 + (p-1)/2) mod p. As (1 + (p-1)/2) is even, this is equivalent to
+ x = a^((1 + (p-1)/2)/2) mod p, or x = a^((p+1)/4) mod p."""
+ v = int(self)
+ s = pow(v, (FE.SIZE + 1) // 4, FE.SIZE)
+ if s**2 % FE.SIZE == v:
+ return FE(s)
+ return None
+
+ def is_square(self):
+ """Determine if this field element has a square root."""
+ # A more efficient algorithm is possible here (Jacobi symbol).
+ return self.sqrt() is not None
+
+ def is_even(self):
+ """Determine whether this field element, represented as integer in 0..p-1, is even."""
+ return int(self) & 1 == 0
+
+ def __eq__(self, a):
+ """Check whether two field elements are equal (second may be an int)."""
+ if isinstance(a, FE):
+ return (self._num * a._den - self._den * a._num) % FE.SIZE == 0
+ return (self._num - self._den * a) % FE.SIZE == 0
+
+ def to_bytes(self):
+ """Convert a field element to a 32-byte array (BE byte order)."""
+ return int(self).to_bytes(32, 'big')
+
+ @staticmethod
+ def from_bytes(b):
+ """Convert a 32-byte array to a field element (BE byte order, no overflow allowed)."""
+ v = int.from_bytes(b, 'big')
+ if v >= FE.SIZE:
+ return None
+ return FE(v)
+
+ def __str__(self):
+ """Convert this field element to a 64 character hex string."""
+ return f"{int(self):064x}"
+
+ def __repr__(self):
+ """Get a string representation of this field element."""
+ return f"FE(0x{int(self):x})"
+
+
+class GE:
+ """Objects of this class represent secp256k1 group elements (curve points or infinity)
+
+ Normal points on the curve have fields:
+ * x: the x coordinate (a field element)
+ * y: the y coordinate (a field element, satisfying y^2 = x^3 + 7)
+ * infinity: False
+
+ The point at infinity has field:
+ * infinity: True
+ """
+
+ # Order of the group (number of points on the curve, plus 1 for infinity)
+ ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
+
+ # Number of valid distinct x coordinates on the curve.
+ ORDER_HALF = ORDER // 2
+
+ def __init__(self, x=None, y=None):
+ """Initialize a group element with specified x and y coordinates, or infinity."""
+ if x is None:
+ # Initialize as infinity.
+ assert y is None
+ self.infinity = True
+ else:
+ # Initialize as point on the curve (and check that it is).
+ fx = FE(x)
+ fy = FE(y)
+ assert fy**2 == fx**3 + 7
+ self.infinity = False
+ self.x = fx
+ self.y = fy
+
+ def __add__(self, a):
+ """Add two group elements together."""
+ # Deal with infinity: a + infinity == infinity + a == a.
+ if self.infinity:
+ return a
+ if a.infinity:
+ return self
+ if self.x == a.x:
+ if self.y != a.y:
+ # A point added to its own negation is infinity.
+ assert self.y + a.y == 0
+ return GE()
+ else:
+ # For identical inputs, use the tangent (doubling formula).
+ lam = (3 * self.x**2) / (2 * self.y)
+ else:
+ # For distinct inputs, use the line through both points (adding formula).
+ lam = (self.y - a.y) / (self.x - a.x)
+ # Determine point opposite to the intersection of that line with the curve.
+ x = lam**2 - (self.x + a.x)
+ y = lam * (self.x - x) - self.y
+ return GE(x, y)
+
+ @staticmethod
+ def mul(*aps):
+ """Compute a (batch) scalar group element multiplication.
+
+ GE.mul((a1, p1), (a2, p2), (a3, p3)) is identical to a1*p1 + a2*p2 + a3*p3,
+ but more efficient."""
+ # Reduce all the scalars modulo order first (so we can deal with negatives etc).
+ naps = [(a % GE.ORDER, p) for a, p in aps]
+ # Start with point at infinity.
+ r = GE()
+ # Iterate over all bit positions, from high to low.
+ for i in range(255, -1, -1):
+ # Double what we have so far.
+ r = r + r
+ # Add then add the points for which the corresponding scalar bit is set.
+ for (a, p) in naps:
+ if (a >> i) & 1:
+ r += p
+ return r
+
+ def __rmul__(self, a):
+ """Multiply an integer with a group element."""
+ if self == G:
+ return FAST_G.mul(a)
+ return GE.mul((a, self))
+
+ def __neg__(self):
+ """Compute the negation of a group element."""
+ if self.infinity:
+ return self
+ return GE(self.x, -self.y)
+
+ def __sub__(self, a):
+ """Subtract a group element from another."""
+ return self + (-a)
+
+ def to_bytes_compressed(self):
+ """Convert a non-infinite group element to 33-byte compressed encoding."""
+ assert not self.infinity
+ return bytes([3 - self.y.is_even()]) + self.x.to_bytes()
+
+ def to_bytes_uncompressed(self):
+ """Convert a non-infinite group element to 65-byte uncompressed encoding."""
+ assert not self.infinity
+ return b'\x04' + self.x.to_bytes() + self.y.to_bytes()
+
+ def to_bytes_xonly(self):
+ """Convert (the x coordinate of) a non-infinite group element to 32-byte xonly encoding."""
+ assert not self.infinity
+ return self.x.to_bytes()
+
+ @staticmethod
+ def lift_x(x):
+ """Return group element with specified field element as x coordinate (and even y)."""
+ y = (FE(x)**3 + 7).sqrt()
+ if y is None:
+ return None
+ if not y.is_even():
+ y = -y
+ return GE(x, y)
+
+ @staticmethod
+ def from_bytes(b):
+ """Convert a compressed or uncompressed encoding to a group element."""
+ assert len(b) in (33, 65)
+ if len(b) == 33:
+ if b[0] != 2 and b[0] != 3:
+ return None
+ x = FE.from_bytes(b[1:])
+ if x is None:
+ return None
+ r = GE.lift_x(x)
+ if r is None:
+ return None
+ if b[0] == 3:
+ r = -r
+ return r
+ else:
+ if b[0] != 4:
+ return None
+ x = FE.from_bytes(b[1:33])
+ y = FE.from_bytes(b[33:])
+ if y**2 != x**3 + 7:
+ return None
+ return GE(x, y)
+
+ @staticmethod
+ def from_bytes_xonly(b):
+ """Convert a point given in xonly encoding to a group element."""
+ assert len(b) == 32
+ x = FE.from_bytes(b)
+ if x is None:
+ return None
+ return GE.lift_x(x)
+
+ @staticmethod
+ def is_valid_x(x):
+ """Determine whether the provided field element is a valid X coordinate."""
+ return (FE(x)**3 + 7).is_square()
+
+ def __str__(self):
+ """Convert this group element to a string."""
+ if self.infinity:
+ return "(inf)"
+ return f"({self.x},{self.y})"
+
+ def __repr__(self):
+ """Get a string representation for this group element."""
+ if self.infinity:
+ return "GE()"
+ return f"GE(0x{int(self.x):x},0x{int(self.y):x})"
+
+# The secp256k1 generator point
+G = GE.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
+
+
+class FastGEMul:
+ """Table for fast multiplication with a constant group element.
+
+ Speed up scalar multiplication with a fixed point P by using a precomputed lookup table with
+ its powers of 2:
+
+ table = [P, 2*P, 4*P, (2^3)*P, (2^4)*P, ..., (2^255)*P]
+
+ During multiplication, the points corresponding to each bit set in the scalar are added up,
+ i.e. on average ~128 point additions take place.
+ """
+
+ def __init__(self, p):
+ self.table = [p] # table[i] = (2^i) * p
+ for _ in range(255):
+ p = p + p
+ self.table.append(p)
+
+ def mul(self, a):
+ result = GE()
+ a = a % GE.ORDER
+ for bit in range(a.bit_length()):
+ if a & (1 << bit):
+ result += self.table[bit]
+ return result
+
+# Precomputed table with multiples of G for fast multiplication
+FAST_G = FastGEMul(G)
+
+class TestFrameworkSecp256k1(unittest.TestCase):
+ def test_H(self):
+ H = sha256(G.to_bytes_uncompressed()).digest()
+ assert GE.lift_x(FE.from_bytes(H)) is not None
+ self.assertEqual(H.hex(), "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")
diff --git a/bip-0374/test_vectors_generate_proof.csv b/bip-0374/test_vectors_generate_proof.csv
new file mode 100644
index 0000000000..f913508df1
--- /dev/null
+++ b/bip-0374/test_vectors_generate_proof.csv
@@ -0,0 +1,12 @@
+index,point_G,scalar_a,point_B,auxrand_r,message,result_proof,comment
+0,02cef38f55e78b321a1f785cb1c6e33dfcef9784c18bdc4e279801c449ccdfb88e,07ff93d43f1012a5d4a44aba55240212ed39c87b3344e46757d99f24177fc576,02dad4b35c2379ba8334c9a5dda8f6e6d5cd575a7cc9d3ca4faaac51839daaa30f,cb979b0fc8ccc7f237751e719d992fcc324b6500af33999cd54a3e5c05fb1ea4,efb07d4b382d3da1079fbf24df623ba6c2e4c764993bbfa6dd7a4fe4aaf33859,7e7e934169e0bf4706e6b29e5a621c7fe199a524744a25af80071e111c0e2e94118e730d8add118dd2ee4f7d1cc183e1b87168362d1a6f85c16d8671a3fc7a8a,Success case 1
+1,02464e351831efedb755223cabbf664f10564b4742c725c023034bc928ed339e0e,f4e9172285393c6ada994c811b3e50fc47e96421ea7e54f4a4e459528d4cf562,03fe589b0fa23f060f6d4d1e76b9b19d5bb3db0e56d39a4303913de0e706463008,75f12482b9209dae12230ea1f8bf69723a1b447d361db8f510dd9ab33556fd4c,76184ce9eea5b339ebf5304b57452c1ada1466610f0a58574d6c496798cee04b,6b4521a8363a7ebc5d95ac6ec6b64db81fcf21795187d7c4600c42b73fb4fb9870ab8d106c0fd2d292c1710e10437b20575ddb3cb32eb77a5618d94ddba600f2,Success case 2
+2,0222db2054fef98344352a13bc0304a71da7b5e9a2f7fd1f3c9f3519a3d9377fb7,589476913e763b60d5c2a5bfb39230ec669caac1b44312e9bcd2d3f4473abfef,03bc7a19970c812118f74ba659b491e00dade6096ff62d1afe032a92b8671498ed,4da1c4c4b0f9db4eb6b2e5cb648d7e8a0aa35aa5c4ec4d07f096e0e03deca366,66503623468a78cfcef47888c85e0010ecd897f441d263448bfc7a89b882ab20,12aa2aa469b3c037871a09d18ab18d3840219b1ed169f6ef9deae6d927949884a459705ae89a57522224ce3482dee00a41ba511188ae60efdeb736223eb66e7b,Success case 3
+3,03dfa65bd3711eba75fa1996a0c1d95a4419bd835304152d9aa6efa590670f2af6,24d0ed3fc189eb1b64e5dc9dd4af0f3c8c143b0c79cb5fcca0dfa08a11cc60a1,03b51081323d38fb0b75f0c1ec6755fdb79c239c327ca11269fe68ba8a878b704e,31a68d6db27f6404bbceff646ff1b26a34704a0105a36c5a845d0257cea19c9b,f2996b3766d123a949e65541baf1d89d446360d05af51bd93f0445d8c472c952,7907653d29c5722ae44510e7f2839f253450aefc833b7e0a3b38384032f847f2cf41136b2fe6a558ad125287d20c0117f2a30c4ac0c4cebbcfa1dd3a69d84200,Success case 4
+4,02b15de5a3aefcfe2473916c76e619b5800ac7250ef93a9e6e0dd1505104fc58e7,73fffa796edb72d111b5e0bbda1608f098ac98120796f971b438691e1bfb7b96,03a4692be176ff89a972de9cc407083096847b950d1cae72b947665a3d5f4c2f01,1cdfb4d7cce5e50783299896a471a44e6aa2c5e2100d6c37987c6b40503c6162,0ceb45f560f2cf6b76a139ffe2c47c5ca6d26d6a3a210e59f197413bbec040b4,02277ca5a7acfe8ae13c2db4a8f74489d0ba100ed8b082381ddb6522c4510718ab88b8dbbd785c388ade79586cf6416f3c47a79670af84abccc788a5d9f2e327,Success case 5
+5,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,c08ca8e0bb59769fc6a4e078456284e00ea34f65add988c246e1bba85824ccdc,034bccb1c570ac1f3bc42d61fe35de605b99626501ccb20297e1acbbf2d7152aa1,c8d7056abd4726eb5a0f198740af14d6c1f0c16e5d7a37eaec621b661e669ac4,,503562d36910cd2d61a4d07c8ff680265c713e63dde0dcb88e6ea3c58597bdc05b86db9af95eccc475ce2177f941c118fefed20227d4ce8ce9557cb008758de6,Success case 6
+6,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,8e641ba6bf7f64eec76005a29585a5035376375f33e331215aedfe03b8e80e7a,0231c64e3efa506fdad6aad0f6084d5f6739de7f448d7e66f9d22f842638f41d60,02a7b2e2f5a5e9b1078dbb160502a32491fe80a091e91dd92cf77b0b7d90970f,35841ca532846e1cdd23a3d107824343584f88eff580929469865eae8355ee3c,5c7b27a33210750e9de8679d9f43497cf9f12ac642cde0a1fc26443aa2fc89bf71aabf7bac89f5d8a96cbe86daba155fa74d6f3e111136179e53b04eb6d7807f,Success case 7
+7,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,cfb9a7ecc49bea4f2e2ee34c38a6f48b5cd5bd06f4e4d4ffb45905b3d26db842,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,d38466b77484154a3fcb3151094c1c8a845c73a3c036b3a8ebffd8ef62c9047f,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,Success case 8
+8,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,0000000000000000000000000000000000000000000000000000000000000000,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,d38466b77484154a3fcb3151094c1c8a845c73a3c036b3a8ebffd8ef62c9047f,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,INVALID,Failure case (a=0)
+9,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,d38466b77484154a3fcb3151094c1c8a845c73a3c036b3a8ebffd8ef62c9047f,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,INVALID,Failure case (a=N [group order])
+10,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,cfb9a7ecc49bea4f2e2ee34c38a6f48b5cd5bd06f4e4d4ffb45905b3d26db842,INFINITY,d38466b77484154a3fcb3151094c1c8a845c73a3c036b3a8ebffd8ef62c9047f,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,INVALID,Failure case (B is point at infinity)
diff --git a/bip-0374/test_vectors_verify_proof.csv b/bip-0374/test_vectors_verify_proof.csv
new file mode 100644
index 0000000000..8076e8136f
--- /dev/null
+++ b/bip-0374/test_vectors_verify_proof.csv
@@ -0,0 +1,16 @@
+index,point_G,point_A,point_B,point_C,proof,message,result_success,comment
+0,02cef38f55e78b321a1f785cb1c6e33dfcef9784c18bdc4e279801c449ccdfb88e,02b540b22c2c5ef0dc886abdaad27498453d893265560bc08a187319af6f845f58,02dad4b35c2379ba8334c9a5dda8f6e6d5cd575a7cc9d3ca4faaac51839daaa30f,03fefe00951dcd0ef10b12523393c2b8113119de4fdeeab320694e96bdccd2775b,7e7e934169e0bf4706e6b29e5a621c7fe199a524744a25af80071e111c0e2e94118e730d8add118dd2ee4f7d1cc183e1b87168362d1a6f85c16d8671a3fc7a8a,efb07d4b382d3da1079fbf24df623ba6c2e4c764993bbfa6dd7a4fe4aaf33859,TRUE,Success case 1
+1,02464e351831efedb755223cabbf664f10564b4742c725c023034bc928ed339e0e,032baaf1b10845a51b551196984a91efe2adf9d41b92bec3927218e6e4ca344002,03fe589b0fa23f060f6d4d1e76b9b19d5bb3db0e56d39a4303913de0e706463008,031f59aa1df22190e00380d8c5941adf899f596593765a1251005fd24f2bf7c884,6b4521a8363a7ebc5d95ac6ec6b64db81fcf21795187d7c4600c42b73fb4fb9870ab8d106c0fd2d292c1710e10437b20575ddb3cb32eb77a5618d94ddba600f2,76184ce9eea5b339ebf5304b57452c1ada1466610f0a58574d6c496798cee04b,TRUE,Success case 2
+2,0222db2054fef98344352a13bc0304a71da7b5e9a2f7fd1f3c9f3519a3d9377fb7,026aa26fcd626f8f55295859e9f8dd1f103149dd64d77c2bbba1bcf33bb37ebaa2,03bc7a19970c812118f74ba659b491e00dade6096ff62d1afe032a92b8671498ed,035628d1a69910daef614c7cae68d71ece55c5908af2360629e25c1b7de21eeb4b,12aa2aa469b3c037871a09d18ab18d3840219b1ed169f6ef9deae6d927949884a459705ae89a57522224ce3482dee00a41ba511188ae60efdeb736223eb66e7b,66503623468a78cfcef47888c85e0010ecd897f441d263448bfc7a89b882ab20,TRUE,Success case 3
+3,03dfa65bd3711eba75fa1996a0c1d95a4419bd835304152d9aa6efa590670f2af6,031bf61ba89009ee1266c9003a72e8e07d77877678ccda7f15325aadcd64ed186b,03b51081323d38fb0b75f0c1ec6755fdb79c239c327ca11269fe68ba8a878b704e,02d1b1f37a80217ba73785babfa63251052775f9d3ca65060054033288b7a3f66b,7907653d29c5722ae44510e7f2839f253450aefc833b7e0a3b38384032f847f2cf41136b2fe6a558ad125287d20c0117f2a30c4ac0c4cebbcfa1dd3a69d84200,f2996b3766d123a949e65541baf1d89d446360d05af51bd93f0445d8c472c952,TRUE,Success case 4
+4,02b15de5a3aefcfe2473916c76e619b5800ac7250ef93a9e6e0dd1505104fc58e7,0296c8e00dda60bb5565b77371ff913091978646b58ccf218bc591f68a75232e6e,03a4692be176ff89a972de9cc407083096847b950d1cae72b947665a3d5f4c2f01,03a7a7f9527fd387c2b2ce0c76669d646c78a3b470a4b34d3a2dabafc8505ef472,02277ca5a7acfe8ae13c2db4a8f74489d0ba100ed8b082381ddb6522c4510718ab88b8dbbd785c388ade79586cf6416f3c47a79670af84abccc788a5d9f2e327,0ceb45f560f2cf6b76a139ffe2c47c5ca6d26d6a3a210e59f197413bbec040b4,TRUE,Success case 5
+5,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,02637b2c3ea8ca80b9caecc50f4134c86ae9cf7a269133e7afc71f30e3a3cda60c,034bccb1c570ac1f3bc42d61fe35de605b99626501ccb20297e1acbbf2d7152aa1,0285b826c8dd175805901906b6c9b4140a30cbcc94c6e7dcf36476038bf90d4718,503562d36910cd2d61a4d07c8ff680265c713e63dde0dcb88e6ea3c58597bdc05b86db9af95eccc475ce2177f941c118fefed20227d4ce8ce9557cb008758de6,,TRUE,Success case 6
+6,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,02983a72b4cb44d4322641a7b2001900cd6ae0908a610546c73ed126accdba0514,0231c64e3efa506fdad6aad0f6084d5f6739de7f448d7e66f9d22f842638f41d60,03af1bc14b384eda28398df6a7900e567c5b6f6613cafce5027b98be015286f71b,5c7b27a33210750e9de8679d9f43497cf9f12ac642cde0a1fc26443aa2fc89bf71aabf7bac89f5d8a96cbe86daba155fa74d6f3e111136179e53b04eb6d7807f,35841ca532846e1cdd23a3d107824343584f88eff580929469865eae8355ee3c,TRUE,Success case 7
+7,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,TRUE,Success case 8
+8,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 1
+9,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 2
+10,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 3
+11,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 4
+12,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 5
+13,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,78a5544afa75bf152653fe55fb76926f2f65131ff090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Tampered proof (random bit-flip)
+14,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb6d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Tampered message (random bit-flip)
diff --git a/bip-0375.mediawiki b/bip-0375.mediawiki
new file mode 100644
index 0000000000..879c932b93
--- /dev/null
+++ b/bip-0375.mediawiki
@@ -0,0 +1,261 @@
+
+
+==Introduction==
+
+===Abstract===
+
+This document proposes additional fields and updated role responsibilities for BIP370 PSBTv2
+which adds support for sending to silent payments as described in BIP352.
+
+===Copyright===
+
+This BIP is licensed under the 2-clause BSD license.
+
+===Motivation===
+
+Partially Signed Bitcoin Transaction Version 2 as described in BIP370 is not compatible with sending to silent payments as described in BIP352.
+In particular, the output script of a silent payment cannot be computed until after all transaction inputs have been added.
+Additionally, the silent payment outputs computed by a signer must be verifiable by other entities, otherwise funds could be sent to an incorrect output script.
+Therefore, new fields and role responsibilities must be added to carry, compute, and verify the silent payment data.
+
+==Specification==
+
+This document specifies new fields and new field inclusion/exclusion requirements.
+
+The new global types are defined as follows:
+
+{|
+! Name
+!
+!
+! Description
+!
+! Description
+! Versions Requiring Inclusion
+! Versions Requiring Exclusion
+! Versions Allowing Inclusion
+|-
+| Silent Payment Global ECDH Share
+| PSBT_GLOBAL_SP_ECDH_SHARE = 0x07
+| <33 byte scan key>
+| The scan key that this ECDH share is for.
+| <33 byte share>
+| An ECDH share for a scan key. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the sum of all private keys of all eligible inputs, and ''B_scan'' is the scan key of a recipient.
+|
+| 0
+| 2
+|-
+| Silent Payment Global DLEQ Proof
+| PSBT_GLOBAL_SP_DLEQ = 0x08
+| <33 byte scan key>
+| The scan key that this proof covers.
+| <64-byte proof>
+| A BIP374 DLEQ proof computed for the matching ECDH share.
+|
+| 0
+| 2
+|}
+
+The new per-input types are defined as follows:
+
+{|
+! Name
+!
+!
+! Description
+!
+! Description
+! Versions Requiring Inclusion
+! Versions Requiring Exclusion
+! Versions Allowing Inclusion
+|-
+| Silent Payment Input ECDH Share
+| PSBT_IN_SP_ECDH_SHARE = 0x1d
+| <33 byte scan key>
+| The scan key that this ECDH share is for.
+| <33 byte share>
+| An ECDH share for a scan key. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the private key of the corresponding prevout public key, and ''B_scan'' is the scan key of a recipient.
+|
+| 0
+| 2
+|-
+| Silent Payment Input DLEQ Proof
+| PSBT_IN_SP_DLEQ = 0x1e
+| <33 byte scan key>
+| The scan key that this proof covers.
+| <64-byte proof>
+| A BIP374 DLEQ proof computed for the matching ECDH share.
+|
+| 0
+| 2
+|}
+
+The new per-output types are defined as follows:
+
+{|
+! Name
+!
+!
+! Description
+!
+! Description
+! Versions Requiring Inclusion
+! Versions Requiring Exclusion
+! Versions Allowing Inclusion
+|-
+| Silent Payment Data
+| PSBT_OUT_SP_V0_INFO = 0x09
+| None
+| No key data
+| <33 byte scan key> <33 byte spend key>
+| The scan and spend public keys from the silent payments address.
+|
+| 0
+| 2
+|-
+| Silent Payment Label
+| PSBT_OUT_SP_V0_LABEL = 0x0a
+| None
+| No key data
+| <32-bit little endian uint label>
+| The label to use to compute the spend key of the silent payments address to verify change.
+|
+| 0
+| 2
+|}
+
+PSBT_OUT_SCRIPT is modified to be optional for outputs in silent payments capable PSBTs. If this field is not included in the output, then the field PSBT_OUT_SP_V0_INFO must be included.
+If a PSBT_OUT_SCRIPT is not present for an output, then that output is being sent to a silent payment address represented by PSBT_OUT_SP_V0_INFO but the script has not yet been computed.
+If both PSBT_OUT_SCRIPT and PSBT_OUT_SP_V0_INFO are present for an output, then the PSBT_OUT_SCRIPT is the computed output script corresponding to the silent payment address in PSBT_OUT_SP_V0_INFO.
+If only PSBT_OUT_SCRIPT is present for an output, then the output is not being sent to a silent payment address.
+
+===Unique Identification===
+
+Silent payment capable PSBTs can be uniquely identified the same way as PSBTv2s, except when including silent payment outputs. If an output contains the PSBT_OUT_SP_V0_INFO field, it must use that field instead of PSBT_OUT_SCRIPT as the output script when creating the unsigned transaction used for unique identification. ''' Why use PSBT_OUT_SP_V0_INFO when serializing for a unique identifier?''' Since the same silent payment capable PSBT is valid whether or not a PSBT_OUT_SCRIPT is included in an output that has PSBT_OUT_SP_V0_INFO set, using the PSBT_OUT_SCRIPT if present for the unique identifier will cause malleability. The identifier will be different depending on whether PSBT_OUT_SCRIPT is present, so always using PSBT_OUT_SP_V0_INFO if it exists makes sure the PSBT is always identified uniquely.
+The PSBT_OUT_SP_V0_INFO should be serialized as a zero byte for the version, followed by the 33 bytes of the scan key and then 33 bytes for the spend key.
+
+
+==Roles==
+
+This document modifies some existing roles.
+
+===Constructor===
+
+All rules must be followed from PSBTv2 for this role, with the following exception:
+When an output is added, it must have either PSBT_OUT_SCRIPT or PSBT_OUT_SP_V0_INFO, or both, set.
+
+Additionally to PSBTv2, the Constructor must also follow additional rules:
+
+Inputs spending an output with script using Segwit version > 1 may only be added if there are no outputs with PSBT_OUT_SP_V0_INFO set.
+Outputs with PSBT_OUT_SP_V0_INFO set may only be added if there are no inputs spending an output script using Segwit version > 1.
+
+===Updater===
+
+The updater should add a PSBT_IN_BIP32_DERIVATION for any p2wpkh, p2sh-p2wpkh, or p2pkh input so the public key is available for creating the ecdh_shared_secret when the private key is not known. If the updater does not want to reveal the fingerprint or derivation path, it can set the value of the field to zero.
+
+====Change Detection====
+
+Updaters may add two PSBT_OUT_BIP32_DERIVATION key-value-pairs with the corresponding derivation path of both the scan and spend keys. A label can be specified in PSBT_OUT_SP_V0_LABEL. The Signer can then use these fields to verify that the silent payment code is change.
+
+===Signer===
+
+All rules must be followed from PSBTv2 for this role. If there are any outputs with PSBT_OUT_SP_V0_INFO set, then the following additional rules must also be adhered to:
+
+If any input is spending an output with script using Segwit version > 1, the Signer must fail.
+
+For each output with PSBT_OUT_SP_V0_INFO set, the Signer should:
+* Compute and set an ECDH share and DLEQ proof for each input it has the private key for, or set a global ECDH share and DLEQ proof if it has private keys for all eligible inputs.
+* Verify the DLEQ proofs for all inputs it does not have the private keys for, or the global DLEQ proof if it is set.
+* If all eligible inputs have an ECDH share or the global ECDH share is set, compute and set the PSBT_OUT_SCRIPT.
+
+If the Signer sets any missing PSBT_OUT_SCRIPTs, it must set the Inputs Modifiable and Outputs Modifiable flags to False.
+
+If any output does not have PSBT_OUT_SCRIPT set, the Signer must not yet add a signature.
+
+The Signer should additionally compute the silent payment addresses, optionally showing this data to the user instead of the computed segwit v1 addresses.
+
+If a sighash type is provided and there are silent payment outputs present, the signer must fail if the sighash type is not SIGHASH_ALL.
+If a sighash type is not provided and there are silent payment outputs present, the signer must sign using SIGHASH_ALL. ''' Why use only SIGHASH_ALL?''' BIP352 allows signing with SIGHASH_NONE and SIGHASH_SINGLE. However, silent payment capable PSBTs compute the output scripts deterministically based on the number and position of silent payment codes with the same scan key. SIGHASH_NONE and SIGHASH_SINGLE allow changing the amount or position of silent payment codes with the same scan and spend keys, which would invalidate computed output scripts.
+
+====Computing the ECDH Shares and DLEQ Proofs====
+
+For each output with PSBT_OUT_SP_V0_INFO set, the Signer may generate a proof for other entities to generate the output scripts and verify that the output scripts were generated correctly.
+
+If the Signer has the private keys for all eligible inputs, the Signer should generate a global ECDH share for each scan key ''Bscan'' as follows:
+
+Using the notation from [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#specification BIP352]
+
+* Let ''an'' be the sum of the private keys ''a'' of all eligible inputs
+* Let ''C = an·Bscan''
+
+Set the key as ''Bscan'' and the value as ''C'' for the PSBT_GLOBAL_SP_ECDH_SHARE field.
+
+Compute the DLEQ proof for ''C'' using [https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki#user-content-DLEQ_Proof_Generation BIP374 GenerateProof] and passing ''an'' as ''a'' and ''Bscan'' as ''B''.
+Set the key as ''Bscan'' and the value as the proof for the PSBT_GLOBAL_SP_DLEQ field.
+
+If the Signer has the private keys for some eligible inputs or does not want to create a global ECDH share, the Signer should generate a per-input ECDH share for each scan key ''Bscan'' as follows:
+
+Using the notation from [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#specification BIP352], for each eligible input:
+
+* Let ''a'' be the private key of the input
+* Let ''C = a·Bscan''
+
+Set the key as ''Bscan'' and the value as ''C'' for the PSBT_IN_SP_ECDH_SHARE field of the input.
+
+Compute the DLEQ proof for ''C'' using [https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki#user-content-DLEQ_Proof_Generation BIP374 GenerateProof] and passing ''Bscan'' as ''B''.
+Set the key as ''Bscan'' and the value as the proof for the PSBT_IN_SP_DLEQ field of the input.
+
+====Verifying the DLEQ Proof====
+
+For each output with PSBT_OUT_SP_V0_INFO set, the Signer should verify the ECDH shares for all eligible inputs it does not have the private key for using the proofs provided by other Signers.
+
+If PSBT_GLOBAL_SP_ECDH_SHARE and PSBT_GLOBAL_SP_DLEQ are set, verify as follows:
+
+* Let ''An'' be the sum of the public keys ''A'' of all eligible inputs
+
+Using [https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki#dleq-proof-verification BIP374 VerifyProof] and passing ''A'' as ''An'', ''B'' as ''Bscan'', ''C'' as the value of PSBT_GLOBAL_SP_ECDH_SHARE, and ''proof'' as the value of PSBT_GLOBAL_SP_DLEQ.
+
+If PSBT_IN_SP_ECDH_SHARE and PSBT_IN_SP_DLEQ are set for a particular input, verify as follows:
+
+Using [https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki#dleq-proof-verification BIP374 VerifyProof] and passing ''A'' as the public key of the input, ''B'' as ''Bscan'', ''C'' as the value of PSBT_IN_SP_ECDH_SHARE, and ''proof'' as the value of PSBT_IN_SP_DLEQ.
+
+
+====Computing the Output Scripts====
+
+Compute the PSBT_OUT_SCRIPT using the procedure in [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#user-content-Creating_outputs BIP352] but substituting ''a·Bscan'' with the PSBT_GLOBAL_SP_ECDH_SHARE for that scan key if available, or the sum of all PSBT_IN_SP_ECDH_SHAREs for that scan key.
+If there are multiple silent payment codes with the same scan key, sort the codes lexicographically in ascending order to determine the ordering of the ''k'' value.
+If there are multiple silent payment codes with both the same scan and spend keys, sort the subgroup by output index in ascending order.
+
+===Transaction Extractor===
+
+For silent payment capable PSBTs, the transaction extractor should compute all output scripts for silent payment codes and verify they are correct using the ECDH shares and DLEQ proofs, otherwise fail.
+
+==Backwards Compatibility==
+
+Silent payment capable PSBTs are backwards compatible with PSBTv2 once all outputs have PSBT_OUT_SCRIPT set. Otherwise they are not backwards compatible.
+
+==Test Vectors==
+
+Todo
+
+==Rationale==
+
+
+
+==Reference implementation==
+
+Todo
diff --git a/bip-0379.md b/bip-0379.md
new file mode 100644
index 0000000000..02268921cc
--- /dev/null
+++ b/bip-0379.md
@@ -0,0 +1,423 @@
+```
+ BIP: 379
+ Layer: Applications
+ Title: Miniscript
+ Author: Pieter Wuille
+ Andrew Poelstra
+ Sanket Kanjalkar
+ Antoine Poinsot
+ Ava Chow
+ Comments-Summary: No comments yet.
+ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0379
+ Status: Draft
+ Type: Informational
+ Created: 2023-10-10
+ License: CC0-1.0
+```
+
+## Abstract
+
+This document specifies Miniscript, a language for writing (a subset of) Bitcoin Scripts in a
+structured way, enabling analysis, composition, generic signing and more.
+
+## Copyright
+
+This document is licensed under the Creative Commons CC0 1.0 Universal license.
+
+## Motivation
+
+Bitcoin Script is an unusual stack-based language with many edge cases, designed for implementing
+spending conditions consisting of various combinations of signatures, hash locks, and time locks.
+Yet, despite being limited in functionality, it is still highly nontrivial to:
+
+* Given a combination of spending conditions, finding the most economical script to implement it.
+* Given two scripts, construct a script that implements a composition of their spending conditions (e.g. a multisig where one of the "keys" is another multisig).
+* Given a script, find out what spending conditions it permits.
+* Given a script and access to a sufficient set of private keys, construct a general satisfying witness for it.
+* Given a script, be able to predict the cost of spending an output.
+* Given a script, know whether particular resource limitations like the ops limit might be hit when spending.
+
+Miniscript functions as a representation for scripts that makes this sort of operations possible.
+It has a structure that allows composition. It is very easy to statically analyze for various
+properties (spending conditions, correctness, security properties, malleability, ...). It can be
+targeted by spending policy compilers. Finally, compatible scripts can easily be converted to
+Miniscript form - avoiding the need for additional metadata for e.g. signing devices that support
+it.
+
+## Specification
+
+These specifications apply to P2WSH ([BIP 141](bip-0141.mediawiki)) and Tapscript ([BIP 342](bip-0342.mediawiki)) scripts, with only minor
+variations between the two. Differences are noted inline. Unless explicitly stated otherwise,
+specifications apply to both. P2SH and bare scripts are excluded from this specification.
+
+### Translation Table
+
+Miniscript consists of a set of script *fragments* which are designed to be safely and correctly composable.
+
+This table shows all Miniscript *fragments* and their associated semantics and Bitcoin Script.
+Fragments that do not change the semantics of their subexpressions are called *wrappers*. Normal
+fragments use a `fragment(arg1,arg2,...)` notation, while wrappers are written using
+prefixes separated from other fragments by a colon. The colon is dropped between subsequent
+wrappers; e.g. `dv:older(144)` is the `d:` wrapper applied to the
+`v:` wrapper applied to the `older` fragment for 144 blocks.
+
+The `pk`, `pkh`, and `and_n` fragments and `t:`,
+`l:`, and `u:` wrappers are syntactic sugar for other Miniscripts, as listed
+in the table below. Note that `<20>` are in hex representation in this document.
+
+Miniscript fragments are expected to be used in [BIP 382](bip-0382.mediawiki) `wsh()` descriptors
+and [BIP 386](bip-0386.mediawiki) `tr()` descriptors. Key expressions are specified in
+[BIP 380](bip-0380.mediawiki#user-content-Key_Expressions). Additionally, BIPs 382 and 386 specify
+restrictions on key expressions and what they resolve to - these apply to key expressions in
+Miniscript. BIP 382's key expression restrictions apply to Miniscript in P2WSH contexts, and BIP
+386's key expression restrictions apply to Miniscript in P2TR contexts. From a user's perspective,
+Miniscript is not a separate language, but rather a significant expansion of the descriptor language.
+
+| Semantics | Miniscript Fragment | Bitcoin Script
+|----------------------------------------------------------|-------------------------------|---------------
+| false | `0` | `0`
+| true | `1` | `1`
+| check(key) | `pk_k(key)` | ``
+| | `pk_h(key)` | `DUP HASH160 EQUALVERIFY `
+| | `pk(key)` = `c:pk_k(key)` | ` CHECKSIG`
+| | `pkh(key)` = `c:pk_h(key)` | `DUP HASH160 EQUALVERIFY CHECKSIG`
+| nSequence ≥ n (and compatible) | `older(n)` | ` CHECKSEQUENCEVERIFY`
+| nLockTime ≥ n (and compatible) | `after(n)` | ` CHECKLOCKTIMEVERIFY`
+| len(x) = 32 and SHA256(x) = h | `sha256(h)` | `SIZE <0x20> EQUALVERIFY SHA256 EQUAL`
+| len(x) = 32 and HASH256(x) = h | `hash256(h)` | `SIZE <0x20> EQUALVERIFY HASH256 EQUAL`
+| len(x) = 32 and RIPEMD160(x) = h | `ripemd160(h)` | `SIZE <0x20> EQUALVERIFY RIPEMD160 EQUAL`
+| len(x) = 32 and HASH160(x) = h | `hash160(h)` | `SIZE <0x20> EQUALVERIFY HASH160 EQUAL`
+| (X and Y) or Z | `andor(X,Y,Z)` | `[X] NOTIF [Z] ELSE [Y] ENDIF`
+| X and Y | `and_v(X,Y)` | `[X] [Y]`
+| | `and_b(X,Y)` | `[X] [Y] BOOLAND`
+| | `and_n(X,Y)` = `andor(X,Y,0)` | `[X] NOTIF 0 ELSE [Y] ENDIF`
+| X or Z | `or_b(X,Z)` | `[X] [Z] BOOLOR`
+| | `or_c(X,Z)` | `[X] NOTIF [Z] ENDIF`
+| | `or_d(X,Z)` | `[X] IFDUP NOTIF [Z] ENDIF`
+| | `or_i(X,Z)` | `IF [X] ELSE [Z] ENDIF`
+| X_1 + ... + X_n = k | `thresh(k,X_1,...,X_n)` | `[X_1] [X_2] ADD ... [X_n] ADD ... EQUAL`
+| check(key_1) + ... + check(key_n) = k *(P2WSH only)* | `multi(k,key_1,...,key_n)` | ` ... CHECKMULTISIG`
+| check(key_1) + ... + check(key_n) = k *(Tapscript only)* | `multi_a(k,key_1,...,key_n)` | ` CHECKSIG CHECKSIGADD ... CHECKSIGADD NUMEQUAL`
+| X (identities) | `a:X` | `TOALTSTACK [X] FROMALTSTACK`
+| | `s:X` | `SWAP [X]`
+| | `c:X` | `[X] CHECKSIG`
+| | `t:X` = `and_v(X,1)` | `[X] 1`
+| | `d:X` | `DUP IF [X] ENDIF`
+| | `v:X` | `[X] VERIFY (or VERIFY version of last opcode in [X])`
+| | `j:X` | `SIZE 0NOTEQUAL IF [X] ENDIF`
+| | `n:X` | `[X] 0NOTEQUAL`
+| | `l:X` = `or_i(0,X)` | `IF 0 ELSE [X] ENDIF`
+| | `u:X` = `or_i(X,0)` | `IF [X] ELSE 0 ENDIF`
+
+### Type System
+
+Not every Miniscript expression can be composed with every other. Some return their result by
+putting true or false on the stack; others can only abort or continue. Some require subexpressions
+that consume an exactly known number of arguments, while others need a subexpression that has a
+nonzero top stack element to satisfy. To model all these properties, we define a correctness type
+system for Miniscript.
+
+#### Correctness
+
+Every miniscript expression has one of four basic types: "**B**" (base), "**V**" (verify),
+"**K**" (key) and "**W**" (wrapped). Then there are 5 type modifiers that guarantee additional
+properties: "**z**" (zero-arg), "**o**" (one-arg), "**n**" (nonzero), "**d**"
+(dissatisfiable), and "**u**" (unit).
+
+The following table lists the correctness requirements for each of the Miniscript expressions, and
+its type properties in function of those of their subexpressions.
+
+| Miniscript | Requires | Type | Properties
+|------------------------------|-------------------------------------------------------|-------------|-----------
+| `0` | | B | z; u; d
+| `1` | | B | z; u
+| `pk_k(key)` | | K | o; n; d; u
+| `pk_h(key)` | | K | n; d; u
+| `older(n)`, `after(n)` | 1 ≤ n < 231 | B | z
+| `sha256(h)` | | B | o; n; d; u
+| `ripemd160(h)` | | B | o; n; d; u
+| `hash256(h)` | | B | o; n; d; u
+| `hash160(h)` | | B | o; n; d; u
+| `andor(X,Y,Z)` | X is Bdu; Y and Z are both B, K, or V | same as Y/Z | z=zXzYzZ; o=zXoYoZ or oXzYzZ; u=uYuZ; d=dZ
+| `and_v(X,Y)` | X is V; Y is B, K, or V | same as Y | z=zXzY; o=zXoY or zYoX; n=nX or zXnY; u=uY
+| `and_b(X,Y)` | X is B; Y is W | B | z=zXzY; o=zXoY or zYoX; n=nX or zXnY; d=dXdY; u
+| `or_b(X,Z)` | X is Bd; Z is Wd | B | z=zXzZ; o=zXoZ or zZoX; d; u
+| `or_c(X,Z)` | X is Bdu; Z is V | V | z=zXzZ; o=oXzZ
+| `or_d(X,Z)` | X is Bdu; Z is B | B | z=zXzZ; o=oXzZ; d=dZ; u=uZ
+| `or_i(X,Z)` | both are B, K, or V | same as X/Z | o=zXzZ; u=uXuZ; d=dX or dZ
+| `thresh(k,X_1,...,X_n)` | 1 ≤ k ≤ n; X1 is Bdu; others are Wdu | B | z=all are z; o=all are z except one is o; d; u
+| `multi(k,key_1,...,key_n)` | 1 ≤ k ≤ n ≤ 20 | B | n; d; u
+| `multi_a(k,key_1,...,key_n)` | 1 ≤ k ≤ n | B | d; u
+| `a:X` | X is B | W | d=dX; u=uX
+| `s:X` | X is Bo | W | d=dX; u=uX
+| `c:X` | X is K | B | o=oX; n=nX; d=dX; u
+| `d:X` | X is Vz | B | o; n; d; *(Tapscript only)* u
+| `v:X` | X is B | V | z=zX; o=oX; n=nX
+| `j:X` | X is Bn | B | o=oX; n; d; u=uX
+| `n:X` | X is B | B | z=zX; o=oX; n=nX; d=dX; u
+
+#### Timelock Type Mixing
+
+There is one additional correctness property that Miniscript expressions must satisfy:
+the four timelock types (absolute time based, absolute height based, relative time based, and
+relative height based) must not be mixed in an incompatible way.
+
+Within `and` combinators and the `thresh` combinator where k >= 2, it is illegal for both absolute
+height based and time based timelocks to appear, or for both relative height based and time based
+timelocks to appear.
+
+For all other combinators, it is legal to mix timelock types. It is also always legal to
+mix absolute and relative timelocks (even if one is height based and the other is time based).
+
+#### Malleability
+
+Malleability is the ability for a third party (someone who does *not* hold a participating private
+key) to modify an existing satisfaction into another valid satisfaction. To analyze the
+malleability guarantees of a script we define three additional type properties: "**s**" (signed),
+"**f**" (forced) and "**e**" (expressive).
+
+The following table lists the malleability properties and requirement of each fragment.
+
+| Miniscript | Requires | Properties
+|------------------------------|---------------------------------------------------------------------|-----------
+| `0` | | s, e
+| `1` | | f
+| `pk_k(key)` | | s, e
+| `pk_h(key)` | | s, e
+| `older(n)` | | f
+| `after(n)` | | f
+| `sha256(h)` | |
+| `ripemd160(h)` | |
+| `hash256(h)` | |
+| `hash160(h)` | |
+| `andor(X,Y,Z)` | eX and (sX or sY or sZ) | s=sZ and (sX or sY); f=fZ and (sX or fY); e=eZ and (sX or fY)
+| `and_v(X,Y)` | | s=sX or sY; f=sX or fY
+| `and_b(X,Y)` | | s=sX or sY; f=fXfY or sXfX or sYfY; e=eXeYsXsY
+| `or_b(X,Z)` | eXeZ and (sX or sZ) | s=sXsZ; e
+| `or_c(X,Z)` | eX and (sX or sZ) | s=sXsZ; f
+| `or_d(X,Z)` | eX and (sX or sZ) | s=sXsZ; f=fZ; e=eZ
+| `or_i(X,Z)` | sX or sZ | s=sXsZ; f=fXfZ; e=eXfZ or eZfX
+| `thresh(k,X_1,...,X_n)` | all are e; at most k are non-s | s=at most k-1 are non-s; e=all are s
+| `multi(k,key_1,...,key_n)` | | s; e
+| `multi_a(k,key_1,...,key_n)` | | s; e
+| `a:X` | | s=sX; f=fX; e=eX
+| `s:X` | | s=sX; f=fX; e=eX
+| `c:X` | | s; f=fX; e=eX
+| `d:X` | | s=sX; e
+| `v:X` | | s=sX; f
+| `j:X` | | s=sX; e=fX
+| `n:X` | | s=sX; f=fX; e=eX
+
+### Satisfaction
+
+The following table shows all valid satisfactions and dissatisfactions for every Miniscript, using
+satisfactions and dissatisfactions of its subexpressions. Multiple possibilities are separated by
+semicolons. Some options are inefficient and provably unnecessary to the satisfaction algorithm
+described below, but are valid according to script rules and could be used by a malleator or other
+non-standard actor. These are called *non-canonical* options, and are listed for completeness, but
+~~[struckthrough]~~. The fragments where a satisfaction or dissatisfaction does not exist will
+contain *(none)*. The fragments where the satisfaction or dissatisfaction is to provide no data
+will contain *(empty)*.
+
+| Miniscript | Dissatisfactions (dsat) | Satisfactions (sat)
+|------------------------------|---------------------------------------------------------|--------------------
+| `0` | *(empty)* | *(none)*
+| `1` | *(none)* | *(empty)*
+| `pk_k(key)` | 0 | sig
+| `pk_h(key)` | 0 key | sig key
+| `older(n)` | *(none)* | *(empty)*
+| `after(n)` | *(none)* | *(empty)*
+| `sha256(h)` | any 32-byte vector except the preimage | preimage
+| `ripemd160(h)` | any 32-byte vector except the preimage | preimage
+| `hash256(h)` | any 32-byte vector except the preimage | preimage
+| `hash160(h)` | any 32-byte vector except the preimage | preimage
+| `andor(X,Y,Z)` | dsat(Z) dsat(X); ~~[dsat(Y) sat(X)]~~ | sat(Y) sat(X); sat(Z) dsat(X)
+| `and_v(X,Y)` | *(none)*; ~~[dsat(Y) sat(X)]~~ | sat(Y) sat(X)
+| `and_b(X,Y)` | dsat(Y) dsat(X); ~~[sat(Y) dsat(X)]; [dsat(Y) sat(X)]~~ | sat(Y) sat(X)
+| `or_b(X,Z)` | dsat(Z) dsat(X) | dsat(Z) sat(X); sat(Z) dsat(X); ~~[sat(Z) sat(X)]~~
+| `or_c(X,Z)` | *(none)* | sat(X); sat(Z) dsat(X)
+| `or_d(X,Z)` | dsat(Z) dsat(X) | sat(X); sat(Z) dsat(X)
+| `or_i(X,Z)` | dsat(X) 1; dsat(Z) 0 | sat(X) 1; sat(Z) 0
+| `thresh(k,X_1,...,X_n)` | All dsats; ~~[Sats/dsats with 1 ≤ #(sats) ≠ k]~~ | Sats/dsats with #(sats) = k
+| `multi(k,key_1,...,key_n)` | 0 0 ... 0 (k+1 times) | 0 sig ... sig
+| `multi_a(k,key_1,...,key_n)` | 0 ... 0 (n times); ~~[sig/0 with #(sig) ≠ k]~~ | sig/0 with #(sig) = k and #(sigs/0) = n
+| `a:X` | dsat(X) | sat(X)
+| `s:X` | dsat(X) | sat(X)
+| `c:X` | dsat(X) | sat(X)
+| `d:X` | 0 | sat(X) 1
+| `v:X` | *(none)* | sat(X)
+| `j:X` | 0; ~~[dsat(X) (if nonzero top stack)]~~ | sat(X)
+| `n:X` | dsat(X) | sat(X)
+
+#### Non-malleable Satisfaction Algorithm
+
+In order to produce non-malleable satisfactions we make use of a function that returns the optimal
+satisfaction and dissatisfaction for a given expression (if any exist), or a special DONTUSE ("don't use") value,
+together with an optional HASSIG ("has signature") marker that tracks whether the solution contains at least one
+signature. To implement the function:
+* Invoke the function recursively for all subexpressions, obtaining all their satisfactions/dissatisfactions.
+* Iterate over all the valid satisfactions/dissatisfactions in the table above (including the non-canonical ones), taking into account:
+ * The dissatisfactions for `sha256`, `ripemd160`, `hash256`, and `hash160` are always malleable, so instead use DONTUSE there.
+ * The non-canonical options for `and_b`, `or_b`, and `thresh` are always overcomplete, so instead use DONTUSE there as well (with HASSIG flag if the original non-canonical solution had one).
+ * The satisfactions for `pk_k`, `pk_h`, and `multi` can be marked HASSIG.
+ * When constructing solutions by combining results for subexpressions, the result is DONTUSE if any of the constituent results is DONTUSE. Furthermore, the result gets the HASSIG tag if any of the constituents does.
+* If among all valid solutions (including DONTUSE ones) more than one does not have the HASSIG marker, return DONTUSE.
+* If instead exactly one does not have the HASSIG marker, return that solution.
+* If all valid solutions have the HASSIG marker, but all of them are DONTUSE, return DONTUSE-HASSIG. The HASSIG marker is important because while this represents a choice between multiple options that would cause malleability if used, they are not available to the attacker, and we may be able to avoid them entirely still.
+* Otherwise, all not-DONTUSE options are valid, so return the smallest one (in terms of witness size).
+
+To produce an overall satisfaction, invoke the function on the toplevel expression. If no valid
+satisfaction is returned, or it is DONTUSE, fail. Otherwise, if any timelocking is used in the
+script but the result does not have the HASSIG flag, also fail. If the satisfaction is both not
+DONTUSE and HASSIG, return it.
+
+
+## Discussion
+
+## Security
+
+Miniscript primarily aims to provide guarantees on the correctness of a Bitcoin Script. That is, to
+guarantee **consensus soundness** and **standardness completeness**. Consensus soundness means
+it is not possible to construct a consensus-valid witness for a Bitcoin Script unless the Miniscript
+spending conditions are met. Standardness completeness means a standardness-valid witness can be
+created for all spending paths of a Miniscript, assuming the resource limits are respected and there
+is no timelock mixing.
+
+Additionally, Miniscript can guarantee the non-malleability and maximum size of a witness. These can
+assist in assessing the soundness of protocols where transaction fees (and therefore transaction
+size) are security-critical parameters.
+
+Hash preimages are constrained to 32 bytes to disallow various forms of griefing, including making
+non-standard (un-relayable) transactions, consensus-invalid swaps across blockchains, as well as
+ensure that satisfaction cost can be accurately calculated.
+
+In order for these properties to not just apply to script, but to an entire transaction, it's
+important that the witness commits to all data relevant for verification. In practice this means
+that scripts whose conditions can be met without any digital signature are insecure. Besides being
+trivially insecure, note how a transaction lacking a signature check allows an attacker to change
+its nLockTime and nSequence fields to meet additional timelock conditions.
+
+### Type System
+
+To statically verify the correctness and malleability guarantees discussed in the previous section,
+we define a type system. See the specifications above for a reference of each fragment's
+requirements and properties. Here we give more information about each type.
+
+Every expression has one of four basic types:
+* "**B**" Base expressions. These take their inputs from the top of the stack. When satisfied, they push a nonzero value of up to 4 bytes onto the stack. When dissatisfied, they push an exact 0 onto the stack (if dissatisfaction without aborting is possible at all). This type is used for most expressions, and required for the top level expression. An example is `older(n)` = ` CHECKSEQUENCEVERIFY`.
+* "**V**" Verify expressions. Like "B", these take their inputs from the top of the stack. Upon satisfaction however, they continue without pushing anything. They cannot be dissatisfied (will abort instead). A "V" can be obtained using the `v:` wrapper on a "B" expression, or by combining other "V" expressions using `and_v`, `or_i`, `or_c`, or `andor`. An example is `v:pk(key)` = ` CHECKSIGVERIFY`.
+* "**K**" Key expressions. They again take their inputs from the top of the stack, but instead of verifying a condition directly they always push a public key onto the stack, for which a signature is still required to satisfy the expression. A "K" can be converted into a "B" using the `c:` wrapper. An example is `pk_h(key)` = `DUP HASH160 EQUALVERIFY`.
+* "**W**" Wrapped expressions. They take their inputs from one below the top of the stack, and push a nonzero (in case of satisfaction) or zero (in case of dissatisfaction) either on top of the stack, or one below. So for example a 3-input "W" would take the stack "A B C D E F" and turn it into "A B F 0" or "A B 0 F" in case of dissatisfaction, and "A B F n" or "A B n F" in case of satisfaction (with n a nonzero value). Every "W" is either `s:B` (SWAP B) or `a:B` (TOALTSTACK B FROMALTSTACK). An example is `s:pk(key)` = `SWAP CHECKSIG`.
+
+Then there are 6 type modifiers, which guarantee additional properties:
+* "**z**" Zero-arg: this expression always consumes exactly 0 stack elements.
+* "**o**" One-arg: this expression always consumes exactly 1 stack element.
+* "**n**" Nonzero: this expression always consumes at least 1 stack element, no satisfaction for this expression requires the top input stack element to be zero.
+* "**d**" Dissatisfiable: a dissatisfaction for this expression can unconditionally be constructed. This implies the dissatisfaction cannot include any signature or hash preimage, and cannot rely on timelocks being satisfied.
+* "**u**" Unit: when satisfied, this expression will put an exact 1 on the stack (as opposed to any nonzero value).
+* "**k**" No timelock mixing. This expression does not contain a mix of heightlock and timelock of the same type. If the miniscript does not have the "k" property, the miniscript template will not match the user expectation of the corresponding spending policy.
+
+Finally to analyze malleability guarantees we introduce 3 new type modifiers:
+* "**s**" Signed: satisfying this expression always requires a signature (predicting whether all satisfactions will be HASSIG).
+* "**f**" Forced: dissatisfying this expression always requires a signature (predicting whether all dissatisfactions will be HASSIG).
+* "**e**" Expressive: this requires a unique unconditional dissatisfaction to exist, and forces all conditional dissatisfactions (if any) to require a signature.
+
+
+### Malleability
+
+Since Segwit, malleating a transaction no longer breaks the validity of unconfirmed descendant
+transactions. However, unintentional malleability may still have a number of much weaker undesirable
+effects. If a witness can be stuffed with additional data, the transaction's feerate will go down,
+potentially to the point where its ability to propagate and get confirmed is impacted. Additionally,
+malleability can be exploited to add roundtrips to BIP152 block propagation, by trying to get
+different miners to mine different versions of the same transaction. Finally, malleability may
+interfere with the usage of hash locks as a mechanism for publishing preimages.
+
+Using the malleability type properties it is possible to determine statically whether a script can
+be non-malleably satisfied under all circumstances. In many cases it is reasonable to only accept
+such guaranteed-non-malleable scripts, as unexpected behavior can occur when using other scripts.
+
+For example, when running the non-malleable satisfaction algorithm above, adding available
+preimages, or increasing the nLockTime/nSequence values actually may make it fail where it succeeded
+before. This is because a larger set of met conditions may mean an existing satisfaction goes from
+non-malleable to malleable. Restricting things to scripts that are guaranteed to be satisfiable in a
+non-malleable way avoids this problem.
+
+When analysing Miniscripts for resource limits, restricting yourself to just non-malleable solutions
+(or even non-malleable scripts) also leads to tighter bounds, as all non-canonical satisfactions and
+dissatisfactions can be left out of consideration.
+
+The malleability analysis makes the following assumptions:
+* The attacker does not have access to any of the private keys of public keys that participate in the Script. Participants with private keys inherently have the ability to produce different satisfactions by creating multiple signatures. While it is also interesting to study the impact rogue participants can have, we treat it as a distinct problem.
+* The attacker only has access to hash preimages that honest users have access to as well. This is a reasonable assumption because hash preimages are revealed once globally, and then available to everyone. On the other hand, making the assumption that attackers may have access to more preimages than honest users makes a large portion of scripts impossible to satisfy in a non-malleable way.
+* The attacker gets to see exactly one satisfying witness of any transaction. If he sees multiple, it becomes possible for the attacker to mix and match different satisfactions. This is very hard to reason about.
+* We restrict this analysis to scripts where no public key is repeated. If signatures constructed for one part of the script can be bound to other checks in the same script, a variant of the mixing from the previous point becomes available that is equally hard to reason about. Furthermore this situation can be avoided by using separate keys.
+* The attacker is constrained by common standardness rules. A miner may be able to malleate a witness considered non-malleable by Miniscript.
+
+#### Non-Malleable Satisfaction
+
+Malleable satisfactions or dissatisfactions appear whenever options are available to attackers distinct from the one taken by honest users. This can happen for multiple reasons:
+1. Two or more options for a satisfaction or dissatisfaction are listed in the table above which are both available to attackers directly. Regardless of which option is used in the honest solution, the attacker can change the solution to the other one.
+2. Two or more options for a satisfaction or dissatisfaction are listed in the table above, only one of which is available to attackers, but the honest solution uses another one. In that case, the attacker can modify the solution to pick the one available to him.
+3. The honest users pick a solution that contains a satisfaction which can be turned into a dissatisfaction without invalidating the overall witness. Those are called overcomplete solutions.
+
+Because we assume attackers never have access to private keys, we can treat any solution that
+includes a signature as one that is unavailable to attackers. For others, the worst case is that the
+attacker has access to every solution the honest users have, but no others: for preimages this is an
+explicit assumption, while timelock availability is determined by the nLockTime and nSequence fields
+in the transaction. As long as the overall satisfaction includes at least one signature, those
+values are fixed, and timelock availability is identical for attackers and honest users.
+
+The description of the non-malleable satisfaction algorithm can be used to show that no
+non-canonical solutions listed in the satisfaction table can occur inside non-malleable
+satisfaction:
+* Some of the non-canonical options (the `or_b`, `and_b`, and `thresh` ones) are overcomplete, and thus can clearly not appear in non-malleable satisfactions.
+* The fact that non-"d" expressions cannot be dissatisfied in valid witnesses rules out the usage of the non-canonical `and_v` dissatisfaction.
+* "d" expressions are defined to be unconditionally dissatisfiable, which implies that for those a non-HASSIG dissatisfaction must exist. Non-HASSIG solutions must be preferred over HASSIG ones (reason 2), and when multiple non-HASSIG ones exist, none can be used (reason 1). This lets us rule out the other non-canonical options in the table:
+ * `j:X` is always "d", its non-HASSIG dissatisfaction "0" always exists, and thus rules out any usage of "dsat(X)".
+ * If `andor(X,Y,Z)` is "d", a non-HASSIG dissatisfaction "dsat(Z) dsat(X)" must exist, and thus rules out any usage of "dsat(Y) sat(X)".
+ * If `and_b(X,Y)` is "d", a non-HASSIG dissatisfaction "dsat(Y) dsat(X)" must exist, and thus rules out any usage of "dsat(Y) sat(X)" and "sat(Y) dsat(X)". Those are also overcomplete.
+ * `thresh(k,...)` is always "d", a non-HASSIG dissatisfaction with just dissatisfactions must exist due to typing rules, and thus rules out usage of the other dissatisfactions. They are also overcomplete.
+
+
+### Resource Limits
+
+Various types of Bitcoin Scripts have different resource limitations, either through consensus or standardness. Some of them affect otherwise valid Miniscripts:
+* In P2WSH, scripts larger than 3600 bytes are invalid by standardness. In Tapscript, scripts are implicitly bounded by the maximum size of a block (1 million virtual bytes).
+* In P2WSH, script satisfactions where the total number of non-push opcodes plus the number of keys participating in all executed `CHECKMULTISIG` is above 201 are invalid by consensus.
+* In both Tapscript and P2WSH, script satisfactions which make the stack exceed 1000 elements before or during execution are invalid.
+* In P2WSH, satisfactions with a witness consisting of over 100 stack elements (excluding the script itself) are invalid by standardness.
+
+A static analysis can be performed on a Miniscript to verify if none, all or any of the spending
+paths hit any of the limits.
+
+
+## Test Vectors
+
+TBD
+
+## Backwards Compatibility
+
+Miniscript's syntax is compatible with BIP 380 Output Script Descriptors, and should be considered
+an extension to it that provides a new type of Script expression that is only valid in
+`wsh()` and `tr()` contexts. As these are wholly new expressions, they are not
+compatible with any existing implementation of descriptors. Additionally, the scripts produced are
+unlikely to be standard scripts.
+
+The `pk()`, `pkh()`, `multi()`, and `multi_a()`
+fragments overlap with existing descriptors. These parse to the same semantic meanings as those
+descriptors and produce the same scripts.
+
+## Reference Implementation
+
+A first reference implementation and documentation for Miniscript in P2WSH was originally published at
+https://github.com/sipa/miniscript .
+
+The reference implementation for Miniscript in P2WSH was introduced in Bitcoin Core through PRs
+[24147](https://github.com/bitcoin/bitcoin/pull/24147), [24148](https://github.com/bitcoin/bitcoin/pull/24148), and
+[24149](https://github.com/bitcoin/bitcoin/pull/24149). The last one to be merged was released in Bitcoin
+Core version 25.0.
+
+The reference implementation for Miniscript in Tapscript was introduced in Bitcoin Core in PR
+[27255](https://github.com/bitcoin/bitcoin/pull/27255). This PR was merged and released in Bitcoin Core
+version 26.0.
diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki
new file mode 100644
index 0000000000..a6a147b446
--- /dev/null
+++ b/bip-0380.mediawiki
@@ -0,0 +1,338 @@
+
+
+==Abstract==
+
+Output Script Descriptors are a simple language which can be used to describe collections of output scripts.
+There can be many different descriptor fragments and functions.
+This document describes the general syntax for descriptors, descriptor checksums, and common expressions.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+Bitcoin wallets traditionally have stored a set of keys which are later serialized and mutated to produce the output scripts that the wallet watches and the addresses it provides to users.
+Typically backups have consisted of solely the private keys, nowadays primarily in the form of BIP 39 mnemonics.
+However this backup solution is insufficient, especially since the introduction of Segregated Witness which added new output types.
+Given just the private keys, it is not possible for restored wallets to know which kinds of output scripts and addresses to produce.
+This has lead to incompatibilities between wallets when restoring a backup or exporting data for a watch only wallet.
+
+Further complicating matters are BIP 32 derivation paths.
+Although BIPs 44, 49, and 84 have specified standard BIP 32 derivation paths for different output scripts and addresses, not all wallets support those derivation paths nor use them.
+The lack of derivation path information in these backups and exports leads to further incompatibilities between wallets.
+
+Current solutions to these issues have not been generic and can be viewed as being layer violations.
+Solutions such as introducing different version bytes for extended key serialization both are a layer violation (key derivation should be separate from script type meaning) and specific only to a particular derivation path and script type.
+
+Output Script Descriptors introduce a generic solution to these issues.
+Script types are specified explicitly through the use of Script Expressions.
+Key derivation paths are specified explicitly in Key Expressions.
+These allow for creating wallet backups and exports which specify the exact scripts, subscripts (redeemScript, witnessScript, etc.), and keys to produce.
+With the general structure specified in this BIP, new Script Expressions can be introduced as new script types are added.
+Lastly, the use of common terminology and existing standards allow for Output Script Descriptors to be engineer readable so that the results can be understood at a glance.
+
+==Specification==
+
+Descriptors consist of several types of expressions.
+The top level expression is a SCRIPT.
+This expression may be followed by #CHECKSUM, where CHECKSUM is an 8 character alphanumeric descriptor checksum.
+Although the checksum is optional for parsing, applications may choose to reject descriptors that do not contain a checksum.
+
+===Script Expressions===
+
+Script Expressions (denoted SCRIPT) are expressions which correspond directly with a Bitcoin script.
+These expressions are written as functions and take arguments.
+Such expressions have a script template which is filled with the arguments correspondingly.
+Expressions are written with a human readable identifier string with the arguments enclosed with parentheses.
+The identifier string should be alphanumeric and may include underscores.
+
+The arguments to a script expression are defined by that expression itself.
+They could be a script expression, a key expression, or some other expression entirely.
+
+===Key Expressions===
+
+A common expression used as an argument to script expressions are key expressions (denoted KEY).
+These represent a public or private key and, optionally, information about the origin of that key.
+Key expressions can only be used as arguments to script expressions.
+
+Key expressions consist of:
+* Optionally, key origin information, consisting of:
+** An open bracket [
+** Exactly 8 hex characters for the fingerprint of the key where the derivation starts (see BIP 32 for details)
+** Followed by zero or more /NUM or /NUMh path elements to indicate the unhardened or hardened derivation steps between the fingerprint and the key that follows.
+** A closing bracket ]
+* Followed by the actual key, which is either:
+** A hex encoded public key, which depending on the script expression, may be either:
+*** 66 hex character string beginning with 02 or 03 representing a compressed public key
+*** 130 hex character string beginning with 04 representing an uncompressed public key
+** A [[https://en.bitcoin.it/wiki/Wallet_import_format|WIF]] encoded private key
+** xpub encoded extended public key or xprv encoded extended private key (as defined in BIP 32)
+*** Followed by zero or more /NUM or /NUMh path elements indicating BIP 32 derivation steps to be taken after the given extended key.
+*** Optionally followed by a single /* or /*h final step to denote all direct unhardened or hardened children.
+
+If the KEY is a BIP 32 extended key, before output scripts can be created, child keys must be derived using the derivation information that follows the extended key.
+When the final step is /* or /*', an output script will be produced for every child key index.
+The derived key must be not be serialized as an uncompressed public key.
+Script Expressions may have further requirements on how derived public keys are serialized for script creation.
+
+In the above specification, the hardened indicator h may be replaced with alternative hardened indicators of H or '.
+
+====Normalization of Key Expressions with Hardened Derivation====
+
+When a descriptor is exported without private keys, it is necessary to do additional derivation to remove any intermediate hardened derivation steps for the exported descriptor to be useful.
+The exporter should derive the extended public key at the last hardened derivation step and use that extended public key as the key in the descriptor.
+The derivation steps that were taken to get to that key must be added to the previous key origin information.
+If there is no key origin information, then one must be added for the newly derived extended public key.
+If the final derivation is hardened, then it is not necessary to do additional derivation.
+
+===Character Set===
+
+The expressions used in descriptors must only contain characters within this character set so that the descriptor checksum will work.
+
+The allowed characters are:
+
+Note that on the last line is a space character.
+
+This character set is written as 3 groups of 32 characters in this specific order so that the checksum below can identify more errors.
+The first group are the most common "unprotected" characters (i.e. things such as hex and keypaths that do not already have their own checksums).
+Case errors cause an offset that is a multiple of 32 while as many alphabetic characters are in the same group while following the previous restrictions.
+
+===Checksum===
+
+Following the top level script expression is a single octothorpe (#) followed by the 8 character checksum.
+The checksum is an error correcting checksum similar to bech32.
+
+The checksum has the following properties:
+* Mistakes in a descriptor string are measured in "symbol errors". The higher the number of symbol errors, the harder it is to detect:
+** An error substituting a character from 0123456789()[],'/*abcdefgh@:$%{} for another in that set always counts as 1 symbol error.
+*** Note that hex encoded keys are covered by these characters. Extended keys (xpub and xprv) use other characters too, but also have their own checksum mechanism.
+*** SCRIPT expression function names use other characters, but mistakes in these would generally result in an unparsable descriptor.
+** A case error always counts as 1 symbol error.
+** Any other 1 character substitution error counts as 1 or 2 symbol errors.
+* Any 1 symbol error is always detected.
+* Any 2 or 3 symbol error in a descriptor of up to 49154 characters is always detected.
+* Any 4 symbol error in a descriptor of up to 507 characters is always detected.
+* Any 5 symbol error in a descriptor of up to 77 characters is always detected.
+* Is optimized to minimize the chance of a 5 symbol error in a descriptor up to 387 characters is undetected
+* Random errors have a chance of 1 in 240 of being undetected.
+
+The checksum itself uses the same character set as bech32: qpzry9x8gf2tvdw0s3jn54khce6mua7l
+
+Valid descriptor strings with a checksum must pass the criteria for validity specified by the Python3 code snippet below.
+The function descsum_check must return true when its argument s is a descriptor consisting in the form SCRIPT#CHECKSUM.
+
+
+INPUT_CHARSET = "0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ "
+CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+GENERATOR = [0xf5dee51989, 0xa9fdca3312, 0x1bab10e32d, 0x3706b1677a, 0x644d626ffd]
+
+def descsum_polymod(symbols):
+ """Internal function that computes the descriptor checksum."""
+ chk = 1
+ for value in symbols:
+ top = chk >> 35
+ chk = (chk & 0x7ffffffff) << 5 ^ value
+ for i in range(5):
+ chk ^= GENERATOR[i] if ((top >> i) & 1) else 0
+ return chk
+
+def descsum_expand(s):
+ """Internal function that does the character to symbol expansion"""
+ groups = []
+ symbols = []
+ for c in s:
+ if not c in INPUT_CHARSET:
+ return None
+ v = INPUT_CHARSET.find(c)
+ symbols.append(v & 31)
+ groups.append(v >> 5)
+ if len(groups) == 3:
+ symbols.append(groups[0] * 9 + groups[1] * 3 + groups[2])
+ groups = []
+ if len(groups) == 1:
+ symbols.append(groups[0])
+ elif len(groups) == 2:
+ symbols.append(groups[0] * 3 + groups[1])
+ return symbols
+
+def descsum_check(s):
+ """Verify that the checksum is correct in a descriptor"""
+ if s[-9] != '#':
+ return False
+ if not all(x in CHECKSUM_CHARSET for x in s[-8:]):
+ return False
+ symbols = descsum_expand(s[:-9]) + [CHECKSUM_CHARSET.find(x) for x in s[-8:]]
+ return descsum_polymod(symbols) == 1
+
+
+This implements a BCH code that has the properties described above.
+The entire descriptor string is first processed into an array of symbols.
+The symbol for each character is its position within its group.
+After every 3rd symbol, a 4th symbol is inserted which represents the group numbers combined together.
+This means that a change that only affects the position within a group, or only a group number change, will only affect a single symbol.
+
+To construct a valid checksum given a script expression, the code below can be used:
+
+
+def descsum_create(s):
+ """Add a checksum to a descriptor without"""
+ symbols = descsum_expand(s) + [0, 0, 0, 0, 0, 0, 0, 0]
+ checksum = descsum_polymod(symbols) ^ 1
+ return s + '#' + ''.join(CHECKSUM_CHARSET[(checksum >> (5 * (7 - i))) & 31] for i in range(8))
+
+
+
+==Test Vectors==
+
+The following tests cover the checksum and character set:
+
+* Valid checksum: raw(deadbeef)#89f8spxm
+* No checksum: raw(deadbeef)
+* Missing checksum: raw(deadbeef)#
+* Too long checksum (9 chars): raw(deadbeef)#89f8spxmx
+* Too short checksum (7 chars): raw(deadbeef)#89f8spx
+* Error in payload: raw(deedbeef)#89f8spxm
+* Error in checksum: raw(deedbeef)##9f8spxm
+* Invalid characters in payload: raw(Ü)#00000000
+
+The following tests cover key expressions:
+
+Valid expressions:
+
+* Compressed public key: 0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Uncompressed public key: 04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235
+* Public key with key origin: [deadbeef/0h/0h/0h]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Public key with key origin (' as hardened indicator): [deadbeef/0'/0'/0']0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Public key with key origin (mixed hardened indicator): [deadbeef/0'/0h/0']0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* WIF uncompressed private key 5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss
+* WIF compressed private key L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1
+* Extended public key: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
+* Extended public key with key origin: [deadbeef/0h/1h/2h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
+* Extended public key with derivation: [deadbeef/0h/1h/2h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3/4/5
+* Extended public key with derivation and children: [deadbeef/0h/1h/2h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3/4/5/*
+* Extended public key with hardened derivation and unhardened children: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3h/4h/5h/*
+* Extended public key with hardened derivation and children: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3h/4h/5h/*h
+* Extended public key with key origin, hardened derivation and children: [deadbeef/0h/1h/2]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3h/4h/5h/*h
+* Extended private key: xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc
+* Extended private key with key origin: [deadbeef/0h/1h/2h]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc
+* Extended private key with derivation: [deadbeef/0h/1h/2h]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3/4/5
+* Extended private key with derivation and children: [deadbeef/0h/1h/2h]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3/4/5/*
+* Extended private key with hardened derivation and unhardened children: xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3h/4h/5h/*
+* Extended private key with hardened derivation and children: xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3h/4h/5h/*h
+* Extended private key with key origin, hardened derivation and children: [deadbeef/0h/1h/2]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3h/4h/5h/*h
+
+Invalid expression:
+
+* Children indicator in key origin: [deadbeef/0h/0h/0h/*]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Trailing slash in key origin: [deadbeef/0h/0h/0h/]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Too short fingerprint: [deadbef/0h/0h/0h]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Too long fingerprint: [deadbeeef/0h/0h/0h]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Invalid hardened indicators: [deadbeef/0f/0f/0f]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Invalid hardened indicators: [deadbeef/0H/0H/0H]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Invalid hardened indicators: [deadbeef/-0/-0/-0]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
+* Private key with derivation: L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1/0
+* Private key with derivation children: L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1/*
+* Derivation index out of range: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483648
+* Invalid derivation index: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/1aa
+* Multiple key origins: [aaaaaaaa][aaaaaaaa]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0
+* Missing key origin start: aaaaaaaa]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0
+* Non hex fingerprint: [gaaaaaaa]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0
+* Key origin with no public key: [deadbeef]
+
+==Backwards Compatibility==
+
+Output script descriptors are an entirely new language which is not compatible with any existing software.
+However many components of the expressions reuse encodings and serializations defined by previous BIPs.
+
+Output script descriptors are designed for future extension with further fragment types and new script expressions.
+These will be specified in additional BIPs.
+
+==Reference Implementation==
+
+Descriptors have been implemented in Bitcoin Core since version 0.17.
+
+==Appendix A: Index of Expressions==
+
+Future BIPs may specify additional types of expressions.
+All available expression types are listed in this table.
+
+{|
+! Name
+! Denoted As
+! BIP
+|-
+| Script
+| SCRIPT
+| 380
+|-
+| Key
+| KEY
+| 380
+|-
+| Tree
+| TREE
+| [[bip-0386.mediawiki|386]]
+|}
+
+==Appendix B: Index of Script Expressions==
+
+Script expressions will be specified in additional BIPs.
+This Table lists all available Script expressions and the BIPs specifying them.
+
+{|
+! Expression
+! BIP
+|-
+| pk(KEY)
+| [[bip-0381.mediawiki|381]]
+|-
+| pkh(KEY)
+| [[bip-0381.mediawiki|381]]
+|-
+| sh(SCRIPT)
+| [[bip-0381.mediawiki|381]]
+|-
+| wpkh(KEY)
+| [[bip-0382.mediawiki|382]]
+|-
+| wsh(SCRIPT)
+| [[bip-0382.mediawiki|382]]
+|-
+| multi(NUM, KEY, ..., KEY)
+| [[bip-0383.mediawiki|383]]
+|-
+| sortedmulti(NUM, KEY, ..., KEY)
+| [[bip-0383.mediawiki|383]]
+|-
+| combo(KEY)
+| [[bip-0384.mediawiki|384]]
+|-
+| raw(HEX)
+| [[bip-0385.mediawiki|385]]
+|-
+| addr(ADDR)
+| [[bip-0385.mediawiki|385]]
+|-
+| tr(KEY), tr(KEY, TREE)
+| [[bip-0386.mediawiki|386]]
+|-
+| musig(KEY, KEY, ..., KEY)
+| [[bip-0390.mediawiki|390]]
+|}
diff --git a/bip-0381.mediawiki b/bip-0381.mediawiki
new file mode 100644
index 0000000000..13c9e15381
--- /dev/null
+++ b/bip-0381.mediawiki
@@ -0,0 +1,125 @@
+
+
+==Abstract==
+
+This document specifies pk(), pkh(), and sh() output script descriptors.
+pk() descriptors take a key and produces a P2PK output script.
+pkh() descriptors take a key and produces a P2PKH output script.
+sh() descriptors take a script and produces a P2SH output script.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+Prior to the activation of Segregated Witness, there were 3 main standard output script formats: P2PK, P2PKH, and P2SH.
+These expressions allow specifying those formats as a descriptor.
+
+==Specification==
+
+Three new script expressions are defined: pk(), pkh(), and sh().
+
+===pk()===
+
+The pk(KEY) expression can be used in any context or level of a descriptor.
+It takes a single key expression as an argument and produces a P2PK output script.
+Depending on the higher level descriptors, there may be restrictions on the type of public keys that can be included.
+Such restrictions will be specified by those descriptors.
+
+The output script produced is:
+
+ OP_CHECKSIG
+
+
+===pkh()===
+
+The pkh(KEY) expression can be used as a top level expression, or inside of either a sh() or wsh() descriptor.
+It takes a single key expression as an argument and produces a P2PKH output script.
+Depending on the higher level descriptors, there may be restrictions on the type of public keys that can be included.
+Such restrictions will be specified by those descriptors.
+
+The output script produced is:
+
+OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG
+
+
+===sh()===
+
+The sh(SCRIPT) expression can only be used as a top level expression.
+It takes a single script expression as an argument and produces a P2SH output script.
+sh() expressions also create a redeemScript which is required in order to spend outputs which use its output script.
+This redeemScript is the output script produced by the SCRIPT argument to sh().
+
+The output script produced is:
+
+OP_HASH160 OP_EQUAL
+
+
+==Test Vectors==
+
+Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed.
+
+* pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)
+** 2103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bdac
+* pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
+** 2103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bdac
+* pkh([deadbeef/1/2'/3/4']L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)
+** 76a9149a1c78a507689f6f54b847ad1cef1e614ee23f1e88ac
+* pkh([deadbeef/1/2'/3/4']03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
+** 76a9149a1c78a507689f6f54b847ad1cef1e614ee23f1e88ac
+* pkh([deadbeef/1/2h/3/4h]03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
+** 76a9149a1c78a507689f6f54b847ad1cef1e614ee23f1e88ac
+* pk(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)
+** 4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235ac
+* pk(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)
+** 4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235ac
+* pkh(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)
+** 76a914b5bd079c4d57cc7fc28ecf8213a6b791625b818388ac
+* pkh(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)
+** 76a914b5bd079c4d57cc7fc28ecf8213a6b791625b818388ac
+* sh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))
+** a9141857af51a5e516552b3086430fd8ce55f7c1a52487
+* sh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+** a9141857af51a5e516552b3086430fd8ce55f7c1a52487
+* sh(pkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))
+** a9141a31ad23bf49c247dd531a623c2ef57da3c400c587
+* sh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+** a9141a31ad23bf49c247dd531a623c2ef57da3c400c587
+* pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0)
+** 76a914ebdc90806a9c4356c1c88e42216611e1cb4c1c1788ac
+* pkh([bd16bee5/2147483647h]xpub69H7F5dQzmVd3vPuLKtcXJziMEQByuDidnX3YdwgtNsecY5HRGtAAQC5mXTt4dsv9RzyjgDjAQs9VGVV6ydYCHnprc9vvaA5YtqWyL6hyds/0)
+** 76a914ebdc90806a9c4356c1c88e42216611e1cb4c1c1788ac
+* pk(xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0)
+** 210379e45b3cf75f9c5f9befd8e9506fb962f6a9d185ac87001ec44a8d3df8d4a9e3ac
+* pk(xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0)
+** 210379e45b3cf75f9c5f9befd8e9506fb962f6a9d185ac87001ec44a8d3df8d4a9e3ac
+
+Invalid descriptors
+
+* pk() only accepts key expressions: pk(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+* pkh() only accepts key expressions: pkh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+* sh() only accepts script expressions: sh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
+* sh() is top level only: sh(sh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))
+
+==Backwards Compatibility==
+
+pk(), pkh(), and sh() descriptors use the format and general operation specified in [[bip-0380.mediawiki|380]].
+As these are wholly new descriptors, they are not compatible with any implementation.
+However the scripts produced are standard scripts so existing software are likely to be familiar with them.
+
+==Reference Implementation==
+
+pk(), pkh(), and sh() descriptors have been implemented in Bitcoin Core since version 0.17.
diff --git a/bip-0382.mediawiki b/bip-0382.mediawiki
new file mode 100644
index 0000000000..d85e168a4f
--- /dev/null
+++ b/bip-0382.mediawiki
@@ -0,0 +1,115 @@
+
+
+==Abstract==
+
+This document specifies wpkh(), and wsh() output script descriptors.
+wpkh() descriptors take a key and produces a P2WPKH output script.
+wsh() descriptors take a script and produces a P2WSH output script.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+Segregated Witness added 2 additional standard output script formats: P2WPKH and P2WSH.
+These expressions allow specifying those formats as a descriptor.
+
+==Specification==
+
+Two new script expressions are defined: wpkh(), and wsh().
+
+===wpkh()===
+
+The wpkh(KEY) expression can be used as a top level expression, or inside of a sh() descriptor.
+It takes a single key expression as an argument and produces a P2WPKH output script.
+Only keys which are/have compressed public keys can be contained in a wpkh() expression.
+
+The output script produced is:
+
+OP_0
+
+
+===wsh()===
+
+The wsh(SCRIPT) expression can be used as a top level expression, or inside of a sh() descriptor.
+It takes a single script expression as an argument and produces a P2WSH output script.
+wsh() expressions also create a witnessScript which is required in order to spend outputs which use its output script.
+This redeemScript is the output script produced by the SCRIPT argument to wsh().
+Any key expression found in any script expression contained by a wsh() expression must only produce compressed public keys.
+
+The output script produced is:
+
+OP_0
+
+
+==Test Vectors==
+
+Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed.
+
+* wpkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)
+** 00149a1c78a507689f6f54b847ad1cef1e614ee23f1e
+* wpkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
+** 00149a1c78a507689f6f54b847ad1cef1e614ee23f1e
+* wpkh([ffffffff/13']xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt/1/2/0)
+** 0014326b2249e3a25d5dc60935f044ee835d090ba859
+* wpkh([ffffffff/13']xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/1/2/*)
+** 0014326b2249e3a25d5dc60935f044ee835d090ba859
+** 0014af0bd98abc2f2cae66e36896a39ffe2d32984fb7
+** 00141fa798efd1cbf95cebf912c031b8a4a6e9fb9f27
+* sh(wpkh(xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi/10/20/30/40/*'))
+** a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87
+** a914bed59fc0024fae941d6e20a3b44a109ae740129287
+** a9148483aa1116eb9c05c482a72bada4b1db24af654387
+* sh(wpkh(xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi/10/20/30/40/*h))
+** a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87
+** a914bed59fc0024fae941d6e20a3b44a109ae740129287
+** a9148483aa1116eb9c05c482a72bada4b1db24af654387
+* wsh(pkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))
+** 0020338e023079b91c58571b20e602d7805fb808c22473cbc391a41b1bd3a192e75b
+* wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+** 0020338e023079b91c58571b20e602d7805fb808c22473cbc391a41b1bd3a192e75b
+* wsh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))
+** 00202e271faa2325c199d25d22e1ead982e45b64eeb4f31e73dbdf41bd4b5fec23fa
+* wsh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+** 00202e271faa2325c199d25d22e1ead982e45b64eeb4f31e73dbdf41bd4b5fec23fa
+* sh(wsh(pkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)))
+** a914b61b92e2ca21bac1e72a3ab859a742982bea960a87
+* sh(wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))
+** a914b61b92e2ca21bac1e72a3ab859a742982bea960a87
+
+Invalid descriptors with descriptions
+
+* Uncompressed public key in wpkh(): wpkh(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)
+* Uncompressed public key in wpkh(): sh(wpkh(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss))
+* Uncompressed public key in wpkh(): wpkh(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)
+* Uncompressed public key in wpkh(): sh(wpkh(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235))
+* Uncompressed public keys under wsh(): wsh(pk(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss))
+* Uncompressed public keys under wsh(): wsh(pk(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235))
+* wpkh() nested in wsh(): wsh(wpkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+* wsh() nested in wsh(): wsh(wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))
+* wsh() nested in wsh(): sh(wsh(wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))))
+* Script in wpkh(): wpkh(wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))
+* Key in wsh(): wsh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
+
+==Backwards Compatibility==
+
+wpkh(), and wsh() descriptors use the format and general operation specified in [[bip-0380.mediawiki|380]].
+As these are a wholly new descriptors, they are not compatible with any implementation.
+However the scripts produced are standard scripts so existing software are likely to be familiar with them.
+
+==Reference Implementation==
+
+wpkh(), and wsh() descriptors have been implemented in Bitcoin Core since version 0.17.
diff --git a/bip-0383.mediawiki b/bip-0383.mediawiki
new file mode 100644
index 0000000000..522eb0cc72
--- /dev/null
+++ b/bip-0383.mediawiki
@@ -0,0 +1,108 @@
+
+
+==Abstract==
+
+This document specifies multi(), and sortedmulti() output script descriptors.
+Both functions take a threshold and one or more public keys and produce a multisig output script.
+multi() specifies the public keys in the output script in the order given in the descriptor while sortedmulti() sorts the public keys lexicographically when the output script is produced.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+The most common complex script used in Bitcoin is a threshold multisig.
+These expressions allow specifying multisig scripts as a descriptor.
+
+==Specification==
+
+Two new script expressions are defined: multi(), and sortedmulti().
+Both expressions produce the scripts of the same template and take the same arguments.
+They are written as multi(k,KEY_1,KEY_2,...,KEY_n).
+k is the threshold - the number of keys that must sign the input for the script to be valid.
+KEY_1,KEY_2,...,KEY_n are the key expressions for the multisig. k must be less than or equal to n.
+
+multi() and sortedmulti() expressions can be used as a top level expression, or inside of either a sh() or wsh() descriptor.
+Depending on the higher level descriptors, there may be restrictions on the type of public keys that can be included.
+
+Depending on the higher level descriptors, there are also restrictions on the number of keys that can be present, i.e. the maximum value of n.
+When used at the top level, there can only be at most 3 keys.
+When used inside of a sh() expression, there can only be most 15 compressed public keys (this is limited by the P2SH script limit).
+Otherwise the maximum number of keys is 20.
+
+The output script produced also depends on the value of k. If k is less than or equal to 16:
+
+OP_k KEY_1 KEY_2 ... KEY_n OP_CHECKMULTISIG
+
+
+if k is greater than 16:
+
+k KEY_1 KEY_2 ... KEY_n OP_CHECKMULTISIG
+
+
+===sortedmulti()===
+
+The only change for sortedmulti() is that the keys are sorted lexicographically prior to the creation of the output script.
+This sorting is on the keys that are to be put into the output script, i.e. after all extended keys are derived.
+
+===Multiple Extended Keys===
+
+When one or more the key expressions in a multi() or sortedmulti() expression are extended keys, the derived keys use the same child index.
+This changes the keys in lockstep and allows for output scripts to be indexed in the same way that the derived keys are indexed.
+
+==Test Vectors==
+
+Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed.
+
+* multi(1,L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)
+** 512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae
+* multi(1,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)
+** 512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae
+* sortedmulti(1,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
+** 512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae
+* sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))
+** a91445a9a622a8b0a1269944be477640eedc447bbd8487
+* sortedmulti(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/0/*)
+** 5221025d5fc65ebb8d44a5274b53bac21ff8307fec2334a32df05553459f8b1f7fe1b62102fbd47cc8034098f0e6a94c6aeee8528abf0a2153a5d8e46d325b7284c046784652ae
+** 52210264fd4d1f5dea8ded94c61e9641309349b62f27fbffe807291f664e286bfbe6472103f4ece6dfccfa37b211eb3d0af4d0c61dba9ef698622dc17eecdf764beeb005a652ae
+** 5221022ccabda84c30bad578b13c89eb3b9544ce149787e5b538175b1d1ba259cbb83321024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c52ae
+* wsh(multi(2,xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0,xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt/1/2/*,xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi/10/20/30/40/*'))
+** 0020b92623201f3bb7c3771d45b2ad1d0351ea8fbf8cfe0a0e570264e1075fa1948f
+** 002036a08bbe4923af41cf4316817c93b8d37e2f635dd25cfff06bd50df6ae7ea203
+** 0020a96e7ab4607ca6b261bfe3245ffda9c746b28d3f59e83d34820ec0e2b36c139c
+* sh(wsh(multi(16,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06,0399eb0a5487515802dc14544cf10b3666623762fbed2ec38a3975716e2c29c232)))
+** a9147fc63e13dc25e8a95a3cee3d9a714ac3afd96f1e87
+* wsh(multi(20,KzoAz5CanayRKex3fSLQ2BwJpN7U52gZvxMyk78nDMHuqrUxuSJy,KwGNz6YCCQtYvFzMtrC6D3tKTKdBBboMrLTsjr2NYVBwapCkn7Mr,KxogYhiNfwxuswvXV66eFyKcCpm7dZ7TqHVqujHAVUjJxyivxQ9X,L2BUNduTSyZwZjwNHynQTF14mv2uz2NRq5n5sYWTb4FkkmqgEE9f,L1okJGHGn1kFjdXHKxXjwVVtmCMR2JA5QsbKCSpSb7ReQjezKeoD,KxDCNSST75HFPaW5QKpzHtAyaCQC7p9Vo3FYfi2u4dXD1vgMiboK,L5edQjFtnkcf5UWURn6UuuoFrabgDQUHdheKCziwN42aLwS3KizU,KzF8UWFcEC7BYTq8Go1xVimMkDmyNYVmXV5PV7RuDicvAocoPB8i,L3nHUboKG2w4VSJ5jYZ5CBM97oeK6YuKvfZxrefdShECcjEYKMWZ,KyjHo36dWkYhimKmVVmQTq3gERv3pnqA4xFCpvUgbGDJad7eS8WE,KwsfyHKRUTZPQtysN7M3tZ4GXTnuov5XRgjdF2XCG8faAPmFruRF,KzCUbGhN9LJhdeFfL9zQgTJMjqxdBKEekRGZX24hXdgCNCijkkap,KzgpMBwwsDLwkaC5UrmBgCYaBD2WgZ7PBoGYXR8KT7gCA9UTN5a3,KyBXTPy4T7YG4q9tcAM3LkvfRpD1ybHMvcJ2ehaWXaSqeGUxEdkP,KzJDe9iwJRPtKP2F2AoN6zBgzS7uiuAwhWCfGdNeYJ3PC1HNJ8M8,L1xbHrxynrqLKkoYc4qtoQPx6uy5qYXR5ZDYVYBSRmCV5piU3JG9,KzRedjSwMggebB3VufhbzpYJnvHfHe9kPJSjCU5QpJdAW3NSZxYS,Kyjtp5858xL7JfeV4PNRCKy2t6XvgqNNepArGY9F9F1SSPqNEMs3,L2D4RLHPiHBidkHS8ftx11jJk1hGFELvxh8LoxNQheaGT58dKenW,KyLPZdwY4td98bKkXqEXTEBX3vwEYTQo1yyLjX2jKXA63GBpmSjv))
+** 0020376bd8344b8b6ebe504ff85ef743eaa1aa9272178223bcb6887e9378efb341ac
+* sh(wsh(multi(20,KzoAz5CanayRKex3fSLQ2BwJpN7U52gZvxMyk78nDMHuqrUxuSJy,KwGNz6YCCQtYvFzMtrC6D3tKTKdBBboMrLTsjr2NYVBwapCkn7Mr,KxogYhiNfwxuswvXV66eFyKcCpm7dZ7TqHVqujHAVUjJxyivxQ9X,L2BUNduTSyZwZjwNHynQTF14mv2uz2NRq5n5sYWTb4FkkmqgEE9f,L1okJGHGn1kFjdXHKxXjwVVtmCMR2JA5QsbKCSpSb7ReQjezKeoD,KxDCNSST75HFPaW5QKpzHtAyaCQC7p9Vo3FYfi2u4dXD1vgMiboK,L5edQjFtnkcf5UWURn6UuuoFrabgDQUHdheKCziwN42aLwS3KizU,KzF8UWFcEC7BYTq8Go1xVimMkDmyNYVmXV5PV7RuDicvAocoPB8i,L3nHUboKG2w4VSJ5jYZ5CBM97oeK6YuKvfZxrefdShECcjEYKMWZ,KyjHo36dWkYhimKmVVmQTq3gERv3pnqA4xFCpvUgbGDJad7eS8WE,KwsfyHKRUTZPQtysN7M3tZ4GXTnuov5XRgjdF2XCG8faAPmFruRF,KzCUbGhN9LJhdeFfL9zQgTJMjqxdBKEekRGZX24hXdgCNCijkkap,KzgpMBwwsDLwkaC5UrmBgCYaBD2WgZ7PBoGYXR8KT7gCA9UTN5a3,KyBXTPy4T7YG4q9tcAM3LkvfRpD1ybHMvcJ2ehaWXaSqeGUxEdkP,KzJDe9iwJRPtKP2F2AoN6zBgzS7uiuAwhWCfGdNeYJ3PC1HNJ8M8,L1xbHrxynrqLKkoYc4qtoQPx6uy5qYXR5ZDYVYBSRmCV5piU3JG9,KzRedjSwMggebB3VufhbzpYJnvHfHe9kPJSjCU5QpJdAW3NSZxYS,Kyjtp5858xL7JfeV4PNRCKy2t6XvgqNNepArGY9F9F1SSPqNEMs3,L2D4RLHPiHBidkHS8ftx11jJk1hGFELvxh8LoxNQheaGT58dKenW,KyLPZdwY4td98bKkXqEXTEBX3vwEYTQo1yyLjX2jKXA63GBpmSjv)))
+** a914c2c9c510e9d7f92fd6131e94803a8d34a8ef675e87
+
+Invalid descriptors
+
+* More than 15 keys in P2SH multisig: sh(multi(16,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06,0399eb0a5487515802dc14544cf10b3666623762fbed2ec38a3975716e2c29c232))
+* Invalid threshold: multi(a,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)
+* Threshold of 0: multi(0,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)
+* Threshold larger than keys: multi(3,L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)
+
+==Backwards Compatibility==
+
+multi(), and sortedmulti() descriptors use the format and general operation specified in [[bip-0380.mediawiki|380]].
+As these are a wholly new descriptors, they are not compatible with any implementation.
+However the scripts produced are standard scripts so existing software are likely to be familiar with them.
+
+==Reference Implementation==
+
+multi(), and sortedmulti() descriptors have been implemented in Bitcoin Core since version 0.17.
diff --git a/bip-0384.mediawiki b/bip-0384.mediawiki
new file mode 100644
index 0000000000..585af5e71b
--- /dev/null
+++ b/bip-0384.mediawiki
@@ -0,0 +1,79 @@
+
+
+==Abstract==
+
+This document specifies combo() output script descriptors.
+These take a key and produce P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH output scripts if applicable to the key.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+In order to make the transition from traditional key based wallets to descriptor based wallets easier, it is useful to be able to take a key and produce the scripts which have traditionally been produced by wallet software.
+
+==Specification==
+
+A new top level script expression is defined: combo(KEY).
+This expression can only be used as a top level expression.
+It takes a single key expression as an argument and produces either 2 or 4 output scripts, depending on the key.
+A combo() expression always produces a P2PK and P2PKH script, the same as putting the key in both a pk() and a pkh() expression.
+If the key is/has a compressed public key, then P2WPKH and P2SH-P2WPKH scripts are also produced, the same as putting the key in both a wpkh() and sh(wpkh()) expression.
+
+==Test Vectors==
+
+Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, and 1st scripts in additional sub-bullets.
+
+* combo(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)
+** 2103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bdac
+** 76a9149a1c78a507689f6f54b847ad1cef1e614ee23f1e88ac
+** 00149a1c78a507689f6f54b847ad1cef1e614ee23f1e
+** a91484ab21b1b2fd065d4504ff693d832434b6108d7b87
+* combo(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)
+** 4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235ac
+** 76a914b5bd079c4d57cc7fc28ecf8213a6b791625b818388ac
+* combo([01234567]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)
+** 2102d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0ac
+** 76a91431a507b815593dfc51ffc7245ae7e5aee304246e88ac
+** 001431a507b815593dfc51ffc7245ae7e5aee304246e
+** a9142aafb926eb247cb18240a7f4c07983ad1f37922687
+* combo(xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334/*)
+** Child 0
+*** 2102df12b7035bdac8e3bab862a3a83d06ea6b17b6753d52edecba9be46f5d09e076ac
+*** 76a914f90e3178ca25f2c808dc76624032d352fdbdfaf288ac
+*** 0014f90e3178ca25f2c808dc76624032d352fdbdfaf2
+*** a91408f3ea8c68d4a7585bf9e8bda226723f70e445f087
+** Child 1
+*** 21032869a233c9adff9a994e4966e5b821fd5bac066da6c3112488dc52383b4a98ecac
+*** 76a914a8409d1b6dfb1ed2a3e8aa5e0ef2ff26b15b75b788ac
+*** 0014a8409d1b6dfb1ed2a3e8aa5e0ef2ff26b15b75b7
+*** a91473e39884cb71ae4e5ac9739e9225026c99763e6687
+
+Invalid descriptors
+
+* combo() in sh : sh(combo(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+* combo() in wsh : wsh(combo(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+* Script in combo(): combo(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+
+==Backwards Compatibility==
+
+combo() descriptors use the format and general operation specified in [[bip-0380.mediawiki|380]].
+As this is a wholly new descriptor, it is not compatible with any implementation.
+However the scripts produced are standard scripts so existing software are likely to be familiar with them.
+
+==Reference Implementation==
+
+combo() descriptors have been implemented in Bitcoin Core since version 0.17.
diff --git a/bip-0385.mediawiki b/bip-0385.mediawiki
new file mode 100644
index 0000000000..1686ef7da5
--- /dev/null
+++ b/bip-0385.mediawiki
@@ -0,0 +1,75 @@
+
+
+==Abstract==
+
+This document specifies raw() and addr() output script descriptors.
+raw() encapsulates a raw script as a descriptor.
+addr() encapsulates an address as a descriptor.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+In order to make descriptors maximally compatible with scripts in use today, it is useful to be able to wrap any arbitrary output script or an address into a descriptor.
+
+==Specification==
+
+Two new script expressions are defined: raw() and addr().
+
+===raw()===
+
+The raw(HEX) expression can only be used as a top level descriptor.
+As the argument, it takes a hex string representing a Bitcoin script.
+The output script produced by this descriptor is the script represented by HEX.
+
+===addr()===
+
+The addr(ADDR) expression can only be used as a top level descriptor.
+It takes an address as its single argument.
+The output script produced by this descriptor is the output script produced by the address ADDR.
+
+==Test Vectors==
+
+Valid descriptors followed by the scripts they produce.
+
+* raw(deadbeef)
+** deadbeef
+* raw(512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae)
+** 512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae
+* raw(a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87)
+** a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87
+* addr(3PUNyaW7M55oKWJ3kDukwk9bsKvryra15j)
+** a914eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee87
+
+Invalid descriptors
+
+* Non-hex script: raw(asdf)
+* Invalid address: addr(asdf)
+* raw nested in sh: sh(raw(deadbeef))
+* raw nested in wsh: wsh(raw(deadbeef))
+* addr nested in sh: sh(addr(3PUNyaW7M55oKWJ3kDukwk9bsKvryra15j))
+* addr nested in wsh: wsh(addr(3PUNyaW7M55oKWJ3kDukwk9bsKvryra15j))
+
+==Backwards Compatibility==
+
+raw() and addr() descriptors use the format and general operation specified in [[bip-0380.mediawiki|380]].
+As this is a wholly new descriptor, it is not compatible with any implementation.
+The reuse of existing Bitcoin addresses allows for this to be more easily implemented.
+
+==Reference Implementation==
+
+raw() and addr() descriptors have been implemented in Bitcoin Core since version 0.17.
diff --git a/bip-0386.mediawiki b/bip-0386.mediawiki
new file mode 100644
index 0000000000..600d14ea6a
--- /dev/null
+++ b/bip-0386.mediawiki
@@ -0,0 +1,122 @@
+
+
+==Abstract==
+
+This document specifies tr() output script descriptors.
+tr() descriptors take a key and optionally a tree of scripts and produces a P2TR output script.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+Taproot added one additional standard output script format: P2TR.
+These expressions allow specifying those formats as a descriptor.
+
+==Specification==
+
+A new script expression is defined: tr().
+A new expression is defined: Tree Expressions
+
+===Tree Expression===
+
+A Tree Expression (denoted TREE) is an expression which represents a tree of scripts.
+The way the tree is represented in an output script is dependent on the higher level expressions.
+
+A Tree Expression is:
+* Any Script Expression that is allowed at the level this Tree Expression is in.
+* A pair of Tree Expressions consisting of:
+** An open brace {
+** A Tree Expression
+** A comma ,
+** A Tree Expression
+** A closing brace }
+
+===tr()===
+
+The tr(KEY) or tr(KEY, TREE) expression can only be used as a top level expression.
+All key expressions under any tr() expression must create x-only public keys.
+
+tr(KEY) takes a single key expression as an argument and produces a P2TR output script which does not have a script path.
+Each key produced by the key expression is used as the internal key of a P2TR output as specified by [[bip-0341.mediawiki#cite_ref-22-0|BIP 341]].
+Specifically, "If the spending conditions do not require a script path, the output key should commit to an unspendable script path instead of having no script path.
+This can be achieved by computing the output key point as ''Q = P + int(hashTapTweak(bytes(P)))G''."
+
+
+
+tr(KEY, TREE) takes a key expression as the first argument, and a tree expression as the second argument and produces a P2TR output script which has a script path.
+The keys produced by the first key expression are used as the internal key as specified by [[bip-0341.mediawiki#Constructing_and_spending_Taproot_outputs|BIP 341]].
+The Tree expression becomes the Taproot script tree as described in BIP 341.
+A merkle root is computed from this tree and combined with the internal key to create the Taproot output key.
+
+
+
+===Modified Key Expression===
+
+Key Expressions within a tr() expression must only create x-only public keys.
+Uncompressed public keys are not allowed, but compressed public keys would be implicitly converted to x-only public keys.
+The keys derived from extended keys must be serialized as x-only public keys.
+An additional key expression is defined only for use within a tr() descriptor:
+
+* A 64 hex character string representing an x-only public key
+
+==Test Vectors==
+
+Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed.
+
+* tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
+** 512077aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11
+* tr(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)
+** 512077aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11
+* tr(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/0/*,pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/1/*))
+** 512078bc707124daa551b65af74de2ec128b7525e10f374dc67b64e00ce0ab8b3e12
+** 512001f0a02a17808c20134b78faab80ef93ffba82261ccef0a2314f5d62b6438f11
+** 512021024954fcec88237a9386fce80ef2ced5f1e91b422b26c59ccfc174c8d1ad25
+* tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,pk(669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0))
+** 512017cf18db381d836d8923b1bdb246cfcd818da1a9f0e6e7907f187f0b2f937754
+* tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,{pk(xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334/0),{{pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL),pk(02df12b7035bdac8e3bab862a3a83d06ea6b17b6753d52edecba9be46f5d09e076)},pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)}})
+** 512071fff39599a7b78bc02623cbe814efebf1a404f5d8ad34ea80f213bd8943f574
+
+Invalid Descriptors
+
+* Uncompressed private key: tr(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)
+* Uncompressed public key: tr(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)
+* tr() nested in wsh: wsh(tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+* tr() nested in sh: sh(tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+* pkh() nested in tr: tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd, pkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))
+
+==Backwards Compatibility==
+
+tr() descriptors use the format and general operation specified in [[bip-0380.mediawiki|380]].
+As these are a set of wholly new descriptors, they are not compatible with any implementation.
+However the scripts produced are standard scripts so existing software are likely to be familiar with them.
+
+Tree Expressions are largely incompatible with existing script expressions due to the restrictions in those expressions.
+As of 2021-06-27, the only allowed script expression that can be used in a tree expression is pk().
+However there will be future BIPs that specify script expressions that can be used in tree expressions.
+
+==Reference Implementation==
+
+tr() descriptors have been implemented in Bitcoin Core since version 22.0.
diff --git a/bip-0387.mediawiki b/bip-0387.mediawiki
new file mode 100644
index 0000000000..0f8c88d3a7
--- /dev/null
+++ b/bip-0387.mediawiki
@@ -0,0 +1,101 @@
+
+
+==Abstract==
+
+This document specifies multi_a() and sortedmulti_a() output script descriptors.
+Like BIP 383's multi() and sortedmulti(), both functions take a threshold and one
+or more public keys and produce a multisig script. The primary distinction is that multi_a()
+and sortedmulti_a() only produce tapscripts and are only allowed in a tapscript context.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+The most common complex script used in Bitcoin is a threshold multisig.
+These expressions allow specifying multisig scripts as a descriptor.
+
+==Specification==
+
+Two new script expressions are defined: multi_a() and sortedmulti_a().
+Both expressions produce the scripts of the same template and take the same arguments.
+They are written as multi_a(k,KEY_1,KEY_2,...,KEY_n).
+k is the threshold - the number of keys that must sign the input for the script to be valid.
+KEY_1,KEY_2,...,KEY_n are the key expressions for the multisig. k must be less than or equal to n.
+
+multi_a() and sortedmulti_a() expressions can only be used inside of a tr() descriptor.
+The maximum number of keys is 999.
+
+The output script produced also depends on the value of k. If k is less than or equal to 16:
+
+KEY_1 OP_CHECKSIG KEY_2 OP_CHECKSIGADD ... KEY_n OP_CHECKSIGADD k OP_NUMEQUAL
+
+
+===sortedmulti_a()===
+
+The only change for sortedmulti_a() is that the x-only public keys are sorted lexicographically prior to the creation of the output script.
+This sorting is on the keys that are to be put into the output script, i.e. after all extended keys are derived.
+
+===Multiple Extended Keys===
+
+When one or more of the key expressions in a multi_a() or sortedmulti_a() expression are extended keys, the derived keys use the same child index.
+This changes the keys in lockstep and allows for output scripts to be indexed in the same way that the derived keys are indexed.
+
+==Test Vectors==
+
+Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed.
+
+* tr(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,multi_a(1,KzoAz5CanayRKex3fSLQ2BwJpN7U52gZvxMyk78nDMHuqrUxuSJy))
+** 5120eb5bd3894327d75093891cc3a62506df7d58ec137fcd104cdd285d67816074f3
+* tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,multi_a(1,669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0))
+** 5120eb5bd3894327d75093891cc3a62506df7d58ec137fcd104cdd285d67816074f3
+* tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))
+** 51202eea93581594a43c0c8423b70dc112e5651df63984d108d4fc8ccd3b63b4eafa
+* tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,sortedmulti_a(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))
+** 512016fa6a6ba7e98c54b5bf43b3144912b78a61b60b02f6a74172b8dcb35b12bc30
+* tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,sortedmulti_a(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/0/*))
+** 5120abd47468515223f58a1a18edfde709a7a2aab2b696d59ecf8c34f0ba274ef772
+** 5120fe62e7ed20705bd1d3678e072bc999acb014f07795fa02cb8f25a7aa787e8cbd
+** 51201311093750f459039adaa2a5ed23b0f7a8ae2c2ffb07c5390ea37e2fb1050b41
+* tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(2,xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0,xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt/1/2/*,xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi/10/20/30/40/*'))
+** 5120e4c8f2b0a7d3a688ac131cb03248c0d4b0a59bbd4f37211c848cfbd22a981192
+** 5120827faedaa21e52fca2ac83b53afd1ab7d4d1e6ce67ff42b19f2723d48b5a19ab
+** 5120647495ed09de61a3a324704f9203c130d655bf3141f9b748df8f7be7e9af55a4
+
+Invalid descriptors
+
+* Unsupported top level: multi_a(1,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0)
+* Unsupported sh() context: sh(multi_a(1,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0))
+* Unsupported wsh() context: wsh(multi_a(1,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0))
+* Invalid threshold: tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(a,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+* Threshold of 0: tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(0,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
+* Uncompressed pubkey: tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(1,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235))
+* Threshold larger than keys: tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(3,L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss))
+
+==Backwards Compatibility==
+
+multi_a() and sortedmulti_a() descriptors use the format and general operation specified in [[bip-0380.mediawiki|380]].
+As these are wholly new descriptors, they are not compatible with any implementation.
+However, the scripts produced are standard scripts, so existing software are likely to be familiar with them.
+
+==Reference Implementation==
+
+multi_a() and sortedmulti_a() descriptors were implemented in Bitcoin Core in https://github.com/bitcoin/bitcoin/pull/24043 and have been available since version 24.0.
diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki
new file mode 100644
index 0000000000..cc9de4273e
--- /dev/null
+++ b/bip-0388.mediawiki
@@ -0,0 +1,350 @@
+
+
+== Abstract ==
+
+Software wallets and hardware signing devices typically partition funds into separate "accounts". When signing or visualizing a transaction, aggregate flows of funds of all accounts affected by the transaction may (and should) be displayed to the user.
+
+Wallet policies build on top of output script descriptors to represent such accounts in a compact, reviewable way.
+An account encompasses a logical group of receive and change addresses, and each wallet policy represents all descriptors necessary to describe an account in its entirety.
+
+We simplify the language to suit devices with limited memory, where even keeping the entire descriptor in memory could be a major hurdle, by reducing the generality of descriptors to just the essential features and by separating the extended pubkeys and other key information from the descriptor.
+
+This results in a more compact representation and simplifies the inspection of the policy by the user.
+
+The compilation of wallet policies to the corresponding descriptor is trivial, and the reverse process is easy for supported descriptors, because the language is kept similar to that of output script descriptors.
+
+== Copyright ==
+
+This BIP is licensed under the BSD 2-clause license.
+
+== Motivation ==
+
+''[[bip-0380.mediawiki|Output Script Descriptors]]'' were introduced in Bitcoin Core as a way to represent collections of output scripts. It is a general and flexible language, designed to catch all the possible use-cases of bitcoin wallets (that is, if you know the script and you have the necessary keys, it will be possible to sign transactions with any descriptor-based software wallet).
+
+Unfortunately, descriptors are not a perfect match for the typical usage of hardware signing devices (often also called ''hardware wallets''). Most of them have some of the following limitations when compared to a general-purpose machine running Bitcoin Core:
+
+* they are embedded devices with limited RAM, and computational power;
+* they cannot import additional private keys (that is, they can only sign with keys derived from a single seed via [[bip-0032.mediawiki|BIP-32]]);
+* they have limited storage, or they might not have persistent storage at all (''stateless design'').
+
+Moreover, other limitations like the limited size of the screen might affect what design choices are available in practice. Therefore, minimizing the amount of information shown on-screen is important for a good user experience. The ability for the user to completely validate on-screen the kind of script used (and each of the involved keys) is crucial for secure usage, as the machine that is interacting with the hardware signer (and running the software wallet) is considered untrusted.
+
+A more native, compact representation of the wallet receive and change addresses might also benefit the UX of software wallets when they use descriptors (possibly with miniscript) for representing complex locking conditions.
+
+We remark that wallet policies are not related to the ''policy'' language, a higher level language that can be compiled to [[bip-0379.md|miniscript]].
+
+=== Security, privacy and UX concerns for hardware signing devices ===
+
+The usage of complex scripts presents challenges in terms of both security and user experience for a hardware signing device.
+
+==== Security issues ====
+
+Hardware signing devices strive to guarantee that no action can be performed without the user’s consent as long as the user correctly verifies the information that is shown on the device’s screen before approving.
+
+This must hold even in scenarios where the attacker has full control of the machine that is connected to the signing device, and can execute arbitrary requests, or tamper with the legitimate user's requests.
+
+Therefore, it is not at all trivial to allow complex scripts, especially if they contain keys that belong to third parties.
+The hardware signing device must guarantee that the user knows precisely what "policy" is being used to spend the funds, and that any "unspent" funds (if any) that is sent to a change address will be protected by the same policy.
+
+This makes it impossible for an attacker to surreptitiously modify the policy, therefore stealing or burning the user's funds.
+
+==== Avoiding key reuse ====
+
+Reusing public keys within a script is a source of malleability when using miniscript policies, which has potential security implications.
+
+Reusing keys across different UTXOs harms user privacy by allowing external parties to link these UTXOs to the same entity once they are spent.
+
+By constraining the derivation path patterns to have a uniform structure, wallet policies prevent key reuse among the same or different UTXOs of the same account.
+
+It is strongly recommended to avoid key reuse across accounts. Distinct public keys per account can be guaranteed by using distinct hardened derivation paths. This specification does not mandate hardened derivation in order to maintain compatibility with existing deployments that do not adhere to this recommendation.
+
+It is out of scope for this document to guarantee that users do not reuse extended public keys among different wallet accounts. This is still very important, but the responsibility is left to the users and their software wallet.
+
+==== UX issues ====
+
+Miniscript (and taproot trees) allow substantially more complex spending policies. It is a challenge to ensure that the user can practically verify such spending policies per the screen.
+
+We set two fundamental design goals:
+* Minimize the amount of information that is shown on screen - so that the user can actually validate it.
+* Minimize the number of times the user has to validate such information.
+
+Designing a secure protocol for the coordination of a descriptor wallet among distant parties is also a challenging problem that is out of the scope of this document. See [[bip-0129.mediawiki|BIP-129 (Bitcoin Secure Multisig Setup)]] for an approach designed for multisig wallets. Regardless of the approach, the ability for the user to carefully verify all the details of the spending policies using the hardware signer's screen is a prerequisite for security in adversarial environments.
+
+=== Policy registration as a solution ===
+
+A solution to address the security concerns, and part of the UX concerns, is to have a registration flow for the wallet policy in the hardware signing device. The ''wallet policy'' must contain enough information to generate all the relevant addresses/scripts, and for the hardware signing device to identify the keys that it controls and that are needed to spend the funds sent to those addresses.
+
+Before a new policy is used for the first time, the user will register a wallet policy into the hardware device. While the details of the process are out of scope in this document, the flow should be something similar to the following:
+
+# The software wallet initiates a ''wallet policy registration'' on the hardware signing device; the information should include the wallet policy, but also a unique ''name'' that identifies the policy.
+# The device shows the wallet policy to the user using the secure screen.
+# After inspecting the policy and comparing it with a trusted source (for example a printed backup), the user approves the policy.
+# If stateful, the hardware signing device persists the policy in its permanent memory; if stateless, it returns a "proof of registration".
+
+The '''proof of registration''' will allow the hardware signer to verify that a certain policy was indeed previously approved by the user, and is therefore safe to use without repeating the expensive user verification procedure. The details of how to create a proof of registration are out of scope for this document; using a Message Authentication Code on a hash committing to the wallet policy, its name and any additional metadata is an effective solution if correctly executed.
+
+Once a policy is registered, the hardware signing device can perform the typical operations securely:
+* generating receive and change addresses;
+* showing addresses on the secure screen;
+* sign transactions spending from a wallet, while correctly identifying change addresses and computing the transaction fees.
+
+Before any of the actions mentioned above, the hardware signing device will retrieve the policy from its permanent storage if stateful; if stateless it will validate the proof of registration before using the wallet policy provided by the client.
+
+Once the previously registered policy is correctly identified and approved by the user (for example by showing its name), and as long as the policy registration was executed securely, hardware signing devices can provide a user experience similar to the usual one for single-signature transactions.
+
+=== Avoiding blowup in descriptor size ===
+
+While reusing a pubkey in different branches of a miniscript is explicitly forbidden by miniscript (as it has certain negative security implications), it is still reasonable to reuse the same xpub in multiple places, albeit with different final steps of derivation (so that the actual pubkeys that are used in the script are indeed different).
+
+In fact, there are many reasonable spending policies with a quadratic size in the number of participants. For example, using Taproot, a 3-of-5 threshold wallet could use:
+* a key path with a 5-of-5 [[bip-0327.mediawiki|MuSig2]] aggregated key
+* a script tree with 11 leaves:
+** 10 different scripts using a 3-of-3 MuSig2 aggregated key, plus
+** a final leaf with a fallback 3-of-5 multisig using multi_a (in case interactive signing is not available).
+
+With each xpub being 118 bytes long, the repetition of xpubs makes the descriptor become extremely large.
+
+Replacing the common part of the key with a short key placeholder and organizing all the key expressions in a separate list helps to keep the size of the wallet policy small, which is crucial to allow human inspection during the registration flow.
+
+== Specification ==
+
+This section formally defines wallet policies, and how they relate to output script descriptors.
+
+=== Formal definition ===
+
+A ''wallet policy'' is composed by a ''wallet descriptor template'', together with a vector of ''key information items''.
+
+==== Wallet descriptor template ====
+
+A ''wallet descriptor template'' is a SCRIPT expression.
+
+SCRIPT expressions:
+* sh(SCRIPT) (top level only): P2SH embed the argument.
+* wsh(SCRIPT) (top level or inside sh only): P2WSH embed the argument.
+* pkh(KEY) (not inside tr): P2PKH output for the given public key.
+* wpkh(KEY) (top level or inside sh only): P2WPKH output for the given compressed pubkey.
+* multi(k,KEY_1,KEY_2,...,KEY_n) (inside sh or wsh only): ''k''-of-''n'' multisig script.
+* sortedmulti(k,KEY_1,KEY_2,...,KEY_n) (inside sh or wsh only): ''k''-of-''n'' multisig script with keys sorted lexicographically in the resulting script.
+* tr(KEY) or tr(KEY,TREE) (top level only): P2TR output with the specified key as internal key, and optionally a tree of script paths.
+* any valid miniscript template (inside wsh or tr only).
+
+See [[bip-0379.md|BIP-379]] for a precise specification of all the valid miniscript SCRIPT expressions.
+
+TREE expressions:
+* any SCRIPT expression
+* An open brace {, a TREE expression, a comma ,, a TREE expression, and a closing brace }
+
+
+KEY expressions consist of
+* a KP expression
+* ''always'' followed by either:
+** the string /**, or
+** a string of the form //*, for two distinct decimal numbers NUM representing unhardened derivations, or
+** any of the additional, implementation-specific valid derivation path patterns (see [[#optional-derivation-paths|Optional derivation paths]] below).
+
+KP expressions (key placeholders) consist of either:
+* a KI (key index) expression, or
+* (only inside tr): musig(KI_1,KI_2,...,KI_n)
+
+A KI (key index) expression consists of:
+* a single character @
+* followed by a non-negative decimal number, with no leading zeros (except for @0)
+
+The /** in the placeholder template represents commonly used paths for receive/change addresses, and is equivalent to <0;1>/*.
+
+Note that while [[bip-0389.mediawiki|BIP-389]] allows multipath / expressions with an arbitrary number of options, this specification restricts it to exactly 2 choices (with the typical meaning of receive/change addresses).
+
+SCRIPT, TREE and KEY expressions map directly to the corresponding concepts defined in [[bip-0380.mediawiki|BIP-380]] for output script descriptors.
+
+Each KEY expression always corresponds to a precise public key in the final bitcoin Script. Therefore, all the derivation steps in the BIP-32 hierarchy are included in a KEY expression.
+
+Each KP (key placeholder) expression, on the other hand, maps to the root of all the corresponding public keys for all the possible UTXOs that belong to the account represented in the wallet policy. Therefore, no derivation steps are allowed in a KP expression.
+
+A KI (key index) @i for some number ''i'' represents the ''i''-th key in the vector of key information items (which must be of size at least ''i + 1'', or the wallet policy is invalid).
+
+Note: while descriptor templates for miniscript are not formally defined in this version of the document (pending standardization), it is straightforward to adapt this approach by adding additional SCRIPT expressions.
+
+==== Key information vector ====
+
+Each element of the key origin information vector is a KEY_INFO expression, containing an extended public key, and (optionally) its key origin.
+
+* Optionally, key origin information, consisting of:
+** An open bracket [
+** Exactly 8 hex characters for the fingerprint of the master key from which this key is derived from (see [[bip-0032.mediawiki|BIP-32]] for details)
+** Followed by zero or more /NUM' or /NUM path elements to indicate hardened or unhardened derivation steps between the fingerprint and the xpub that follows
+** A closing bracket ]
+* Followed by the actual key, which is a serialized extended public key (as defined in [[bip-0032.mediawiki|BIP-32]]).
+
+==== Additional rules ====
+
+A wallet policy must have at least one key placeholder and the corresponding key.
+
+The public keys obtained by deserializing elements of the key information vector must be pairwise distinct'''Why must public keys be distinct?''' Reusing pubkeys could be insecure in the context of wallet policies containing [https://bitcoin.sipa.be/miniscript/ miniscript]. Avoiding repeated public keys altogether avoids the problem at the source..
+
+If two KEY are KP//* and KP/
/* for the same key placeholder KP, then the sets {M, N} and {P, Q} must be disjoint. Two musig key placeholders are the same if they have exactly the same set of key indexes (regardless of the order).
+
+Repeated KI expressions are not allowed inside a musig placeholder.
+
+The key information vector should be ordered so that placeholder @i never appears for the first time before an occurrence of @j for some j < i; for example, the first placeholder is always @0, the next one is @1, etc.
+
+=== Descriptor derivation ===
+
+From a wallet descriptor template (and the associated vector of key information items), one can therefore obtain the corresponding multipath descriptor by:
+
+* replacing each key placeholder with the corresponding key origin information;
+* replacing every /** with /<0;1>/*.
+
+For example, the wallet descriptor pkh(@0/**) with key information
+["[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"]
+produces the following multipath descriptor:
+
+pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<0;1>/*)
+
+=== Implementation guidelines ===
+
+It is acceptable to implement only a subset of the possible wallet policies defined by this standard. It is recommended that any limitations are clearly documented.
+
+Implementations can add additional metadata that is stored together with the wallet policy for the purpose of wallet policy registration and later usage. Metadata can be vendor-specific and is out of the scope of this document.
+
+Any implementation in a software wallet that allows wallet policies not matching any of the specifications in [[bip-0044.mediawiki|BIP-44]], [[bip-0049.mediawiki|BIP-49]], [[bip-0084.mediawiki|BIP-84]], [[bip-0086.mediawiki|BIP-86]] (especially if involving external cosigners) should put great care into a process for backing up the wallet policy that represents the account. In fact, unlike standard single-signature scenarios, the seed alone is no longer enough to discover wallet policies with existing funds, and the loss of the backup is likely to lead to permanent loss of funds. Unlike the seed, leaking such backups only affects the privacy of the user, but it does not allow the attacker to steal funds.
+
+=== Optional derivation paths ===
+
+In order to allow supporting legacy derivation schemes (for example, using simply /* instead of the more common //* scheme most software wallets use today), or other schemes that are not covered in this document, implementations might choose to permit additional derivation patterns for the key placeholder (KP) expressions.
+
+However, care needs to be taken in view of the following considerations:
+
+* Allowing derivation schemes with a different length or cardinality in the same wallet policy would make it difficult to guarantee that there are no repeated pubkeys for every possible address generated by the policy. For example, @0/<0;1>/* and @1/* would generate the same pubkeys if the second public key in the key information vector is one of the first two unhardened children of the first public key. This could cause malleability with potential security implications (for example, in policies containing miniscript).
+* Allowing naked pubkeys with no /* suffix (for example a descriptor template like wsh(multi(2,@0,@1/<0;1>/*))) would cause a pubkey to be repeated in every output generated from the policy, which would result in a total loss of privacy.
+
+== Examples ==
+
+In the examples in this section, the vector of key information items is omitted. See the test vectors below for complete examples.
+
+Common single-signature account patterns:
+* pkh(@0/**) (legacy).
+* wpkh(@0/**) (native segwit).
+* sh(wpkh(@0/**)) (nested segwit).
+* tr(@0/**) (taproot single-signature account).
+
+Common multisig schemes:
+* wsh(multi(2,@0/**,@1/**)) - SegWit 2-of-2 multisig, keys in order.
+* sh(sortedmulti(2,@0/**,@1/**,@2/**)) - Legacy 2-of-3 multisig, sorted keys.
+* tr(musig(@0/**,@1/**)) - MuSig2 2-of-2 in the taproot keypath
+
+Some miniscript policies in wsh:
+* wsh(and_v(v:pk(@0/**),or_d(pk(@1/**),older(12960)))) - Trust-minimized second factor, degrading to a single signature after about 90 days.
+* wsh(thresh(3,pk(@0/**),s:pk(@1/**),s:pk(@2/**),sln:older(12960))) - A 3-of-3 wallet that becomes a 2-of-3 if coins are not spent for about 90 days.
+* wsh(or_d(pk(@0/**),and_v(v:multi(2,@1/**,@2/**,@3/**),older(65535)))) - A singlesig wallet with automatic inheritance to a timelocked 2-of-3 multisig of family members.
+
+== Test Vectors ==
+
+=== Valid policies ===
+
+[[bip-0044.mediawiki|BIP-44]], first account
+ Descriptor template: pkh(@0/**)
+ Keys info: ["[6738736c/44'/0'/0']xpub6Br37sWxruYfT8ASpCjVHKGwgdnYFEn98DwiN76i2oyY6fgH1LAPmmDcF46xjxJr22gw4jmVjTE2E3URMnRPEPYyo1zoPSUba563ESMXCeb"]
+ Descriptor: pkh([6738736c/44'/0'/0']xpub6Br37sWxruYfT8ASpCjVHKGwgdnYFEn98DwiN76i2oyY6fgH1LAPmmDcF46xjxJr22gw4jmVjTE2E3URMnRPEPYyo1zoPSUba563ESMXCeb/<0;1>/*)
+
+[[bip-0049.mediawiki|BIP-49]], second account
+ Descriptor template: sh(wpkh(@0/**))
+ Keys info: ["[6738736c/49'/0'/1']xpub6Bex1CHWGXNNwGVKHLqNC7kcV348FxkCxpZXyCWp1k27kin8sRPayjZUKDjyQeZzGUdyeAj2emoW5zStFFUAHRgd5w8iVVbLgZ7PmjAKAm9"]
+ Descriptor: sh(wpkh([6738736c/49'/0'/1']xpub6Bex1CHWGXNNwGVKHLqNC7kcV348FxkCxpZXyCWp1k27kin8sRPayjZUKDjyQeZzGUdyeAj2emoW5zStFFUAHRgd5w8iVVbLgZ7PmjAKAm9/<0;1>/*))
+
+[[bip-0084.mediawiki|BIP-84]], third account
+ Descriptor template: wpkh(@0/**)
+ Keys info: ["[6738736c/84'/0'/2']xpub6CRQzb8u9dmMcq5XAwwRn9gcoYCjndJkhKgD11WKzbVGd932UmrExWFxCAvRnDN3ez6ZujLmMvmLBaSWdfWVn75L83Qxu1qSX4fJNrJg2Gt"]
+ Descriptor: wpkh([6738736c/84'/0'/2']xpub6CRQzb8u9dmMcq5XAwwRn9gcoYCjndJkhKgD11WKzbVGd932UmrExWFxCAvRnDN3ez6ZujLmMvmLBaSWdfWVn75L83Qxu1qSX4fJNrJg2Gt/<0;1>/*)
+
+[[bip-0086.mediawiki|BIP-86]], first account
+ Descriptor template: tr(@0/**)
+ Keys info: ["[6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL"]
+ Descriptor: tr([6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL/<0;1>/*)
+
+[[bip-0048.mediawiki|BIP-48]] P2WSH multisig
+ Descriptor template: wsh(sortedmulti(2,@0/**,@1/**))
+ Keys info: ["[6738736c/48'/0'/0'/2']xpub6FC1fXFP1GXLX5TKtcjHGT4q89SDRehkQLtbKJ2PzWcvbBHtyDsJPLtpLtkGqYNYZdVVAjRQ5kug9CsapegmmeRutpP7PW4u4wVF9JfkDhw", "[b2b1f0cf/48'/0'/0'/2']xpub6EWhjpPa6FqrcaPBuGBZRJVjzGJ1ZsMygRF26RwN932Vfkn1gyCiTbECVitBjRCkexEvetLdiqzTcYimmzYxyR1BZ79KNevgt61PDcukmC7"]
+ Descriptor: wsh(sortedmulti(2,[6738736c/48'/0'/0'/2']xpub6FC1fXFP1GXLX5TKtcjHGT4q89SDRehkQLtbKJ2PzWcvbBHtyDsJPLtpLtkGqYNYZdVVAjRQ5kug9CsapegmmeRutpP7PW4u4wVF9JfkDhw/<0;1>/*,[b2b1f0cf/48'/0'/0'/2']xpub6EWhjpPa6FqrcaPBuGBZRJVjzGJ1ZsMygRF26RwN932Vfkn1gyCiTbECVitBjRCkexEvetLdiqzTcYimmzYxyR1BZ79KNevgt61PDcukmC7/<0;1>/*))
+
+Miniscript: A 3-of-3 that becomes a 2-of-3 after 90 days
+ Descriptor template: wsh(thresh(3,pk(@0/**),s:pk(@1/**),s:pk(@2/**),sln:older(12960)))
+ Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js", "[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2"]
+ Descriptor: wsh(thresh(3,pk([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<0;1>/*),s:pk([b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js/<0;1>/*),s:pk([a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2/<0;1>/*),sln:older(12960)))
+
+Miniscript: A singlesig wallet with automatic inheritance to a timelocked 2-of-3 multisig
+ Descriptor template: wsh(or_d(pk(@0/**),and_v(v:multi(2,@1/**,@2/**,@3/**),older(65535))))
+ Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js", "[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2", "[bb641298/44'/0'/0'/100']xpub6Dz8PHFmXkYkykQ83ySkruky567XtJb9N69uXScJZqweYiQn6FyieajdiyjCvWzRZ2GoLHMRE1cwDfuJZ6461YvNRGVBJNnLA35cZrQKSRJ"]
+ Descriptor: wsh(or_d(pk([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<0;1>/*),and_v(v:multi(2,[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js/<0;1>/*,[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2/<0;1>/*,[bb641298/44'/0'/0'/100']xpub6Dz8PHFmXkYkykQ83ySkruky567XtJb9N69uXScJZqweYiQn6FyieajdiyjCvWzRZ2GoLHMRE1cwDfuJZ6461YvNRGVBJNnLA35cZrQKSRJ/<0;1>/*),older(65535))))
+
+Taproot wallet policy with sortedmulti_a and a miniscript leaf
+ Descriptor template: tr(@0/**,{sortedmulti_a(1,@0/<2;3>/*,@1/**),or_b(pk(@2/**),s:pk(@3/**))})
+ Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "xpub6Fc2TRaCWNgfT49nRGG2G78d1dPnjhW66gEXi7oYZML7qEFN8e21b2DLDipTZZnfV6V7ivrMkvh4VbnHY2ChHTS9qM3XVLJiAgcfagYQk6K", "xpub6GxHB9kRdFfTqYka8tgtX9Gh3Td3A9XS8uakUGVcJ9NGZ1uLrGZrRVr67DjpMNCHprZmVmceFTY4X4wWfksy8nVwPiNvzJ5pjLxzPtpnfEM", "xpub6GjFUVVYewLj5no5uoNKCWuyWhQ1rKGvV8DgXBG9Uc6DvAKxt2dhrj1EZFrTNB5qxAoBkVW3wF8uCS3q1ri9fueAa6y7heFTcf27Q4gyeh6"]
+ Descriptor: tr([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<0;1>/*,{sortedmulti_a(1,xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<2;3>/*,xpub6Fc2TRaCWNgfT49nRGG2G78d1dPnjhW66gEXi7oYZML7qEFN8e21b2DLDipTZZnfV6V7ivrMkvh4VbnHY2ChHTS9qM3XVLJiAgcfagYQk6K/<0;1>/*),or_b(pk(xpub6GxHB9kRdFfTqYka8tgtX9Gh3Td3A9XS8uakUGVcJ9NGZ1uLrGZrRVr67DjpMNCHprZmVmceFTY4X4wWfksy8nVwPiNvzJ5pjLxzPtpnfEM/<0;1>/*),s:pk(xpub6GjFUVVYewLj5no5uoNKCWuyWhQ1rKGvV8DgXBG9Uc6DvAKxt2dhrj1EZFrTNB5qxAoBkVW3wF8uCS3q1ri9fueAa6y7heFTcf27Q4gyeh6/<0;1>/*))})
+
+Taproot MuSig2 3-of-3 in the key path, with three 2-of-2 MuSig2 recovery paths after 90 days in the script paths
+ Descriptor template: tr(musig(@0,@1,@2)/**,{and_v(v:pk(musig(@0,@1)/**),older(12960)),{and_v(v:pk(musig(@0,@2)/**),older(12960)),and_v(v:pk(musig(@1,@2)/**),older(12960))}})
+ Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js", "[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2"]
+ Descriptor: tr(musig([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa,[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js,[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2)/<0;1>/*,{and_v(v:pk(musig([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa,[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js)/<0;1>/*),older(12960)),{and_v(v:pk(musig([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa,[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2)/<0;1>/*),older(12960)),and_v(v:pk(musig([b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js,[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2)/<0;1>/*),older(12960))}})
+
+=== Invalid policies ===
+
+The following descriptor templates are invalid:
+
+* pkh(@0): Key placeholder with no path following it
+* pkh(@0/0/**): Key placeholder with an explicit path present
+* sh(multi(1,@1/**,@0/**)): Key placeholders out of order
+* sh(multi(1,@0/**,@2/**)): Skipped key placeholder @1
+* sh(multi(1,@0/**,@0/**)): Repeated keys with the same path expression
+* sh(multi(1,@0/<0;1>/*,@0/<1;2>/*)): Non-disjoint multipath expressions (@0/1/* appears twice)
+* sh(multi(1,@0/**,xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU/<0;1>/*)): Expression with a non-KP key present
+* pkh(@0/<0;1;2>/*): Solved cardinality > 2
+* tr(musig(@0/**,@1/**)): Derivation before aggregation is not allowed in wallet policies (despite being allowed in [[bip-0390.mediawiki|BIP-390]])
+
+Remark: some of the examples of invalid descriptor templates may be valid via optional extensions.
+
+== Backwards Compatibility ==
+
+The @ character used for key placeholders is not part of the syntax of output script descriptors, therefore any valid descriptor with at least one KEY expression is not a valid descriptor template. Vice versa, any descriptor template with at least one key placeholder is not a valid output script descriptor.
+
+Adoption of wallet policies in software and hardware wallets is opt-in. Conversion from wallet policies to the corresponding descriptors is programmatically extremely easy, and conversion from descriptors to wallet policies (when respecting the required patterns) can be automated. See the reference implementation below for some examples of conversion.
+
+Software wallets are recommended to allow exporting plain descriptors for the purposes of interoperability with software not using wallet policies.
+
+== Reference Implementation ==
+
+Wallet policies are implemented in
+* the [https://github.com/LedgerHQ/app-bitcoin-new Ledger bitcoin application] since version 2.1.0;
+* the [https://github.com/digitalbitbox/bitbox02-firmware BitBox02 firmware] since version v9.15.0;
+* [https://github.com/Blockstream/Jade Blockstream Jade] since version v1.0.24, via [https://github.com/ElementsProject/libwally-core libwally-core] v1.0.0.
+* [https://github.com/btcpayserver/btcpayserver BTCPay Server] from version [https://github.com/btcpayserver/btcpayserver/pull/6684 v2.1.1]. (Currently only a limited subset of singlesig and multisig policies)
+* [https://github.com/MetacoSA/NBitcoin/ NBitcoin] through Miniscript.Parse.
+
+For development and testing purposes, we provide a [[bip-0388/wallet_policies.py|Python 3.7 reference implementation]] of simple classes to handle wallet policies, and the conversion to/from output script descriptors.
+The reference implementation is for demonstration purposes only and not to be used in production environments.
+
+== Change Log ==
+
+* '''1.1.0''' (2024-11):
+** Added support for musig key placeholders in descriptor templates.
+* '''1.0.0''' (2024-05):
+** Initial version.
+
+== Footnotes ==
+
+
+
+== Acknowledgments ==
+
+The authors would like to thank the people who provided feedback in the bitcoin-dev list, and in person.
diff --git a/bip-0388/wallet_policies.py b/bip-0388/wallet_policies.py
new file mode 100755
index 0000000000..43aa54fa50
--- /dev/null
+++ b/bip-0388/wallet_policies.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python3
+
+from typing import Iterable, List, Mapping, Tuple, Generator
+
+
+def find_all(text: str, pattern: str, start: int = 0) -> Generator[int, None, None]:
+ """Generates all the positions of `pattern` as a substring of `text`, starting from index at least `start`."""
+ while True:
+ start = text.find(pattern, start)
+ if start == -1:
+ return
+ yield start
+ start += len(pattern)
+
+
+def find_first(text: str, start_pos: int, patterns: Iterable[str]) -> int:
+ """Returns the position of the first occurrence of any of the elements in `patterns` as a substring of `text`,
+ or -1 if none of the patterns is found."""
+ matches = (text.find(x, start_pos) for x in patterns)
+ return min((x for x in matches if x != -1), default=-1)
+
+
+def find_key_end_position(desc: str, start_pos: int) -> int:
+ """Assuming that `start_pos` is the beginning of a KEY expression (and not musig), finds the position of the end
+ of the key expression, excluding (if present) the final derivation steps after an xpub. This is the information
+ that goes into an entry of the vector of key information of the wallet policy."""
+
+ has_orig_info = True if desc[start_pos] == '[' else False
+
+ if has_orig_info:
+ closing_bracket_pos = desc.find("]", start_pos)
+ if closing_bracket_pos == -1:
+ raise Exception("Invalid descriptor: could not find closing ']'")
+ key_pos_start = closing_bracket_pos + 1
+ else:
+ key_pos_start = start_pos
+
+ # find the earliest occurrence of ",", a ")" or a "/" (it must find at least 1)
+ end_pos = find_first(desc, key_pos_start, [",", ")", "/"])
+ if end_pos == -1:
+ raise Exception(
+ "Invalid descriptor: cannot find the end of key expression")
+
+ return end_pos
+
+
+class WalletPolicy(object):
+ """Simple class to represent wallet policies. This is a toy implementation that does not parse the descriptor
+ template. A more robust implementation would build the abstract syntax tree of the template and of the descriptor,
+ allowing one to detect errors, and manipulate it semantically instead of relying on string manipulation."""
+
+ def __init__(self, descriptor_template: str, keys_info: List[str]):
+ self.descriptor_template = descriptor_template
+ self.keys_info = keys_info
+
+ def to_descriptor(self) -> str:
+ """Converts a wallet policy into the descriptor (with the / syntax, if present)."""
+
+ desc = self.descriptor_template
+
+ # replace each "/**" with "/<0;1>/*"
+ desc = desc.replace("/**", "/<0;1>/*")
+
+ # process all the @N expressions in decreasing order. This guarantees that string replacements
+ # works as expected (as any prefix expression is processed after).
+ for i in reversed(range(len(self.keys_info))):
+ desc = desc.replace(f"@{i}", self.keys_info[i])
+
+ # there should not be any remaining "@" expressions
+ if desc.find("@") != -1:
+ raise Exception("Invalid descriptor template: contains invalid key index")
+
+ return desc
+
+ @classmethod
+ def from_descriptor(cls, descriptor: str) -> 'WalletPolicy':
+ """Converts a "reasonable" descriptor (with the / syntax) into the corresponding wallet policy."""
+
+ # list of pairs of integers, where the tuple (m,n) with m < n means a key expression starts at
+ # m (inclusive) and at n (exclusive)
+ key_expressions: List[Tuple[int, int]] = []
+
+ key_with_orig_pos_start = None
+
+ def parse_key_expressions(only_first=False, handle_musig=False):
+ # Starting at the position in `key_with_orig_pos_start`, parses a number of key expressions, and updates
+ # the `key_expressions` array accordingly.
+ # If `only_first` is `True`, it stops after parsing a single key expression.
+ # If `handle_musig` is `True`, and a key expression is a `musig` operator, it recursively parses
+ # the keys in the musig expression. `musig` inside `musig` is not allowed.
+
+ nonlocal key_with_orig_pos_start
+ if key_with_orig_pos_start is None:
+ raise Exception("Unexpected error")
+
+ while True:
+ if handle_musig and descriptor[key_with_orig_pos_start:].startswith("musig"):
+ closing_parenthesis_pos = find_first(
+ descriptor, key_with_orig_pos_start, [")"])
+ if closing_parenthesis_pos == -1:
+ raise Exception(
+ "Invalid descriptor: musig without closing parenthesis")
+ key_with_orig_pos_start = key_with_orig_pos_start + \
+ len("musig(")
+ parse_key_expressions(
+ only_first=False, handle_musig=False)
+
+ key_pos_end = closing_parenthesis_pos + 1
+ else:
+ key_pos_end = find_key_end_position(
+ descriptor, key_with_orig_pos_start)
+ key_expressions.append(
+ (key_with_orig_pos_start, key_pos_end))
+
+ if descriptor[key_pos_end] == '/':
+ # find the actual end (comma or closing parenthesis)
+ key_pos_end = find_first(
+ descriptor, key_pos_end, [",", ")"])
+ if key_pos_end == -1:
+ raise Exception(
+ "Invalid descriptor: unterminated key expression")
+
+ if descriptor[key_pos_end] == ',':
+ # There is another key expression, repeat from after the comma
+ key_with_orig_pos_start = key_pos_end + 1
+ else:
+ break
+
+ if only_first:
+ break
+
+ # operators for which the KEY is the first argument
+ operators_key_first = ["pk", "pkh", "pk_h", "pk_k", "tr"]
+ # operators for which the KEY is everything except the first argument
+ operators_key_all_but_first = [
+ "multi", "sortedmulti", "multi_a", "sortedmulti_a"]
+ for op in operators_key_first + operators_key_all_but_first:
+ for op_pos_start in find_all(descriptor, op + "("):
+
+ # ignore if not a whole word (otherwise "sortedmulti" would be found inside "multi")
+ if op_pos_start > 0 and 'a' <= desc[op_pos_start - 1] <= 'z':
+ continue
+
+ if op in operators_key_all_but_first:
+ # skip the first argument (we know it's not a KEY expression, so it does not have a comma)
+ first_comma_pos = descriptor.find(",", op_pos_start)
+ if first_comma_pos == -1:
+ raise Exception(
+ "Invalid descriptor: multi, sortedmulti, multi_a and sortedmulti_a must have at least two arguments")
+ key_with_orig_pos_start = 1 + first_comma_pos
+ else:
+ # other operators, the first argument is already a KEY expression
+ key_with_orig_pos_start = op_pos_start + len(op) + 1
+
+ only_first = op in operators_key_first
+ parse_key_expressions(
+ only_first=only_first, handle_musig=True)
+
+ result: List[str] = []
+ keys: List[str] = []
+ keys_to_idx: Mapping[str, int] = {}
+
+ prev_end = 0
+ for start, end in sorted(key_expressions):
+ result.append(descriptor[prev_end:start])
+
+ key = descriptor[start:end]
+ if key not in keys_to_idx:
+ idx = len(keys)
+ keys.append(key)
+ keys_to_idx[key] = idx
+ else:
+ idx = keys_to_idx[key]
+ result.append(f"@{idx}")
+
+ prev_end = end
+
+ result.append(descriptor[prev_end:])
+
+ return cls("".join(result), keys)
+
+
+if __name__ == "__main__":
+ descriptors = [
+ "pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/**)",
+ "wsh(multi(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/**,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/**))",
+ "tr([12345678/44'/0'/0']xpub6BVZ6JrGsWsUbpP74S8rnz13hVFDtYtKyuTTEYPNSF6GFpDFpL1YXWg3BpwpUWAnsZZ7Qe3XKz7GL3BEx3RQVq61cxqSkjceq25S1xFKFVa,{pk(xpub6AGdromjXf5yf3m7ndaCoR9Ac3UjwTvQ7QQkZoyoh2vfGE9i1AwB2vCbvjTpBL1KRERUsGszg63SVNXsHZU3CiykQqtZPrdXKMdaG2vs6uu),pk(xpub6AnhdkteWC4kPQvkY3QQXGmDCMfmFoYzEQ7FwRFa4BQ1a22k4VL4BD3Jdcog2Sf2KzBscXXAdPRMgjCBDeq6bAryqnMaWX2FaVUGPxWMLDh)})",
+ "tr(xpub6AEWqA1MNRzBBXenkug4NtNguDKTNcXoKQj8fU9VQyid38yikruFRffjoDm9UEaHGEJ6jQxjYdWWZRxR7Xy5ePrQNjohXJuNzkRNSiiBUcE,sortedmulti_a(2,[11223344/44'/0'/0']xpub6AyJhEKxcPaPnYNuA7VBeUQ24v6mEzzPSX5AJm3TSyg1Zsti7rnGKy1Hg6JAdXKF4QUmFZbby9p97AjBNm2VFCEec2ip5C9JntyxosmCeMW,xpub6AQVHBgieCHpGo4GhpGAo4v9v7hfr2Kr4D8ZQJqJwbEyZwtW3pWYSLRQyrNYbTzpoq6XpFtaKZGnEGUMtiydCgqsJDAZNqs9L5QDNKqUBsV))",
+ "tr([11111111/44'/0'/0']xpub6CLZSUDtcUhJVDoPSY8pSRKi4W1RSSLBgwZ2AYmwTH9Yv5tPVFHZxJBUQ27QLLwHej6kfo9DQQbwaHmpXsQq59CjtsE2gNLHmojwgMrsQNe/**,{and_v(v:pk([22222222/44'/0'/0']xpub6CiztfGsUxmpwkWe6gvz8d5VHyFLDoiPpeUfWmQ2vWAhQL3Z1hhEc6PE4irFs4bzjS7dCB4yyinaubrCpFJq4bcKGCD4jjqTxaWiKAJ7mvJ/**),older(52596)),multi_a(2,[33333333/44'/0'/0']xpub6DTZd6od7is2wxXndmE7zaUifzFPwVKshVSGEZedfTJtUjfLyhy4hgCW15hvxRpGaDmtiFoJKaCEaSRfXrQBuYRx18zwquy46dwBsJnsrz2/**,[44444444/44'/0'/0']xpub6BnK4wFbPeLZM4VNjoUA4yLCru6kCT3bhDJNBhbzHLGp1fmgK6muz27h4drixJZeHG8vSS5U5EYyE3gE8ozG94iNg3NDYE8M5YafvhzhMR9/**)})",
+ "tr(musig([33333333/44'/0'/0']xpub6DTZd6od7is2wxXndmE7zaUifzFPwVKshVSGEZedfTJtUjfLyhy4hgCW15hvxRpGaDmtiFoJKaCEaSRfXrQBuYRx18zwquy46dwBsJnsrz2,[44444444/44'/0'/0']xpub6BnK4wFbPeLZM4VNjoUA4yLCru6kCT3bhDJNBhbzHLGp1fmgK6muz27h4drixJZeHG8vSS5U5EYyE3gE8ozG94iNg3NDYE8M5YafvhzhMR9)/**,{and_v(v:pk([22222222/44'/0'/0']xpub6CiztfGsUxmpwkWe6gvz8d5VHyFLDoiPpeUfWmQ2vWAhQL3Z1hhEc6PE4irFs4bzjS7dCB4yyinaubrCpFJq4bcKGCD4jjqTxaWiKAJ7mvJ/**),older(52596)),pk([11111111/44'/0'/0']xpub6CLZSUDtcUhJVDoPSY8pSRKi4W1RSSLBgwZ2AYmwTH9Yv5tPVFHZxJBUQ27QLLwHej6kfo9DQQbwaHmpXsQq59CjtsE2gNLHmojwgMrsQNe/**)})",
+ ]
+
+ for desc in descriptors:
+ # Demoes the conversion from a "sane" descriptor to a wallet policy
+ print(f"Descriptor:\n{desc}")
+ wp = WalletPolicy.from_descriptor(desc)
+ print(f"Policy descriptor template:\n{wp.descriptor_template}")
+ print(f"Keys:\n{wp.keys_info}")
+ print("======================================================\n")
+
+ # Converting back to descriptors also works, as long as we take care of /**
+ assert wp.to_descriptor().replace("/<0;1>/*", "/**") == desc
diff --git a/bip-0389.mediawiki b/bip-0389.mediawiki
new file mode 100644
index 0000000000..6c88a89aff
--- /dev/null
+++ b/bip-0389.mediawiki
@@ -0,0 +1,110 @@
+
+
+==Abstract==
+
+This document specifies a modification to Key Expressions of Descriptors that are described in BIP 380.
+This modification allows Key Expressions to indicate BIP 32 derivation path steps that can have multiple values.
+
+==Copyright==
+
+This BIP is licensed under the BSD 2-clause license.
+
+==Motivation==
+
+Descriptors can describe the scripts that are used in a wallet, but wallets often require at least two descriptors for all of the scripts that they watch for.
+Wallets typically have one descriptor for producing receiving addresses, and the other for change addresses.
+These descriptors are often extremely similar - they produce the same types of scripts, derive keys from the same master key, and use derivation paths that are almost identical.
+The only differences are in the derivation path where one of the steps will be different between the descriptors.
+Thus it is useful to have a notation to represent both descriptors as a single descriptor where one of the derivation steps is a pair of values.
+
+==Specification==
+
+For extended keys and their derivations paths in a Key Expression, BIP 380 states:
+
+* xpub encoded extended public key or xprv encoded extended private key (as defined in BIP 32)
+** Followed by zero or more /NUM or /NUMh path elements indicating BIP 32 derivation steps to be taken after the given extended key.
+** Optionally followed by a single /* or /*h final step to denote all direct unhardened or hardened children.
+
+This is modified to state:
+
+* xpub encoded extended public key or xprv encoded extended private key (as defined in BIP 32)
+** Followed by zero or more /NUM (may be followed by h, H, or ' to indicate a hardened step) path elements indicating BIP 32 derivation steps to be taken after the given extended key.
+** Followed by zero or one / (each NUM may be followed by h, H, or ' to indicate a hardened step) path element indicating a tuple of BIP 32 derivation steps to be taken after the given extended key.
+*** Followed by zero or more ;NUM (may be followed by h, H, or ' to indicate a hardened step) additional tuple values of BIP 32 derivation steps
+*** Followed by a single >/
+** Followed by zero or more /NUM (may be followed by h, H, or ' to indicate a hardened step) path elements indicating BIP 32 derivation steps to be taken after the given extended key.
+** Optionally followed by a single /* (may be followed by h, H, or ' to indicate a hardened step) final step to denote all direct unhardened or hardened children.
+
+When a / is encountered, parsers should account for a presence of multiple descriptors where the first descriptor uses the first NUM, and a second descriptor uses the second NUM, and so on, until each NUM is accounted for in the production of public keys, scripts, and addresses, as well as descriptor import and export operations.
+Descriptors that contain multiple Key Expressions that each have a / must have tuples of exactly the same length so that they are derived in lockstep in the same way that /* paths in multiple Key expressions are handled.
+Duplicate NUMs within a tuple are not allowed.
+
+The common use case for this is to represent descriptors for producing receiving and change addresses.
+When interpreting for this use case, wallets should use the first descriptor for producing receiving addresses, and the second descriptor for producing change addresses.
+For this use case, the element will commonly be the value /<0;1>
+
+Note that only one / specifier is allowed in a Key Expression.
+
+==Test Vectors==
+
+Valid multipath descriptors followed by the descriptors they expand into as sub-bullets
+
+* pk(xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/<0;1>)
+** pk(xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0)
+** pk(xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/1)
+* pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/<2147483647h;0>/0)
+** pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647h/0)
+** pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/0/0)
+* wpkh([ffffffff/13h]xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/<1;3>/2/*
+** wpkh([ffffffff/13h]xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/1/2/*)
+** wpkh([ffffffff/13h]xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/3/2/*)
+* multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<1;2>/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/<3;4>/0/*)
+** multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/3/0/*)
+** multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/2/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/4/0/*)
+* pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0;1;2>)
+** pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0)
+** pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1)
+** pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/2)
+* sh(multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<1;2;3>/0/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/*,xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/<3;4;5>/*))
+** sh(multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/0/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/*,xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/3/*))
+** sh(multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/2/0/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/*,xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/4/*))
+** sh(multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3/0/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/*,xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/5/*))
+
+Invalid descriptors
+
+* Multiple multipath specifiers: pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/<0;1>/<2;3>)
+* Multipath specifier in origin: pkh([deadbeef/<0;1>]xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0)
+* Multipath specifiers of mismatched lengths: tr(xpub661MyMwAqRbcF3yVrV2KyYetLMYA5mCbv4BhrKwUrFE9LZM6JRR1AEt8Jq4V4C8LwtTke6YEEdCZqgXp85YRk2j74EfJKhe3QybQ9kcUjs4/<6;7;8;9>/*,{pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<1;2;3>/0/*),pk(xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/<3;4;5>/*)})
+* Multipath specifiers of mismatched lengths: sh(multi(2,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/<1;2;3>/0/*,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0/*,xprv9s21ZrQH143K3jUwNHoqQNrtzJnJmx4Yup8NkNLdVQCymYbPbJXnPhwkfTfxZfptcs3rLAPUXS39oDLgrNKQGwbGsEmJJ8BU3RzQuvShEG4/0/0/<3;4>/*))
+* Empty multipath specifier: wpkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<>/*)
+* Missing multipath start: wpkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0>/*)
+* Missing multipath end: wpkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0/*)
+* Missing index in multipath specifier: wpkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0;>/*)
+
+==Backwards Compatibility==
+
+This is an addition to the Key Expressions defined in BIP 380.
+Key Expressions using the format described in BIP 380 are compatible with this modification and parsers that implement this will still be able to parse such descriptors.
+However as this is an addition to Key Expressions, older parsers will not be able to understand such descriptors.
+
+This modification to Key Expressions uses two new characters: < and ;.
+These are part of the descriptor character set and so are covered by the checksum algorithm.
+As these are previously unused characters, old parsers will not accidentally mistake them for indicating something else.
+
+This proposal is in contrast to similar proposals such as BIP 88 which allow for multiple derivation indexes in a single element.
+This limitation exists in order to reduce the number of descriptors that are expanded, avoid confusion about how to expand the descriptor, and avoid having expanded descriptors that users are not expecting.
+
+==Reference Implementation==
+
+https://github.com/bitcoin/bitcoin/pull/22838
diff --git a/bip-0390.mediawiki b/bip-0390.mediawiki
new file mode 100644
index 0000000000..185ea93a31
--- /dev/null
+++ b/bip-0390.mediawiki
@@ -0,0 +1,117 @@
+
+
+==Abstract==
+
+This document specifies a musig() key expression for output script descriptors.
+musig() expressions take multiple keys and produce an aggregate public key using BIP 327.
+
+==Copyright==
+
+This BIP is licensed under the Creative Commons CC0 1.0 Universal license.
+
+==Motivation==
+
+BIP 327 introduces the MuSig2 Multi-Signature scheme. It is useful to have a way for keys to be used
+in a MuSig2 aggregate key to be expressed in descriptors so that wallets can more easily use MuSig2.
+
+==Specification==
+
+A new key expression is defined: musig().
+
+===musig(KEY, KEY, ..., KEY)===
+
+The musig(KEY, KEY, ..., KEY) expression can only be used inside of a tr()
+expression as a key expression. It additionally cannot be nested within another musig()
+expression. Repeated participant public keys are not allowed. The aggregate public key is produced
+by using the KeyAgg algorithm on all KEYs specified in the expression after performing all
+specified derivation. As with script expressions, KEY can contain child derivation specified by
+/*. A new aggregate public key will be computed for each child index. Keys must be sorted
+with the KeySort algorithm after all derivation and prior to aggregation'''Why must
+the keys be sorted prior to aggregation?''' Although the descriptor's written form sets an order
+for the keys that could be used for aggregation, the order should not matter as MuSig2 philosophically
+operates over a set of keys, with the order merely being an implementation detail in aggregation
+itself. Requiring sorting of keys prior to aggregation enforces this philosophy as keys can be
+written in the descriptor in any order with the end result still being the same. Furthermore, this
+aids with recovery where the descriptor was not backed up as users will not need to also have
+backed up, or guess, the correct order of keys..
+
+===musig(KEY, KEY, ..., KEY)/NUM/.../*===
+
+musig(KEY, KEY, ..., KEY)/NUM/.../* expressions are also allowed, with the same usage
+restrictions as in the previous section. The aggregate public key
+is first computed as described above, with the keys also being sorted after all derivation and prior
+to aggregation. Then further BIP 32 derivation will be performed on the aggregate public key as described in
+[[bip-0328.mediawiki|BIP 328]]. As there is no aggregate private key,
+only unhardened derivation from the aggregate public key is allowed, and thus the derivation steps
+following the musig() expression cannot contain
+/NUMh or /NUM' derivation steps nor /*h, or /*' child derivation.
+For these musig() expressions, the KEY expressions contained within must be xpubs or derived from
+xpubs, and cannot contain child derivation as specified by a /*, /*', or /*h.
+
+==Test Vectors==
+
+Valid descriptors containing followed by the scripts they produce. Descriptors involving derived child keys
+will have the 0th, 1st, and 2nd scripts listed.
+
+* rawtr(musig(KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74sHUHy8S,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))
+** 5120789d937bade6673538f3e28d8368dda4d0512f94da44cf477a505716d26a1575
+* tr(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))
+** 512079e6c3e628c9bfbce91de6b7fb28e2aec7713d377cf260ab599dcbc40e542312
+* rawtr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*)
+** 51209508c08832f3bb9d5e8baf8cb5cfa3669902e2f2da19acea63ff47b93faa9bfc
+** 51205ca1102663025a83dd9b5dbc214762c5a6309af00d48167d2d6483808525a298
+** 51207dbed1b89c338df6a1ae137f133a19cae6e03d481196ee6f1a5c7d1aeb56b166
+* tr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*,pk(f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9))
+** 51201d377b637b5c73f670f5c8a96a2c0bb0d1a682a1fca6aba91fe673501a189782
+** 51208950c83b117a6c208d5205ffefcf75b187b32512eb7f0d8577db8d9102833036
+** 5120a49a477c61df73691b77fcd563a80a15ea67bb9c75470310ce5c0f25918db60d
+* tr(f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,pk(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*))
+** 512068983d461174afc90c26f3b2821d8a9ced9534586a756763b68371a404635cc8
+** 5120368e2d864115181bdc8bb5dc8684be8d0760d5c33315570d71a21afce4afd43e
+** 512097a1e6270b33ad85744677418bae5f59ea9136027223bc6e282c47c167b471d5
+
+Invalid descriptors
+
+* musig() is not allowed in top-level pk(): pk(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))
+* musig() is not allowed in top-level pkh(): pkh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))
+* musig() is not allowed in wpkh(): wpkh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))
+* musig() is not allowed in combo(): combo(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))
+* musig() is not allowed in sh(wpkh()): sh(wpkh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)))
+* musig() is not allowed in sh(wsh()): sh(wsh(pk(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))))
+* musig() is not allowed in wsh(): wsh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))
+* musig() is not allowed in sh(): sh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))
+* Ranged musig() requires all participants to be xpubs: tr(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)/0/0)
+* Cannot have ranged participants if musig() is also ranged: tr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*)
+* musig() cannot have hardened derivation steps: tr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0h/*)
+* musig() cannot have hardened child derivation: tr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*h)
+
+==Backwards Compatibility==
+
+musig() expressions use the format and general operation specified in
+[[bip-0380.mediawiki|BIP 380]]. As these are a set of wholly new expressions, they are not compatible
+with any implementation. However the keys are produced using a standard process so existing software
+are likely to be familiar with them.
+
+==Rationale==
+
+
+
+==Reference Implementation==
+
+The reference implementation is available in Bitcoin Core [[https://github.com/bitcoin/bitcoin/pull/31244|PR #31244]].
+
+==Acknowledgements==
+
+Thanks to Pieter Wuille, Andrew Poelstra, Sanket Kanjalkar, Salvatore Ingala, and all others who
+participated in discussions on this topic.
diff --git a/bip-0431.mediawiki b/bip-0431.mediawiki
new file mode 100644
index 0000000000..2af0e53c26
--- /dev/null
+++ b/bip-0431.mediawiki
@@ -0,0 +1,291 @@
+
+
+==Abstract==
+
+This document describes pinning problems that can arise from limitations in mempool policy.
+
+It also describes a type of policy with adjusted topology limits which, combined with other policy rules, helps minimize the potential pinning problems. These restrictions simplify the assessment of incentive compatibility of accepting or replacing such transactions, thus helping ensure any replacements are more profitable for the node. Within the context of nodes that implement this policy, fee-bumping is more reliable for users.
+
+==Motivation==
+
+Mempools typically accept and relay transactions that spend outputs from other unconfirmed transactions, but restrict package sizes through ancestor and descendant limits
+https://github.com/bitcoin/bitcoin/blob/632a2bb731804dffe52bd4cbd90bfee352d25ede/doc/policy/mempool-limits.md
+to limit the computational complexity of mempool operations and mitigate Denial of Service attacks.
+
+Users may also create unconfirmed transactions that conflict with -- or are "double spends" of -- each other by spending the same input(s) in both.
+Instead of always keeping the first-seen transaction, many mempools also have some kind of Replace by Fee (RBF) policy
+
+[https://github.com/bitcoin/bitcoin/blob/632a2bb731804dffe52bd4cbd90bfee352d25ede/doc/policy/mempool-replacements.md Bitcoin Core's RBF policy] at the time of writing. It is slightly different from what is described in BIP 125.
+
+to keep the more incentive compatible transaction, i.e. one that would earn a miner more fees. Users utilize these rules when they create higher feerate double-spends (replacements) to expedite confirmation of their transactions.
+
+However, these policies make imperfect trade-offs between incentive compatibility and DoS-resistance. For example, malicious actors may sometimes exploit limitations to prevent incentive-compatible transactions from being accepted or fee-bumped (''pinning'').
+
+Pinning is consequential to contracting protocols in which untrusted parties construct and sign time-sensitive transactions to be broadcast on-chain later
+Posts about pinning in LN and LN-Symmetry:
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020458.html "Bringing a nuke to a knife fight: Transaction introspection to stop RBF pinning"]
+* [https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-April/002639.html "RBF Pinning with Counterparties and Competing Interest"]
+* [https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-June/002758.html "Pinning : The Good, The Bad, The Ugly"]
+* [https://github.com/t-bast/lightning-docs/blob/master/pinning-attacks.md "Pinning Attacks"]
+* [https://gist.github.com/instagibbs/60264606e181451e977e439a49f69fe1 "Eltoo Pinning"]
+.
+When the funds available to be redeemed by each party depend on a transaction confirming within a specific time window, a malicious party may be able to steal money if the honest party cannot get their transaction confirmed. As such, the ability to fee-bump a transaction to entice miners to include it in their blocks is crucial to the security of the protocol.
+
+===RBF pinning through absolute fees===
+
+Imagine that counterparties Alice and Mallory have transactions (or packages) A and B, respectively, which conflict with each other. Alice broadcasts A and Mallory broadcasts B. RBF rules require the replacement transaction pay a higher absolute fee than the aggregate fees paid by all original transactions ([https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md#current-replace-by-fee-policy "Rule 3"]). This means Mallory may increase the fees required to replace B beyond what Alice was planning to pay for A's fees.
+
+1. Adding transaction(s) that descend from B and pay a low feerate (too low to fee-bump B through CPFP)Example: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-December/022216.html.
+
+2. Adding a high-fee descendant of B that also spends from another large, low-feerate mempool transaction (where the fee of the descendant is too low to fee-bump both B and its other parent through CPFP)Example: https://github.com/bitcoin/bitcoin/pull/25038#issuecomment-1320295394.
+
+===RBF pinning through number of conflicts===
+
+RBF rules require that no replacement trigger the removal of more than 100 transactions ([https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md#current-replace-by-fee-policy "Rule 5"]). This number includes the descendants of the conflicted mempool transactions. Mallory can make it more difficult to replace transactions by attaching lots of descendants to them. For example, if Alice wants to batch-replace 5 transactions but each has 21 descendants, her replacement will be rejected regardless of its fees.
+
+===RBF incentive compatibility requirements===
+
+There is currently no effective rule to enforce that a replacement transaction would be more incentive compatible to keep in the mempool. It is difficult to quantify the incentive compatibility of a set of transactions, especially in comparison with another set of transactionshttps://delvingbitcoin.org/t/mempool-incentive-compatibility/553, but the requirement of a feerate increase ([https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md#current-replace-by-fee-policy "Rule 6"]) is far too simplistic.
+
+For example, a user could create a replacement transaction that pays more fees and is higher feerate, but has a low feerate ancestor and would confirm slower than the original transaction. As a result, all transactions signed with SIGHASH_ANYONECANPAY are vulnerable to being replaced by a transaction that will confirm later than the originalhttps://github.com/bitcoin/bitcoin/pull/23121#pullrequestreview-766271585.
+
+===Child fees don't count towards RBF rules===
+
+A transaction must meet all fee-related requirements (Rules 3, 4, 6) alone; its child's fees cannot be used. A ''Package RBF'' policy would allow a transaction's child to be used for its RBF requirements.
+
+In LN Penalty, conflicting commitment transactions signed with the same fees cannot replace each other, even if accompanied by a fee-bumping child. This limitation necessitates the presence of two anchor outputs, allowing both parties to fee-bump either commitment transaction that enters their mempool.
+
+===Package limit pinning and replacing CPFP Carve Out===
+
+Mempool policies limit the number and total virtual size of an unconfirmed transaction's descendants. A fee-bumping child of an unconfirmed transaction (CPFP) may be rejected for exceeding the descendant limit. When a transaction has multiple outputs owned by different parties, a malicious party can prevent the other(s) from CPFPing their transaction by attaching enough descendants to monopolize the descendant limit (''package limit pinning'').
+
+LN commitment transactions rely on CPFP carve out [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-November/016518.html "CPFP Carve-Out for Fee-Prediction Issues in Contracting Applications (eg Lightning)"] to avoid package limit pinning.
+
+There are weaknesses with this approach of using 2 anchors and CPFP Carve Out. This proposal helps address a few of them (see Related Work for how other weaknesses are addressed):
+
+* Cluster Mempool necessitates the removal of CPFP Carve Out https://delvingbitcoin.org/t/an-overview-of-the-cluster-mempool-proposal/393#the-cpfp-carveout-rule-can-no-longer-be-supported-12.
+* CPFP Carve Out only allows ''one more'' child to be added to the transaction. This means it cannot guarantee the ability to CPFP for more than 2 parties of a shared transaction.
+
+==Topologically Restricted Until Confirmation==
+
+This section describes one approach for opt-in policy rules that can realistically be deployed today and is useful to today's applications.
+It is based on the idea that most limitations stem from existing ancestor/descendant package limits being too permissive for the majority of use cases.
+
+The scope of the policy's anti-pinning benefits is limited to the individual node's mempool, and the degree to which a user's transaction is safe from pinning depends how much of the network has adopted this policy.
+
+Similarly, there are multiple approaches to creating a policy to minimize pinning, more may become available over time (see Related Work section), and the details of this approach can be tweaked if conditions change. For example, if loosening one of the topology restrictions enables a new use case while still providing acceptable pinning bounds, it can be changed.
+
+===Specification===
+
+Senders can signal that they want a transaction to be Topologically Restricted Until Confirmation (TRUC). Specifically, set nVersion=3.
+A node that implements this policy would apply their existing standardness and policy rules, along with the following set of rules, to TRUC transactions:
+
+1. A TRUC transaction signals replaceability, even if it does not signal BIP125 replaceability.
+
+2. Any TRUC transaction's unconfirmed ancestors must all be TRUC. Any descendant of an unconfirmed TRUC transaction must also be TRUC.
+Rationale:
+* Requiring packages to be all-or-none TRUC makes it possible to enforce the topology limits. For example, the TRUC descendant limit would not be very meaningful if it could be bypassed by creating a non-TRUC child.
+* Combined with Rule 1, this requirement creates "inherited signaling" when descendants of unconfirmed transactions are created. Checking whether a transaction signals replaceability this way does not require mempool traversal, and does not change based on what transactions are mined.
+
+Note: A TRUC transaction can spend outputs from ''confirmed'' non-TRUC transactions. A non-TRUC transaction can spend outputs from ''confirmed'' TRUC transactions.
+
+3. An unconfirmed TRUC transaction cannot have more than 1 unconfirmed ancestor. An unconfirmed TRUC transaction cannot have more than 1 unconfirmed descendant. CPFP Carve Out is not granted to TRUC transactions.
+Rationale:
+* The larger the descendant limit, the more transactions may need to be replaced. See #1 in Rule 3 Pinning section above. This also makes pinning using Rule 5 more difficult, since a directly conflicting transaction has fewer possible descendants.
+* These two limits (ancestor count 2, descendant count 2) effectively create a cluster limit using the existing ancestor and descendant limits. Increasing them to 3 would imply an infinite cluster count limit.
+* This 1-parent-1-child topology makes it possible to use ancestor score (minimum of ancestor feerate and individual feerate) as a measure of incentive compatibility.
+
+ Q: Why not allow multiple parents to enable batched fee-bumping?
+ To mitigate pinning through absolute fees, we need to prevent a child of an unconfirmed TRUC transaction from bringing in more unconfirmed ancestors. See #2 in "RBF pinning through absolute fees" section above.
+
+ Q: Why not allow another child?
+ Allowing another child disables the ability to use ancestor score to measure incentive compatibility. Imagine the original transaction, A, has a child B and co-parent C (i.e. B spends from A and C). C also has another child, D. B is one of the original transactions and thus its ancestor feerate must be lower than the package's feerate. However, this may be an underestimation because D can bump C without B's help. This is resolved if TRUC transactions can only have TRUC ancestors, as then C cannot have another child.
+
+ Q: Why allow any descendants at all?
+ At least 1 descendant is required to allow CPFP of the presigned transaction. Without package RBF, multiple anchor outputs would be required to allow each counterparty to fee-bump any presigned transaction. With package RBF, since the presigned transactions can replace each other, 1 anchor output is sufficient.
+
+
+4. A TRUC transaction cannot have a sigop-adjusted virtual size larger than 10,000 vB.
+Rationale: Limit the amount of virtual bytes (and thus fees) that may need to be replaced, while leaving a comfortable amount of space for payments, HTLCs, or other uses of the transaction. Generally, having a smaller maximum size helps to better define bounds for algorithms and memory usage, and the existing limit of 100,000 vB seems much larger than necessary.
+
+
+5. A TRUC transaction that has an unconfirmed TRUC ancestor cannot have a sigop-adjusted virtual size larger than 1000 vB.
+Rationale: Limit the amount of virtual bytes (and thus fees) that may need to be replaced, while leaving a comfortable amount of space for inputs to fund the transaction.
+ Q: Why not bigger?
+ The larger the descendant size limit, the more vbytes may need to be replaced. With default limits, if the child is e.g. 100,000 vB, that might be an additional 100,000 sats (at 1 sat/vbyte) or more, depending on the feerate. Restricting all children to 1000 vB reduces the upper bound of the additional fees by a factor of 100.
+
+ This rule is also easily tacked on to existing logic for policy and wallets. A maximum size standard transaction (100 kvB) can have up to 1000 vB of descendants to be within the default descendant limit (101 kvB).
+
+ Q: Why not smaller?
+ The smaller this limit, the fewer UTXOs a child may use to fund this fee-bump. For example, only allowing the TRUC child to have 2 inputs would require wallets to maintain a pool of high-value confirmed UTXOs. However, as the fee-bumping child only needs to fund fees (as opposed to payments), just a few UTXOs should suffice. With a limit of 1000 vB and usage of taproot outputs, the child can have 15 inputs and 2 outputs (calculated using [https://bitcoinops.org/en/tools/calc-size/ this tool]).
+
+
+6. An individual TRUC transaction is permitted to be below the mempool min relay feerate, assuming it is considered within a package that meets the mempool's feerate requirements.
+Rationale: This allows contracting protocols to create presigned transactions with 0 fees and fee-bump them using CPFP at broadcast time.
+
+
+====Implementation====
+
+* https://github.com/bitcoin/bitcoin/pull/28948
+* https://github.com/bitcoin/bitcoin/pull/29873
+* https://github.com/bitcoin/bitcoin/pull/29496
+
+====Related Work====
+
+This 1-parent-1-child (aka cluster size 2) topology restriction makes the transactions much easier to reason about, which enables additional features like
+feerate diagram comparisons
+
+[https://github.com/bitcoin/bitcoin/pull/29242 this PR] implements feerate diagram creation and comparison for sets of transactions in which the maximum cluster size is 2, e.g. all TRUC transactions.
+,
+package RBF
+
+[https://github.com/bitcoin/bitcoin/pull/28984 this PR] implements package RBF, enforcing incentive compatibility by comparing the feerate diagrams of the mempool before and after replacement. The feerate diagrams are easy to build when the relevant clusters are of size 2 and below, so package RBF is restricted to those scenarios. As TRUC transactions always have this property, package RBF is enabled for TRUC transactions.
+,
+and sibling eviction
+
+[https://github.com/bitcoin/bitcoin/pull/29306 This PR] implements sibling eviction for TRUC transactions: if a new transaction would exceed a transaction's descendant limit, it considers evicting the existing descendant using replacement rules. Sibling eviction is feasible for TRUC transactions because there is no difficulty in identifying which descendant to evict (there can only be 1).
+.
+
+The [https://github.com/bitcoin/bips/pull/1524 Ephemeral Anchors] proposal builds on top of this one to add more features.
+It changes the anchor script to be anyone can spend, allowing anybody to add fees and reducing the onchain footprint and fee costs.
+It also allows anchor outputs to have 0 value, eliminating the need to deduct value from the input amount in order to create anchors.
+
+The [https://delvingbitcoin.org/t/an-overview-of-the-cluster-mempool-proposal/393/7 Cluster Mempool] proposal makes fundamental changes to mempool structure and policy rules, enabling the accurate assessment of the incentive compatibility of accepting or removing a transaction, among other things. Notably, Cluster Mempool introduces a limit to all transactions' cluster size to make incentive compatibility calculations feasible. This cluster limit is similar to TRUC limits in that it bounds computation to enable improved policies, but is applied to all transactions (not just ones that opt in) and is much less restrictive than TRUC limits.
+
+Cluster Mempool provides a more holistic solution to some of the problems listed (such as adding an incentive compatibility requirement to RBF and safely enabling package RBF for more complex topologies). However, it does not help resolve all problems (such as RBF Pinning through absolute fees and number of conflicts). Also, since Cluster Mempool is incompatible with CPFP Carve Outhttps://delvingbitcoin.org/t/an-overview-of-the-cluster-mempool-proposal/393#the-cpfp-carveout-rule-can-no-longer-be-supported-12, TRUC with sibling eviction and package RBF provide an alternative solution to applications that rely on it.
+
+Building on top of Cluster Mempool, there are also various ideas for extending TRUC transactions and creating another anti-pinning policy
+https://delvingbitcoin.org/t/v3-and-some-possible-futures/523/3.
+
+[https://bitcoinops.org/en/topics/package-relay Package Relay] includes changes in p2p protocol, transaction relay logic, and mempool policy to enable nodes to accept and relay packages of transactions. Much of this proposal's utility relies on the existence of package relay for 1-parent-1-child packages (the topology TRUC supports).
+
+====Backward Compatibility====
+
+Transactions with nVersion=3 were previously nonstandard. There are no known conflicts with previous usage.
+
+====Intended Usage====
+
+Generally, users with no interest in spending unconfirmed outputs from a transaction can make them TRUC transactions for more robust RBF abilities.
+
+This proposal allows for a different solution to fee-bumping in LN, in which commitment transactions are signed with 0 fees and include a single anchor that can later be used to add fees at broadcast time
+Proposals for changes to LN commitment transaction format using TRUC and a single anchor:
+* [https://delvingbitcoin.org/t/lightning-transactions-with-v3-and-ephemeral-anchors/418 "Lightning transactions with v3 and ephemeral anchors"]
+* [https://github.com/instagibbs/bolts/commits/zero_fee_commitment bolts proposal branch]
+* See "Intended usage for LN" section in [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html "New transaction policies (nVersion=3) for contracting protocols"]
+.
+A similar fee-bumping model can also be used in other contracting protocols
+Examples of non-LN protocols that have shown interest in, designed, or built fee-bumping using TRUC:
+* A LN-Symmetry implementation using TRUC and ephemeral anchors: [https://delvingbitcoin.org/t/ln-symmetry-project-recap/359 LN-Symmetry Project Recap] [https://github.com/instagibbs/lightning/tree/eltoo_support branch]
+* See "Managing Fees Safely" mentioning ephemeral anchors in [https://jameso.be/vaults.pdf "Vaults and Covenants"]
+.
+
+==Alternatives==
+
+Various alternatives for RBF
+Proposals and discussions dedicated to improving RBF:
+* [https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff "RBF Improvements"]
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019817.html "Improving RBF Policy"]
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/016998.html "[PROPOSAL] Emergency RBF (BIP 125)"]
+
+and new fee-bumping mechanisms
+
+ Proposals and discussions dedicated to improving or creating new fee-bumping mechanisms:
+* [https://github.com/lightning/bolts/pull/1036 "Add option to sign commitments at various feerates"]
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019243.html "A Stroll through Fee-Bumping Techniques : Input-Based vs Child-Pay-For-Parent"]
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html "A Replacement for RBF and CPFP: Non-Destructive TXID Dependencies for Fee Sponsoring"]
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html "Thoughts on fee bumping"]
+
+have been proposed across multiple discussion threads.
+Most alternatives do not conflict with TRUC, and some work in conjunction with this proposal - see Related Work.
+A few popular ideas that were not incorporated into this work are summarized here.
+
+===Alternatives: add static incentive compatibility rule in RBF policy===
+
+Add incentive compatibility requirement to RBF policy using some existing score or static calculation
+Examples of incentive compatibility score proposals and suggestions:
+* [https://github.com/bitcoin/bitcoin/pull/23121 "check ancestor feerate in RBF, remove BIP125 Rule2"]
+* [https://github.com/bitcoin/bitcoin/pull/26451 "Enforce incentive compatibility for all RBF replacements"]
+* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019841.html
+* https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff?permalink_comment_id=4081349#gistcomment-4081349
+.
+
+As the incentive compatibility "score" of a transaction must be dynamically calculated given the structure of mempools today, there is no satisfactory solution. A full calculation is too computationally expensive. Static values can overestimate or underestimate, leading to more pinning problems Four examples of static calculations and an example in which they are all inaccurate: https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff#mining-score-of-a-mempool-transaction.
+The ability to calculate incentive compatibility scores efficiently is a primary feature and motivation for both TRUC transactions and Cluster Mempool.
+
+===Alternatives: replace by feerate===
+
+"Instead of using Rule 3 and/or 4 (requiring an increase in absolute fees), allow replacements with a higher feerate."
+
+One variation of this proposal is to apply this rule in certain exceptional scenarios or when the replacement would confirm "soon"
+Examples of Replace by Feerate proposals and suggestions:
+* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/016998.html "[PROPOSAL] Emergency RBF (BIP 125)"]
+* [https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff#fees-in-next-block-and-feerate-for-the-rest-of-the-mempool]
+* [https://petertodd.org/2024/one-shot-replace-by-fee-rate "One-Shot Replace-by-Fee-Rate"]
+.
+
+The primary problem with these proposals is the potential for free relay and DDoS attacks.
+
+Removing Rule 3 and 4 in general would allow free relay
+Examples of free relay with the removal of Rule 3 and/or 4:
+ Consider a rule where the fee can be decreased (remove Rule 3 and 4) but the feerate must double. In this scenario, a 100 kvB transaction can be replaced by a 100 vB transaction paying 200 sats. That's 200 sats to relay 100,200 vB of transaction data, which is less than 0.002 sat/vB. It becomes quite cheap to replace large portions of the mempool, decreasing both its average feerate and total absolute fees.
+
+ Consider a rule where the fee can stay the same (keep Rule 3 but drop Rule 4) but the feerate must double. The attacker can start out with 100 kvB transaction, paying 1 sat/vB. A user can reduce its size over and over again, doubling the feerate each time until it gets too small, and end up paying 100 ksat for 100 kvB(1 + 1/2 + 1/4 + ... + log2(mintxsize)) -> approaches 200 kvB. This means the attacker pays a rate of 0.5 sat/vB to relay transactions, which is below our "free relay" threshold of 1 sat/vB.
+.
+
+Another issue is the complexity of defining and implementing a "would confirm soon" or "is in the top N portion of the mempool." These proposals require an efficient way to assess the incentive compatibility score of a transaction and where it ranks amongst the other mempool transactions. This isn't feasible without something like cluster mempool (also see the "add static incentive compatibility rule in RBF policy" section above)
+Concerns about Replace by Feerate proposals
+* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/017020.html
+* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/017002.html
+* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html
+* https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff?permalink_comment_id=4044451#gistcomment-4044451
+.
+
+===Alternatives: implement rate-limiting without fee rules===
+"Since Rule 3 and 4 (requiring an increase in absolute fees) are for rate-limiting, replace them with a mempool-wide or per-peer rate limits on replacements by outpoint and/or bandwidth
+Examples of general rate-limiting proposals and suggestions:
+* https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff?permalink_comment_id=4081349#gistcomment-4081349
+* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019820.html
+* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/017024.html
+ Related proposal for changing the amount of bandwidth that replacement transactions use:
+* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019820.html
+."
+
+A problem with any global rate limit is that, in the absence of reputation or identities, the limit could be exhausted by an attacker, thus restricting replacements for honest users. For example, an outpoint-based rate limit could be exhausted by one dishonest participant of a shared transaction, preventing the other participants from making any replacements. There are also other concerns about implementation complexity, free relay issues, and other unresolved edge cases
+Concerns
+* https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff?permalink_comment_id=4081559#gistcomment-4081559
+* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019921.html
+* https://docs.google.com/document/d/1LpYF17HdbXPGHKSl3WYdxG4XTJBNJKSn-c2UJ2yphhE/edit?usp=sharing
+.
+
+
+==Acknowledgements==
+
+Thank you to everyone who contributed to this proposal and document, including
+Jon Atack,
+Matt Corallo,
+Suhas Daftuar,
+Mark Erhardt,
+Antoine Poinsot,
+Antoine Riard,
+Gregory Sanders,
+and Bastien Teinturier.
+
+==References and Rationale==
+
+
+
diff --git a/bip-0443.mediawiki b/bip-0443.mediawiki
new file mode 100644
index 0000000000..620336e9c3
--- /dev/null
+++ b/bip-0443.mediawiki
@@ -0,0 +1,465 @@
+
+
+
+== Abstract ==
+
+This BIP proposes to add consensus support for a new tapscript opcode that enables a new type of output restrictions:
+OP_CHECKCONTRACTVERIFY (OP_CCV).
+
+This opcode enables users to create UTXOs that carry a dynamic commitment to a piece of data. The commitment can be
+validated during the execution of the script, allowing introspection to the committed data. Moreover, a script can
+constrain the internal public key and taptree of one or more outputs, and possibly the committed data.
+
+In conjunction with an opcode for ''vector commitments''''Vector commitments'' are cryptographic primitives that
+allow to commit to a vector of values via a single short value. Hashing and concatenation trivially allow to commit to
+an entire vector, and later reveal all of its elements. Merkle trees are among the simplest efficient vector
+commitments, allowing to reveal individual elements with logarithmically-sized proofs., this allows to create and
+compose arbitrary state machines that define the possible future outcomes of a UTXO. The validity of a state transition
+depends on the conditions that can be expressed in the program (scripts in the taptree).
+
+=== Copyright ===
+
+This document is licensed under the 3-clause BSD license.
+
+=== Motivation ===
+
+The ability to constrain the future of coins beyond what is possible with presigned transactions is at the core of
+numerous attempts to improve bitcoin. Some of the proposed applications include:
+
+* UTXO sharing schemes like Ark, CoinPools, Timeout Trees, etc. use various types of output restrictions in order to enable multiple parties to share the control of a UTXO, while ensuring that each participant controls their own `balance.
+* OP_VAULT[[bip-0345.mediawiki|BIP-345]] is a proposed opcode to implement a 2-step withdrawal process, enabling on-chain reactive security.
+* OP_CHECKTEMPLATEVERIFY[[bip-119.mediawiki|BIP-114]] is a long-proposed opcode to constrain a transaction to a ''template'' with a fixed set of outputs.
+* Sidechains and rollups could be implemented via a UTXO encumbered with a recursive covenant, updating the sidechain state root every time it is spent.
+
+Constructions like BitVMhttps://bitvm.org/ try to side-step the lack of a primitive allowing UTXOs to carry
+state with a clever use of Lamport Signatures, and optimistic execution of smart contracts. This comes with an extremely
+high cost in term of complexity, interactivity, and (potentially) in block size occupation, for some of the possible
+execution paths. Moreover, the design of fully trustless bridges remains elusive.
+
+Rather than providing a construct optimized for a specific application, this BIP aims to provide a fundamental building
+block that is widely applicable, and common to many constructions.
+
+== Design ==
+
+OP_CHECKCONTRACTVERIFY is an implementation of a new primitive that could be called
+''state-carrying UTXOs''. It allows to embed a commitment to a piece of data in a UTXO, and to validate it during the
+execution of the script, and ''carry'' a (possibly dynamically computed) piece of data to the new UTXOs that are
+produced.
+
+We consider the ''program'' of a P2TR UTXO to be composed of an x-only public key (that we call the ''naked key''), and
+a Merkle tree of scripts. If there is no data committed in the UTXO, then the naked key is the internal key as defined
+in BIP-341.
+
+If the UTXO carries a commitment to a 32-byte hash (the ''data''), the naked key is tweaked with a hash of the data.
+The resulting key is the taproot internal key per BIP-341.
+
+This allows to embed a commitment to the data that can be validated during the script execution, while staying fully
+compatible with taproot. Notably:
+* the committed data does not make the UTXO any larger;
+* the keypath spend is still available to any party that possesses the private key of the naked key, as long as they have knowledge of the embedded data (or at least the data’s hash)For example, in a multi-party contract, the naked key could be an aggregate key using [[bip-0327.mediawiki|MuSig2]]; the taproot keypath would therefore allow a ''cooperative'' spend, without executing any script at all. Like for all taproot transactions, this is indeed the
+ cheapest way of spending the UTXO — albeit not always possible in practice.;
+* if multiple scripts are in different leaves of the taptree, only the ones that actually need to access the data have to pay a cost for it, in terms of additional witness bytes.
+
+OP_CHECKCONTRACTVERIFY can be applied to introspect the program and data of one of the inputs of the
+transaction (typically, the UTXO being spent, in order to access its committed data), or one of the outputs of the
+transaction (in order to define its program, and possibly its committed data).
+
+=== Output amounts ===
+
+When checking the script of one or more outputs with OP_CHECKCONTRACTVERIFY, it is usually necessary to
+also check that the amount of the current input (that is, the UTXO being spent) is correctly distributed among the
+outputs in the expected way. Therefore, the opcode already includes an amount semantic that covers the common use cases.
+
+There are three supported modes for the opcode when checking an output, depending on the value of the mode
+parameter:
+* ''default'': the residual amount of the current input must be preserved in the output (aggregate across the inputs that specify the output);
+* ''ignore'': the output amount is ignored.
+* ''deduct'': the amount of the checked output is subtracted from the amount of the current input (the residual amount is then available for further checks);
+
+The ''default'' logic covers the common case where a UTXO’s full amount is required to be sent to a specific output.
+
+The ''deduct'' logic allows to assign portions of the input amount to one or more outputs; the residual amount, checked
+with a final check using the ''default'' logic, can be used to enforce that the total amount is preserved.
+
+The following figures illustrate some common examples of supported use cases for the amount logic. This list is not
+exhaustive, as there are many more possible combinations.
+
+'''Remark:''' validation fails if the amount of an output is checked with both the ''default'' and the ''deduct'' logic
+in the same transaction, or multiple times with the ''deduct'' logic. This prevents duplicate or inconsistent counting
+of the same amounts.
+
+'''Remark:''' it is allowed to check for multiple inputs to check the same output with the ''default'' logic. This
+allows multiple inputs to aggregate (in full or in part) their amounts to the same output.
+
+-----
+
+::[[File:bip-0443/amount_example_1.png|framed|center|alt=1-to-1 amount logic|600px]]
+::'''Figure 1:''' A UTXO A sends the entire amount to some output contract B, using CCV with the default semantic.
+
+-----
+
+::[[File:bip-0443/amount_example_2.png|framed|center|alt=3-to-1 aggregate amount logic|600px]]
+::'''Figure 2:''' Three UTXOs aggregate their amounts towards the same output contract, using CCV with the default semantic.
+
+-----
+
+::[[File:bip-0443/amount_example_3.png|framed|center|alt=split amount logic|600px]]
+::'''Figure 3:''' A UTXO A sends a portion of its amount to a contract A' identical to itself, and the rest to a different contract B. It would use CCV to introspect its own input's program, then to check the first output with the deduct semantic, then to check the second output with the default semantic to assign the residual amount.
+
+-----
+
+::[[File:bip-0443/amount_example_4.png|framed|center|alt=split and aggregate amount logic|600px]]
+::'''Figure 4:''' Similar to the previous example, but a second input B also checks the same output X with the default semantic, aggregating its input with the residual amount of the first input.
+
+-----
+
+Note that the ''deduct'' semantic does not allow to check the exact amount of its output. Therefore, in contracts using
+a scheme similar to figure 3 or 4 above, amounts should be constrained either with a signature, or with future
+introspection opcodes that allow fixing the amount. In lack of that, amounts would be malleable.
+
+== Specification ==
+
+The tapscript opcode OP_SUCCESS187 (0xbb) is constrained with new rules to implement
+OP_CHECKCONTRACTVERIFY.
+
+When evaluating OP_CHECKCONTRACTVERIFY (OP_SUCCESS187,
+0xbb), the expected format of the stack, shown bottom to top, is:
+
+
+
+
+
+where:
+
+* is a minimally encoded integer, according to one of the values defined below.
+* is the Merkle root of the taproot tree, or a minimally encoded -1, or the empty buffer.
+* is called the ''naked key'', and it's a valid 32-byte x-only public key, or a minimally encoded -1, or the empty buffer.
+* is a minimally encoded -1, or a minimally encoded non-negative integer.
+* is a buffer of arbitrary length.
+
+In short, the semantics of the opcode with respect to the script can be summarized as follows:
+
+
+Verify that the input/output with the given 'index' is a P2TR UTXO whose taproot output key is obtained from 'pk',
+tweaked with the hash of 'data' (if non-empty), then taptweaked with 'taptree' (if non-empty).
+
+
+If the is non-empty, then the additive tweak for the data is computed as:
+
+
+ data_tweak = sha256(pk || data)
+
+
+In the following, the ''current input'' is the input whose script is being executed.
+
+The following value of the are defined:
+* CCV_MODE_CHECK_INPUT = -1: Check an input's script; no amount check.
+* CCV_MODE_CHECK_OUTPUT = 0: Check an output's script; preserve the (possibly residual) amount.
+* CCV_MODE_CHECK_OUTPUT_IGNORE_AMOUNT = 1: Check an output's script; ignore amounts.
+* CCV_MODE_CHECK_OUTPUT_DEDUCT_AMOUNT = 2: Check an output's script; deduct the output amount from the input's residual amount.
+
+Any other value of the makes the opcode succeed validation immediately for the current
+inputThis allows to soft-fork future behavior by introducing new values for the . As the mode
+would always be hard-coded via a push in the script, the risk of mistakes seems negligible..
+
+The following values of the other parameters have special meanings:
+* If the is -1, it is replaced with the Merkle root of the current input's tapscript tree. If the taptree is the empty buffer, then the taptweak is skipped.
+* If the is 0, it is replaced with the NUMS x-only pubkey 0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 defined in BIP-0340. If the is -1, it is replaced with the taproot internal key of the current input.
+* If the is -1, it is replaced with the index of the current input.
+* If the is the empty buffer, then there is no data tweak for the input/output being checked.
+
+Any other value of the , , or parameters
+is invalid, and makes the opcode immediately fail validation.
+
+=== Script support for OP_CHECKCONTRACTVERIFY ===
+
+The specification is divided into three parts:
+* the transaction-wide initialization;
+* the input initialization;
+* the opcode evaluation.
+
+The following helper function is a version of taproot_tweak_pubkey, except that a raw 32-byte data is used
+as the tweak.
+
+
+def tweak_embed_data(pubkey, data):
+ assert len(pubkey) == 32
+
+ data_tweak = sha256(pubkey + data)
+
+ t = int_from_bytes(data_tweak)
+ if t >= SECP256K1_ORDER:
+ raise ValueError
+ P = lift_x(int_from_bytes(pubkey))
+ if P is None:
+ raise ValueError
+ Q = point_add(P, point_mul(G, t))
+ return 0 if has_even_y(Q) else 1, bytes_from_int(x(Q))
+
+
+The taproot_tweak_pubkey from [[bip-0341.mediawiki|BIP341]] is also used as a helper function.
+
+The following notations are used in the pseudocode below:
+* n_inputs and n_outputs are the number of inputs and outputs of the transaction, respectively;
+* inputs[i] is the i-th input of the transaction;
+* outputs[i] is the i-th output of the transaction;
+* this_input_index, this_input_internal_key and this_input_taptree are the index,
+ taproot internal key and taproot Merkle root of the current input, respectively.
+* P2TR(key) computes the scriptPubKey of the P2TR output with the given key as the taproot output key.
+
+==== Transaction-wide initialization ====
+
+This is executed once for the entire transaction, before any of the transaction input's scripts are evaluated.
+Itinitializes three arrays that are used to keep track of the amount information of the output.
+
+
+ output_min_amount = [0] * n_outputs
+ output_checked_default = [False] * n_outputs
+ output_checked_deduct = [False] * n_outputs
+
+
+==== Input initialization ====
+
+This is executed at the beginning of the evaluation of each input's script. It initializes the residual amount to equal
+the full amount of the current input.
+
+
+ residual_input_amount = input[this_input_index].amount
+
+
+==== OP_CHECKCONTRACTVERIFY evaluation ====
+
+The following code is executed every time the OP_CHECKCONTRACTVERIFY opcode is encountered during the
+evaluation of a taproot script spend. this_input_index, this_input_internal_key and
+this_input_taptree are the index, taproot internal key and taproot Merkle root of the current input.
+
+BIP341_NUMS_KEY is the x-only provably unspendable key 50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0
+defined in [[bip-341.mediawiki|BIP-341]].
+
+
+ if mode < CCV_MODE_CHECK_INPUT or mode > CCV_MODE_CHECK_OUTPUT_DEDUCT_AMOUNT:
+ return success() # undefined mode is OP_SUCCESS
+
+ if index == -1:
+ index = this_input_index
+
+ if mode == CCV_MODE_CHECK_INPUT:
+ if index < 0 or index >= n_inputs:
+ return fail() # input index out of bounds
+
+ target_script = inputs[index].scriptPubKey
+ else:
+ if index < 0 or index >= n_outputs:
+ return fail() # output index out of bounds
+
+ target_script = outputs[index].scriptPubKey
+
+ if taptree == <-1>:
+ taptree = this_input_taptree
+
+ if pk == <0>:
+ naked_key = BIP341_NUMS_KEY
+ elif pk == <-1>:
+ naked_key = this_input_internal_key
+ elif len(pk) == 32:
+ naked_key = pk
+ else:
+ return fail()
+
+ # Verify the target contract data and program
+ _, internal_key = tweak_embed_data(naked_key, data)
+
+ if len(taptree) != 0:
+ if len(taptree) != 32:
+ return fail()
+
+ _, final_key = taproot_tweak_pubkey(internal_key, taptree)
+ else:
+ final_key = internal_key
+
+ if target_script != P2TR(final_key):
+ return fail()
+
+ # Amount checks
+
+ if mode == CCV_MODE_CHECK_OUTPUT:
+ # default amount semantic
+ if output_checked_deduct[index]:
+ return fail()
+
+ output_min_amount[index] += residual_input_amount
+ residual_input_amount = 0
+
+ if outputs[index].amount < output_min_amount[index]:
+ return fail()
+
+ output_checked_default[index] = True
+ elif mode == CCV_MODE_CHECK_OUTPUT_DEDUCT_AMOUNT:
+ # 'deduct' amount semantic
+ if residual_input_amount < outputs[index].amount:
+ return fail()
+
+ if output_checked_default[index] or output_checked_deduct[index]:
+ return fail()
+
+ residual_input_amount = residual_input_amount - outputs[index].amount
+ output_checked_deduct[index] = True
+
+ stack.pop(5) # drop all 5 stack elements
+
+
+==== sigops budget ====
+
+TODO
+
+== Policy changes ==
+
+TODO
+
+== Implementation ==
+
+A reference implementation is provided as a bitcoin-core [https://github.com/bitcoin/bitcoin/pull/32080 pull request].
+
+== Examples ==
+
+This section documents some common script fragments that use OP_CHECKCONTRACTVERIFY for various common
+choices of the parameters. Depending on the use case, some of the parameters might be passed via the witness stack.
+In these examples, <> (empty buffer) and 0 both refer to an empty stack element.
+
+----
+
+Check data embedded in the current input:
+
+
+
+
+
+
+OP_CHECKCONTRACTVERIFY
+
+
+This would be used to access the data committed in the current input. The parameter, of course,
+would be passed via the witness stack.
+
+----
+
+Check that the input with index in_i is a specific contract with embedded input_data:
+
+
+
+
+
+
+OP_CHECKCONTRACTVERIFY
+
+
+This allows introspecting the program (naked key and taptree) and data of another input of the transaction.
+
+----
+
+Check that the output with index out_i is a certain contract (pubkey and taptree) with the specified
+embedded , preserving input amount:
+
+
+
+
+
+
+OP_CHECKCONTRACTVERIFY
+
+
+This allows introspecting an output's program and data, and sending the full residual amount to it. Logically, it can be
+thought as a state transition, moving money to a different state, but still under the control of the pre-set rules.
+Typically, the data would be computed based on the witness stack, while the output program would be
+hard-coded in Script.
+
+----
+
+Check that the output with index out_i is a P2TR with pubkey output_pk, preserving amount:
+
+> # no data
+
+
+> # no taptweak
+
+OP_CHECKCONTRACTVERIFY
+
+
+Unlike the previous example, here there is no computation over the destination taproot public key, since both
+data and taptweak are omitted.
+
+----
+
+Check that the output with index out_i is a certain contract (pubkey and taptree) with the specified
+embedded data; don't check amount:
+
+
+
+
+
+
+OP_CHECKCONTRACTVERIFY
+
+
+'''Remark:''' amounts are malleable with this check alone; therefore, it is expected that the amount is also checked
+with separate introspection opcodes.
+
+----
+
+Check that the amount of the current input is partially sent to the first output (that must have a certain pubkey), and
+all the remaining amount is sent to the second output, which has the same internal key and taptree as the current input:
+
+> # no data
+
+>
+> # no tweak
+
+OP_CHECKCONTRACTVERIFY
+
+> # no data
+
+
+
+
+OP_CHECKCONTRACTVERIFY
+
+
+'''Remark:''' in some applications, it might be desirable to check the exact amount of the first output with separate
+introspection opcodes.
+
+== Applications ==
+
+TODO
+
+== Deployment ==
+
+The activation mechanism, and the set of other BIPs to be concurrently deployed, are to be determined.
+
+== Backwards compatibility ==
+
+OP_CHECKCONTRACTVERIFY replaces the witness v1-only opcode OP_SUCCESS187 with stricter verification
+semantics. Consequently, scripts using those opcodes which previously were valid will cease to be valid with this change.
+
+Stricter verification semantics for an OP_SUCCESSx opcode are a soft fork, so existing software will be fully functional
+without upgrade except for mining and block validation.
+
+== Footnotes ==
+
+
+
+
+== Acknowledgements ==
+
+TODO
\ No newline at end of file
diff --git a/bip-0443/amount_example_1.png b/bip-0443/amount_example_1.png
new file mode 100644
index 0000000000..71d913bbf5
Binary files /dev/null and b/bip-0443/amount_example_1.png differ
diff --git a/bip-0443/amount_example_2.png b/bip-0443/amount_example_2.png
new file mode 100644
index 0000000000..72d623adea
Binary files /dev/null and b/bip-0443/amount_example_2.png differ
diff --git a/bip-0443/amount_example_3.png b/bip-0443/amount_example_3.png
new file mode 100644
index 0000000000..0d6b9de585
Binary files /dev/null and b/bip-0443/amount_example_3.png differ
diff --git a/bip-0443/amount_example_4.png b/bip-0443/amount_example_4.png
new file mode 100644
index 0000000000..6b0c8513fc
Binary files /dev/null and b/bip-0443/amount_example_4.png differ
diff --git a/scripts/buildtable.pl b/scripts/buildtable.pl
index 1edd8c0dcf..acec8acf6e 100755
--- a/scripts/buildtable.pl
+++ b/scripts/buildtable.pl
@@ -89,23 +89,35 @@
);
my %GrandfatheredPD = map { $_ => undef } qw(9 36 37 38 42 49 50 60 65 67 69 74 80 81 83 90 99 105 107 109 111 112 113 114 122 124 125 126 130 131 132 133 140 141 142 143 144 146 147 150 151 152);
my %TolerateMissingLicense = map { $_ => undef } qw(1 10 11 12 13 14 15 16 21 31 33 34 35 39 43 44 45 47 61 64 68 70 71 72 73 101 102 106 120 121);
-my %TolerateTitleTooLong = map { $_ => undef } qw(39 44 45 47 49 60 67 68 69 73 74 75 80 81 99 105 106 109 113 122 126 131 143 145 147 173);
+my %TolerateTitleTooLong = map { $_ => undef } qw(39 44 45 47 49 60 67 68 69 73 74 75 80 81 99 105 106 109 113 122 126 131 143 145 147 173 327);
my %emails;
my $bipnum = 0;
while (++$bipnum <= $topbip) {
my $fn = sprintf "bip-%04d.mediawiki", $bipnum;
+ my $is_markdown = 0;
+ if (!-e $fn) {
+ $fn = sprintf "bip-%04d.md", $bipnum;
+ $is_markdown = 1;
+ }
-e $fn || next;
open my $F, "<$fn";
- while (<$F> !~ m[^(?:\xef\xbb\xbf)?
$]) {
+ if ($is_markdown) {
+ while (<$F> !~ m[^(?:\xef\xbb\xbf)?```$]) {
+ die "No ``` in $fn" if eof $F;
+ }
+ } else {
+ while (<$F> !~ m[^(?:\xef\xbb\xbf)?
$]) {
die "No
in $fn" if eof $F;
+ }
}
my %found;
my ($title, $author, $status, $type, $layer);
my ($field, $val);
while (<$F>) {
- m[^
$] && last;
+ last if ($is_markdown && m[^```$]);
+ last if (!$is_markdown && m[^
$]);
if (m[^ ([\w-]+)\: (.*\S)$]) {
$field = $1;
$val = $2;
@@ -125,9 +137,9 @@
} elsif ($field eq 'Title') {
$title = $val;
my $title_len = length($title);
- die "$fn has too-long TItle ($title_len > 44 char max)" if $title_len > 44 and not exists $TolerateTitleTooLong{$bipnum};
+ die "$fn has too-long Title ($title_len > 44 char max)" if $title_len > 44 and not exists $TolerateTitleTooLong{$bipnum};
} elsif ($field eq 'Author') {
- $val =~ m/^(\S[^<@>]*\S) \<([^@>]*\@[\w.]+\.\w+)\>$/ or die "Malformed Author line in $fn";
+ $val =~ m/^(\S[^<@>]*\S) \<([^@>]*\@[\w.-]+\.\w+)\>$/ or die "Malformed Author line in $fn";
my ($authorname, $authoremail) = ($1, $2);
$authoremail =~ s/(?<=\D)$bipnum(?=\D)//g;
$emails{$authorname}->{$authoremail} = undef;
diff --git a/scripts/diffcheck.sh b/scripts/diffcheck.sh
new file mode 100755
index 0000000000..aa9f557cf2
--- /dev/null
+++ b/scripts/diffcheck.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+scripts/buildtable.pl >/tmp/table.mediawiki 2> /dev/null
+diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/after.diff || true
+if git checkout HEAD^ && scripts/buildtable.pl >/tmp/table.mediawiki 2>/dev/null; then
+ diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/before.diff || true
+ newdiff=$(diff -s /tmp/before.diff /tmp/after.diff -u | grep '^+')
+ if [ -n "$newdiff" ]; then
+ echo "$newdiff"
+ exit 1
+ fi
+ echo "README table matches expected table from BIP files"
+else
+ echo 'Cannot build previous commit table for comparison'
+ exit 1
+fi
diff --git a/scripts/link-format-chk.sh b/scripts/link-format-chk.sh
index e3f0f6d770..9493765d99 100755
--- a/scripts/link-format-chk.sh
+++ b/scripts/link-format-chk.sh
@@ -8,16 +8,14 @@
ECODE=0
FILES=""
-for fname in $(git diff --name-only HEAD $(git merge-base HEAD master)); do
- if [[ $fname == *.mediawiki ]]; then
- GRES=$(grep -n '](http' $fname)
- if [ "$GRES" != "" ]; then
- if [ $ECODE -eq 0 ]; then
- >&2 echo "Github Mediawiki format writes link as [URL text], not as [text](url):"
- fi
- ECODE=1
- echo "- $fname:$GRES"
+for fname in *.mediawiki; do
+ GRES=$(grep -n '](http' $fname)
+ if [ "$GRES" != "" ]; then
+ if [ $ECODE -eq 0 ]; then
+ >&2 echo "Github Mediawiki format writes link as [URL text], not as [text](url):"
fi
+ ECODE=1
+ echo "- $fname:$GRES"
fi
done
exit $ECODE