Line data Source code
1 : // Copyright (c) 2009-2020 The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #ifndef BITCOIN_PSBT_H
6 : #define BITCOIN_PSBT_H
7 :
8 : #include <attributes.h>
9 : #include <node/transaction.h>
10 : #include <optional.h>
11 : #include <policy/feerate.h>
12 : #include <primitives/transaction.h>
13 : #include <pubkey.h>
14 : #include <script/sign.h>
15 : #include <script/signingprovider.h>
16 :
17 : // Magic bytes
18 : static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff};
19 :
20 : // Global types
21 : static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00;
22 :
23 : // Input types
24 : static constexpr uint8_t PSBT_IN_NON_WITNESS_UTXO = 0x00;
25 : static constexpr uint8_t PSBT_IN_WITNESS_UTXO = 0x01;
26 : static constexpr uint8_t PSBT_IN_PARTIAL_SIG = 0x02;
27 : static constexpr uint8_t PSBT_IN_SIGHASH = 0x03;
28 : static constexpr uint8_t PSBT_IN_REDEEMSCRIPT = 0x04;
29 : static constexpr uint8_t PSBT_IN_WITNESSSCRIPT = 0x05;
30 : static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
31 : static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
32 : static constexpr uint8_t PSBT_IN_SCRIPTWITNESS = 0x08;
33 :
34 : // Output types
35 : static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00;
36 : static constexpr uint8_t PSBT_OUT_WITNESSSCRIPT = 0x01;
37 : static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02;
38 :
39 : // The separator is 0x00. Reading this in means that the unserializer can interpret it
40 : // as a 0 length key which indicates that this is the separator. The separator has no value.
41 : static constexpr uint8_t PSBT_SEPARATOR = 0x00;
42 :
43 : // BIP 174 does not specify a maximum file size, but we set a limit anyway
44 : // to prevent reading a stream indefinitely and running out of memory.
45 : const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MiB
46 :
47 : /** A structure for PSBTs which contain per-input information */
48 4758 : struct PSBTInput
49 : {
50 : CTransactionRef non_witness_utxo;
51 : CTxOut witness_utxo;
52 : CScript redeem_script;
53 : CScript witness_script;
54 : CScript final_script_sig;
55 : CScriptWitness final_script_witness;
56 : std::map<CPubKey, KeyOriginInfo> hd_keypaths;
57 : std::map<CKeyID, SigPair> partial_sigs;
58 : std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
59 663 : int sighash_type = 0;
60 :
61 : bool IsNull() const;
62 : void FillSignatureData(SignatureData& sigdata) const;
63 : void FromSignatureData(const SignatureData& sigdata);
64 : void Merge(const PSBTInput& input);
65 1326 : PSBTInput() {}
66 :
67 : template <typename Stream>
68 392 : inline void Serialize(Stream& s) const {
69 : // Write the utxo
70 392 : if (non_witness_utxo) {
71 248 : SerializeToVector(s, PSBT_IN_NON_WITNESS_UTXO);
72 248 : OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS);
73 248 : SerializeToVector(os, non_witness_utxo);
74 248 : }
75 392 : if (!witness_utxo.IsNull()) {
76 181 : SerializeToVector(s, PSBT_IN_WITNESS_UTXO);
77 181 : SerializeToVector(s, witness_utxo);
78 181 : }
79 :
80 392 : if (final_script_sig.empty() && final_script_witness.IsNull()) {
81 : // Write any partial signatures
82 357 : for (auto sig_pair : partial_sigs) {
83 34 : SerializeToVector(s, PSBT_IN_PARTIAL_SIG, MakeSpan(sig_pair.second.first));
84 34 : s << sig_pair.second.second;
85 34 : }
86 :
87 : // Write the sighash type
88 323 : if (sighash_type > 0) {
89 24 : SerializeToVector(s, PSBT_IN_SIGHASH);
90 24 : SerializeToVector(s, sighash_type);
91 24 : }
92 :
93 : // Write the redeem script
94 323 : if (!redeem_script.empty()) {
95 83 : SerializeToVector(s, PSBT_IN_REDEEMSCRIPT);
96 83 : s << redeem_script;
97 83 : }
98 :
99 : // Write the witness script
100 323 : if (!witness_script.empty()) {
101 45 : SerializeToVector(s, PSBT_IN_WITNESSSCRIPT);
102 45 : s << witness_script;
103 45 : }
104 :
105 : // Write any hd keypaths
106 323 : SerializeHDKeypaths(s, hd_keypaths, PSBT_IN_BIP32_DERIVATION);
107 323 : }
108 :
109 : // Write script sig
110 392 : if (!final_script_sig.empty()) {
111 41 : SerializeToVector(s, PSBT_IN_SCRIPTSIG);
112 41 : s << final_script_sig;
113 41 : }
114 : // write script witness
115 392 : if (!final_script_witness.IsNull()) {
116 38 : SerializeToVector(s, PSBT_IN_SCRIPTWITNESS);
117 38 : SerializeToVector(s, final_script_witness.stack);
118 38 : }
119 :
120 : // Write unknown things
121 398 : for (auto& entry : unknown) {
122 6 : s << entry.first;
123 6 : s << entry.second;
124 : }
125 :
126 392 : s << PSBT_SEPARATOR;
127 392 : }
128 :
129 :
130 : template <typename Stream>
131 469 : inline void Unserialize(Stream& s) {
132 : // Used for duplicate key detection
133 469 : std::set<std::vector<unsigned char>> key_lookup;
134 :
135 : // Read loop
136 : bool found_sep = false;
137 1508 : while(!s.empty()) {
138 : // Read
139 1508 : std::vector<unsigned char> key;
140 1508 : s >> key;
141 :
142 : // the key is empty if that was actually a separator byte
143 : // This is a special case for key lengths 0 as those are not allowed (except for separator)
144 1508 : if (key.empty()) {
145 : found_sep = true;
146 437 : break;
147 : }
148 :
149 : // First byte of key is the type
150 1071 : unsigned char type = key[0];
151 :
152 : // Do stuff based on type
153 1071 : switch(type) {
154 : case PSBT_IN_NON_WITNESS_UTXO:
155 : {
156 233 : if (!key_lookup.emplace(key).second) {
157 2 : throw std::ios_base::failure("Duplicate Key, input non-witness utxo already provided");
158 231 : } else if (key.size() != 1) {
159 2 : throw std::ios_base::failure("Non-witness utxo key is more than one byte type");
160 : }
161 : // Set the stream to unserialize with witness since this is always a valid network transaction
162 229 : OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() & ~SERIALIZE_TRANSACTION_NO_WITNESS);
163 229 : UnserializeFromVector(os, non_witness_utxo);
164 : break;
165 229 : }
166 : case PSBT_IN_WITNESS_UTXO:
167 215 : if (!key_lookup.emplace(key).second) {
168 2 : throw std::ios_base::failure("Duplicate Key, input witness utxo already provided");
169 213 : } else if (key.size() != 1) {
170 2 : throw std::ios_base::failure("Witness utxo key is more than one byte type");
171 : }
172 211 : UnserializeFromVector(s, witness_utxo);
173 : break;
174 : case PSBT_IN_PARTIAL_SIG:
175 : {
176 : // Make sure that the key is the size of pubkey + 1
177 46 : if (key.size() != CPubKey::SIZE + 1 && key.size() != CPubKey::COMPRESSED_SIZE + 1) {
178 2 : throw std::ios_base::failure("Size of key was not the expected size for the type partial signature pubkey");
179 : }
180 : // Read in the pubkey from key
181 44 : CPubKey pubkey(key.begin() + 1, key.end());
182 44 : if (!pubkey.IsFullyValid()) {
183 0 : throw std::ios_base::failure("Invalid pubkey");
184 : }
185 44 : if (partial_sigs.count(pubkey.GetID()) > 0) {
186 0 : throw std::ios_base::failure("Duplicate Key, input partial signature for pubkey already provided");
187 : }
188 :
189 : // Read in the signature from value
190 44 : std::vector<unsigned char> sig;
191 44 : s >> sig;
192 :
193 : // Add to list
194 44 : partial_sigs.emplace(pubkey.GetID(), SigPair(pubkey, std::move(sig)));
195 : break;
196 44 : }
197 : case PSBT_IN_SIGHASH:
198 42 : if (!key_lookup.emplace(key).second) {
199 2 : throw std::ios_base::failure("Duplicate Key, input sighash type already provided");
200 40 : } else if (key.size() != 1) {
201 2 : throw std::ios_base::failure("Sighash type key is more than one byte type");
202 : }
203 38 : UnserializeFromVector(s, sighash_type);
204 : break;
205 : case PSBT_IN_REDEEMSCRIPT:
206 : {
207 107 : if (!key_lookup.emplace(key).second) {
208 2 : throw std::ios_base::failure("Duplicate Key, input redeemScript already provided");
209 105 : } else if (key.size() != 1) {
210 2 : throw std::ios_base::failure("Input redeemScript key is more than one byte type");
211 : }
212 103 : s >> redeem_script;
213 : break;
214 : }
215 : case PSBT_IN_WITNESSSCRIPT:
216 : {
217 58 : if (!key_lookup.emplace(key).second) {
218 2 : throw std::ios_base::failure("Duplicate Key, input witnessScript already provided");
219 56 : } else if (key.size() != 1) {
220 2 : throw std::ios_base::failure("Input witnessScript key is more than one byte type");
221 : }
222 54 : s >> witness_script;
223 : break;
224 : }
225 : case PSBT_IN_BIP32_DERIVATION:
226 : {
227 262 : DeserializeHDKeypaths(s, key, hd_keypaths);
228 : break;
229 : }
230 : case PSBT_IN_SCRIPTSIG:
231 : {
232 55 : if (!key_lookup.emplace(key).second) {
233 2 : throw std::ios_base::failure("Duplicate Key, input final scriptSig already provided");
234 53 : } else if (key.size() != 1) {
235 2 : throw std::ios_base::failure("Final scriptSig key is more than one byte type");
236 : }
237 51 : s >> final_script_sig;
238 : break;
239 : }
240 : case PSBT_IN_SCRIPTWITNESS:
241 : {
242 47 : if (!key_lookup.emplace(key).second) {
243 2 : throw std::ios_base::failure("Duplicate Key, input final scriptWitness already provided");
244 45 : } else if (key.size() != 1) {
245 2 : throw std::ios_base::failure("Final scriptWitness key is more than one byte type");
246 : }
247 43 : UnserializeFromVector(s, final_script_witness.stack);
248 : break;
249 : }
250 : // Unknown stuff
251 : default:
252 6 : if (unknown.count(key) > 0) {
253 0 : throw std::ios_base::failure("Duplicate Key, key for unknown value already provided");
254 : }
255 : // Read in the value
256 6 : std::vector<unsigned char> val_bytes;
257 6 : s >> val_bytes;
258 6 : unknown.emplace(std::move(key), std::move(val_bytes));
259 : break;
260 6 : }
261 1508 : }
262 :
263 437 : if (!found_sep) {
264 0 : throw std::ios_base::failure("Separator is missing at the end of an input map");
265 : }
266 501 : }
267 :
268 : template <typename Stream>
269 : PSBTInput(deserialize_type, Stream& s) {
270 : Unserialize(s);
271 : }
272 : };
273 :
274 : /** A structure for PSBTs which contains per output information */
275 3944 : struct PSBTOutput
276 : {
277 : CScript redeem_script;
278 : CScript witness_script;
279 : std::map<CPubKey, KeyOriginInfo> hd_keypaths;
280 : std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
281 :
282 : bool IsNull() const;
283 : void FillSignatureData(SignatureData& sigdata) const;
284 : void FromSignatureData(const SignatureData& sigdata);
285 : void Merge(const PSBTOutput& output);
286 1248 : PSBTOutput() {}
287 :
288 : template <typename Stream>
289 394 : inline void Serialize(Stream& s) const {
290 : // Write the redeem script
291 394 : if (!redeem_script.empty()) {
292 39 : SerializeToVector(s, PSBT_OUT_REDEEMSCRIPT);
293 39 : s << redeem_script;
294 39 : }
295 :
296 : // Write the witness script
297 394 : if (!witness_script.empty()) {
298 24 : SerializeToVector(s, PSBT_OUT_WITNESSSCRIPT);
299 24 : s << witness_script;
300 24 : }
301 :
302 : // Write any hd keypaths
303 394 : SerializeHDKeypaths(s, hd_keypaths, PSBT_OUT_BIP32_DERIVATION);
304 :
305 : // Write unknown things
306 398 : for (auto& entry : unknown) {
307 4 : s << entry.first;
308 4 : s << entry.second;
309 : }
310 :
311 394 : s << PSBT_SEPARATOR;
312 394 : }
313 :
314 :
315 : template <typename Stream>
316 400 : inline void Unserialize(Stream& s) {
317 : // Used for duplicate key detection
318 400 : std::set<std::vector<unsigned char>> key_lookup;
319 :
320 : // Read loop
321 : bool found_sep = false;
322 666 : while(!s.empty()) {
323 : // Read
324 666 : std::vector<unsigned char> key;
325 666 : s >> key;
326 :
327 : // the key is empty if that was actually a separator byte
328 : // This is a special case for key lengths 0 as those are not allowed (except for separator)
329 666 : if (key.empty()) {
330 : found_sep = true;
331 390 : break;
332 : }
333 :
334 : // First byte of key is the type
335 276 : unsigned char type = key[0];
336 :
337 : // Do stuff based on type
338 276 : switch(type) {
339 : case PSBT_OUT_REDEEMSCRIPT:
340 : {
341 49 : if (!key_lookup.emplace(key).second) {
342 2 : throw std::ios_base::failure("Duplicate Key, output redeemScript already provided");
343 47 : } else if (key.size() != 1) {
344 2 : throw std::ios_base::failure("Output redeemScript key is more than one byte type");
345 : }
346 45 : s >> redeem_script;
347 : break;
348 : }
349 : case PSBT_OUT_WITNESSSCRIPT:
350 : {
351 30 : if (!key_lookup.emplace(key).second) {
352 2 : throw std::ios_base::failure("Duplicate Key, output witnessScript already provided");
353 28 : } else if (key.size() != 1) {
354 2 : throw std::ios_base::failure("Output witnessScript key is more than one byte type");
355 : }
356 26 : s >> witness_script;
357 : break;
358 : }
359 : case PSBT_OUT_BIP32_DERIVATION:
360 : {
361 193 : DeserializeHDKeypaths(s, key, hd_keypaths);
362 : break;
363 : }
364 : // Unknown stuff
365 : default: {
366 4 : if (unknown.count(key) > 0) {
367 0 : throw std::ios_base::failure("Duplicate Key, key for unknown value already provided");
368 : }
369 : // Read in the value
370 4 : std::vector<unsigned char> val_bytes;
371 4 : s >> val_bytes;
372 4 : unknown.emplace(std::move(key), std::move(val_bytes));
373 : break;
374 4 : }
375 : }
376 666 : }
377 :
378 390 : if (!found_sep) {
379 0 : throw std::ios_base::failure("Separator is missing at the end of an output map");
380 : }
381 410 : }
382 :
383 : template <typename Stream>
384 : PSBTOutput(deserialize_type, Stream& s) {
385 : Unserialize(s);
386 : }
387 : };
388 :
389 : /** A version of CTransaction with the PSBT format*/
390 1252 : struct PartiallySignedTransaction
391 : {
392 : Optional<CMutableTransaction> tx;
393 : std::vector<PSBTInput> inputs;
394 : std::vector<PSBTOutput> outputs;
395 : std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
396 :
397 : bool IsNull() const;
398 :
399 : /** Merge psbt into this. The two psbts must have the same underlying CTransaction (i.e. the
400 : * same actual Bitcoin transaction.) Returns true if the merge succeeded, false otherwise. */
401 : NODISCARD bool Merge(const PartiallySignedTransaction& psbt);
402 : bool AddInput(const CTxIn& txin, PSBTInput& psbtin);
403 : bool AddOutput(const CTxOut& txout, const PSBTOutput& psbtout);
404 892 : PartiallySignedTransaction() {}
405 : explicit PartiallySignedTransaction(const CMutableTransaction& tx);
406 : /**
407 : * Finds the UTXO for a given input index
408 : *
409 : * @param[out] utxo The UTXO of the input if found
410 : * @param[in] input_index Index of the input to retrieve the UTXO of
411 : * @return Whether the UTXO for the specified input was found
412 : */
413 : bool GetInputUTXO(CTxOut& utxo, int input_index) const;
414 :
415 : template <typename Stream>
416 284 : inline void Serialize(Stream& s) const {
417 :
418 : // magic bytes
419 284 : s << PSBT_MAGIC_BYTES;
420 :
421 : // unsigned tx flag
422 284 : SerializeToVector(s, PSBT_GLOBAL_UNSIGNED_TX);
423 :
424 : // Write serialized tx to a stream
425 284 : OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS);
426 284 : SerializeToVector(os, *tx);
427 :
428 : // Write the unknown things
429 288 : for (auto& entry : unknown) {
430 4 : s << entry.first;
431 4 : s << entry.second;
432 : }
433 :
434 : // Separator
435 284 : s << PSBT_SEPARATOR;
436 :
437 : // Write inputs
438 676 : for (const PSBTInput& input : inputs) {
439 392 : s << input;
440 : }
441 : // Write outputs
442 678 : for (const PSBTOutput& output : outputs) {
443 394 : s << output;
444 : }
445 284 : }
446 :
447 :
448 : template <typename Stream>
449 344 : inline void Unserialize(Stream& s) {
450 : // Read the magic bytes
451 344 : uint8_t magic[5];
452 344 : s >> magic;
453 344 : if (!std::equal(magic, magic + 5, PSBT_MAGIC_BYTES)) {
454 4 : throw std::ios_base::failure("Invalid PSBT magic bytes");
455 : }
456 :
457 : // Used for duplicate key detection
458 340 : std::set<std::vector<unsigned char>> key_lookup;
459 :
460 : // Read global data
461 : bool found_sep = false;
462 678 : while(!s.empty()) {
463 : // Read
464 678 : std::vector<unsigned char> key;
465 678 : s >> key;
466 :
467 : // the key is empty if that was actually a separator byte
468 : // This is a special case for key lengths 0 as those are not allowed (except for separator)
469 678 : if (key.empty()) {
470 : found_sep = true;
471 336 : break;
472 : }
473 :
474 : // First byte of key is the type
475 342 : unsigned char type = key[0];
476 :
477 : // Do stuff based on type
478 342 : switch(type) {
479 : case PSBT_GLOBAL_UNSIGNED_TX:
480 : {
481 338 : if (!key_lookup.emplace(key).second) {
482 0 : throw std::ios_base::failure("Duplicate Key, unsigned tx already provided");
483 338 : } else if (key.size() != 1) {
484 2 : throw std::ios_base::failure("Global unsigned tx key is more than one byte type");
485 : }
486 336 : CMutableTransaction mtx;
487 : // Set the stream to serialize with non-witness since this should always be non-witness
488 336 : OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS);
489 336 : UnserializeFromVector(os, mtx);
490 336 : tx = std::move(mtx);
491 : // Make sure that all scriptSigs and scriptWitnesses are empty
492 811 : for (const CTxIn& txin : tx->vin) {
493 475 : if (!txin.scriptSig.empty() || !txin.scriptWitness.IsNull()) {
494 2 : throw std::ios_base::failure("Unsigned tx does not have empty scriptSigs and scriptWitnesses.");
495 : }
496 : }
497 : break;
498 336 : }
499 : // Unknown stuff
500 : default: {
501 4 : if (unknown.count(key) > 0) {
502 0 : throw std::ios_base::failure("Duplicate Key, key for unknown value already provided");
503 : }
504 : // Read in the value
505 4 : std::vector<unsigned char> val_bytes;
506 4 : s >> val_bytes;
507 4 : unknown.emplace(std::move(key), std::move(val_bytes));
508 4 : }
509 4 : }
510 678 : }
511 :
512 336 : if (!found_sep) {
513 0 : throw std::ios_base::failure("Separator is missing at the end of the global map");
514 : }
515 :
516 : // Make sure that we got an unsigned tx
517 336 : if (!tx) {
518 2 : throw std::ios_base::failure("No unsigned transcation was provided");
519 : }
520 :
521 : // Read input data
522 : unsigned int i = 0;
523 771 : while (!s.empty() && i < tx->vin.size()) {
524 469 : PSBTInput input;
525 469 : s >> input;
526 437 : inputs.push_back(input);
527 :
528 : // Make sure the non-witness utxo matches the outpoint
529 437 : if (input.non_witness_utxo && input.non_witness_utxo->GetHash() != tx->vin[i].prevout.hash) {
530 0 : throw std::ios_base::failure("Non-witness UTXO does not match outpoint hash");
531 : }
532 437 : ++i;
533 469 : }
534 : // Make sure that the number of inputs matches the number of inputs in the transaction
535 302 : if (inputs.size() != tx->vin.size()) {
536 0 : throw std::ios_base::failure("Inputs provided does not match the number of inputs in transaction.");
537 : }
538 :
539 : // Read output data
540 : i = 0;
541 692 : while (!s.empty() && i < tx->vout.size()) {
542 400 : PSBTOutput output;
543 400 : s >> output;
544 390 : outputs.push_back(output);
545 390 : ++i;
546 400 : }
547 : // Make sure that the number of outputs matches the number of outputs in the transaction
548 292 : if (outputs.size() != tx->vout.size()) {
549 2 : throw std::ios_base::failure("Outputs provided does not match the number of outputs in transaction.");
550 : }
551 380 : }
552 :
553 : template <typename Stream>
554 : PartiallySignedTransaction(deserialize_type, Stream& s) {
555 : Unserialize(s);
556 : }
557 : };
558 :
559 : enum class PSBTRole {
560 : CREATOR,
561 : UPDATER,
562 : SIGNER,
563 : FINALIZER,
564 : EXTRACTOR
565 : };
566 :
567 : std::string PSBTRoleName(PSBTRole role);
568 :
569 : /** Checks whether a PSBTInput is already signed. */
570 : bool PSBTInputSigned(const PSBTInput& input);
571 :
572 : /** Signs a PSBTInput, verifying that all provided data matches what is being signed. */
573 : bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash = SIGHASH_ALL, SignatureData* out_sigdata = nullptr, bool use_dummy = false);
574 :
575 : /** Counts the unsigned inputs of a PSBT. */
576 : size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction& psbt);
577 :
578 : /** Updates a PSBTOutput with information from provider.
579 : *
580 : * This fills in the redeem_script, witness_script, and hd_keypaths where possible.
581 : */
582 : void UpdatePSBTOutput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index);
583 :
584 : /**
585 : * Finalizes a PSBT if possible, combining partial signatures.
586 : *
587 : * @param[in,out] psbtx PartiallySignedTransaction to finalize
588 : * return True if the PSBT is now complete, false otherwise
589 : */
590 : bool FinalizePSBT(PartiallySignedTransaction& psbtx);
591 :
592 : /**
593 : * Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized.
594 : *
595 : * @param[in] psbtx PartiallySignedTransaction
596 : * @param[out] result CMutableTransaction representing the complete transaction, if successful
597 : * @return True if we successfully extracted the transaction, false otherwise
598 : */
599 : bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransaction& result);
600 :
601 : /**
602 : * Combines PSBTs with the same underlying transaction, resulting in a single PSBT with all partial signatures from each input.
603 : *
604 : * @param[out] out the combined PSBT, if successful
605 : * @param[in] psbtxs the PSBTs to combine
606 : * @return error (OK if we successfully combined the transactions, other error if they were not compatible)
607 : */
608 : NODISCARD TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs);
609 :
610 : //! Decode a base64ed PSBT into a PartiallySignedTransaction
611 : NODISCARD bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error);
612 : //! Decode a raw (binary blob) PSBT into a PartiallySignedTransaction
613 : NODISCARD bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, const std::string& raw_psbt, std::string& error);
614 :
615 : #endif // BITCOIN_PSBT_H
|