You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
aba9370 test: strip `vin.scriptWitness` from more PSBT test vectors (Kittywhiskers Van Gogh)
e4530e6 merge bitcoin#23718: hash preimages fields (Kittywhiskers Van Gogh)
dc9342b test: strip `vin.scriptWitness` from PSBT test vectors (Kittywhiskers Van Gogh)
c076d02 merge bitcoin#17034: PSBT version, proprietary, and xpub fields (BIP 174) (Kittywhiskers Van Gogh)
f1ba319 partial bitcoin#22514: Actually use SIGHASH_DEFAULT for PSBT signing (Kittywhiskers Van Gogh)
0c52bfe merge bitcoin#22513: Allow walletprocesspsbt to sign without finalizing (Kittywhiskers Van Gogh)
193765b merge bitcoin#23403: Fix segfault in the psbt_wallet_tests/psbt_updater_test (Kittywhiskers Van Gogh)
ba85b4c merge bitcoin#23303: Fix wallet_multisig_descriptor_psbt.py (Kittywhiskers Van Gogh)
c7a69cc merge bitcoin#22067: Test and document a basic M-of-N multisig using descriptor wallets and PSBTs (Kittywhiskers Van Gogh)
3219855 merge bitcoin#23106: Ensure wallet is unlocked before signing PSBT with walletprocesspsbt and GUI (Kittywhiskers Van Gogh)
b7c7c7b partial bitcoin#21365: Basic Taproot signing support for descriptor wallets (Kittywhiskers Van Gogh)
4a08920 partial bitcoin#21330: Deal with missing data in signature hashes more consistently (Kittywhiskers Van Gogh)
Pull request description:
## Additional Information
* Even though Dash Core does not implement Taproot, [bitcoin#21365](bitcoin#21365) has been partially backported due to changes related to transaction precomputation, required by later PSBT backports.
* Some test vectors introduced in [bitcoin#17034](bitcoin#17034) and [bitcoin#23718](bitcoin#23718) have `psbtx.tx->vin[i].scriptWitness` populated and as Dash Core does not support SegWit, attempting to read the raw data results in serialization errors.
The offending field was stripped out by forking Bitcoin Core v24 and modifying `decodepsbt` to strip out the field, reencode the modified data and return it. These changes were made in separate commits.
## Breaking Changes
None expected.
## Checklist
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
- [x] I have added or updated relevant unit/integration/functional/e2e tests
- [x] I have made corresponding changes to the documentation
- [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_
ACKs for top commit:
UdjinM6:
utACK aba9370
PastaPastaPasta:
utACK aba9370
Tree-SHA512: 439e009da032dffaa7b7048984ed27fefb7ce0854240e280a898d20c50132197d5575d8a289391d50f2527ab4f26326481ce78200c3014b6223d9c661e5c9377
Copy file name to clipboardExpand all lines: doc/descriptors.md
+41Lines changed: 41 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -117,6 +117,47 @@ Key order does not matter for `sortedmulti()`. `sortedmulti()` behaves in the sa
117
117
as `multi()` does but the keys are reordered in the resulting script such that they
118
118
are lexicographically ordered as described in BIP67.
119
119
120
+
#### Basic multisig example
121
+
122
+
For a good example of a basic M-of-N multisig between multiple participants using descriptor
123
+
wallets and PSBTs, as well as a signing flow, see [this functional test](/test/functional/wallet_multisig_descriptor_psbt.py).
124
+
125
+
Disclaimers: It is important to note that this example serves as a quick-start and is kept basic for readability. A downside of the approach
126
+
outlined here is that each participant must maintain (and backup) two separate wallets: a signer and the corresponding multisig.
127
+
It should also be noted that privacy best-practices are not "by default" here - participants should take care to only use the signer to sign
128
+
transactions related to the multisig. Lastly, it is not recommended to use anything other than a Bitcoin Core descriptor wallet to serve as your
129
+
signer(s). Other wallets, whether hardware or software, likely impose additional checks and safeguards to prevent users from signing transactions that
130
+
could lead to loss of funds, or are deemed security hazards. Conforming to various 3rd-party checks and verifications is not in the scope of this example.
131
+
132
+
The basic steps are:
133
+
134
+
1. Every participant generates an xpub. The most straightforward way is to create a new descriptor wallet which we will refer to as
135
+
the participant's signer wallet. Avoid reusing this wallet for any purpose other than signing transactions from the
136
+
corresponding multisig we are about to create. Hint: extract the wallet's xpubs using `listdescriptors` and pick the one from the
137
+
`pkh` descriptor since it's least likely to be accidentally reused (legacy addresses)
138
+
2. Create a watch-only descriptor wallet (blank, private keys disabled). Now the multisig is created by importing the two descriptors:
139
+
`wsh(sortedmulti(<M>,XPUB1/0/*,XPUB2/0/*,…,XPUBN/0/*))` and `wsh(sortedmulti(<M>,XPUB1/1/*,XPUB2/1/*,…,XPUBN/1/*))`
140
+
(one descriptor w/ `0` for receiving addresses and another w/ `1` for change). Every participant does this
141
+
3. A receiving address is generated for the multisig. As a check to ensure step 2 was done correctly, every participant
142
+
should verify they get the same addresses
143
+
4. Funds are sent to the resulting address
144
+
5. A sending transaction from the multisig is created using `walletcreatefundedpsbt` (anyone can initiate this). It is simple to do
145
+
this in the GUI by going to the `Send` tab in the multisig wallet and creating an unsigned transaction (PSBT)
146
+
6. At least `M` participants check the PSBT with their multisig using `decodepsbt` to verify the transaction is OK before signing it.
147
+
7. (If OK) the participant signs the PSBT with their signer wallet using `walletprocesspsbt`. It is simple to do this in the GUI by
148
+
loading the PSBT from file and signing it
149
+
8. The signed PSBTs are collected with `combinepsbt`, finalized w/ `finalizepsbt`, and then the resulting transaction is broadcasted
150
+
to the network. Note that any wallet (eg one of the signers or multisig) is capable of doing this.
151
+
9. Checks that balances are correct after the transaction has been included in a block
152
+
153
+
You may prefer a daisy chained signing flow where each participant signs the PSBT one after another until
154
+
the PSBT has been signed `M` times and is "complete." For the most part, the steps above remain the same, except (6, 7)
155
+
change slightly from signing the original PSBT in parallel to signing it in series. `combinepsbt` is not necessary with
156
+
this signing flow and the last (`m`th) signer can just broadcast the PSBT after signing. Note that a parallel signing flow may be
157
+
preferable in cases where there are more signers. This signing flow is also included in the test / Python example.
158
+
[The test](/test/functional/wallet_multisig_descriptor_psbt.py) is meant to be documentation as much as it is a functional test, so
159
+
it is kept as simple and readable as possible.
160
+
120
161
### BIP32 derived keys and chains
121
162
122
163
Most modern wallet software and hardware uses keys that are derived using
// TODO we're using amount=0 here but we should use the correct amount. This works because Dash ignores the amount while signing/verifying (only used in Bitcoin/Segwit)
559
-
if (!VerifyScript(txNew.vin[nTxInIndex].scriptSig, sigPubKey, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, MutableTransactionSignatureChecker(&txNew, nTxInIndex, 0))) {
0 commit comments