Bitcoin ABC 0.34.2
P2P Digital Currency
psbt.h
Go to the documentation of this file.
1// Copyright (c) 2009-2019 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 <node/transaction.h>
10#include <pubkey.h>
11#include <script/sign.h>
13
14#include <optional>
15
16// Magic bytes
17static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff};
18
19// Global types
20static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00;
21
22// Input types
23static constexpr uint8_t PSBT_IN_UTXO = 0x00;
24static constexpr uint8_t PSBT_IN_PARTIAL_SIG = 0x02;
25static constexpr uint8_t PSBT_IN_SIGHASH = 0x03;
26static constexpr uint8_t PSBT_IN_REDEEMSCRIPT = 0x04;
27static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
28static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
29
30// Output types
31static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00;
32static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02;
33
34// The separator is 0x00. Reading this in means that the unserializer can
35// interpret it as a 0 length key which indicates that this is the separator.
36// The separator has no value.
37static constexpr uint8_t PSBT_SEPARATOR = 0x00;
38
39// BIP 174 does not specify a maximum file size, but we set a limit anyway
40// to prevent reading a stream indefinitely and running out of memory.
41const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MiB
42
44struct PSBTInput {
48 std::map<CPubKey, KeyOriginInfo> hd_keypaths;
49 std::map<CKeyID, SigPair> partial_sigs;
50 std::map<std::vector<uint8_t>, std::vector<uint8_t>> unknown;
51 std::optional<SigHashType> sighash_type;
52
53 bool IsNull() const;
54 void FillSignatureData(SignatureData &sigdata) const;
55 void FromSignatureData(const SignatureData &sigdata);
56 void Merge(const PSBTInput &input);
57 PSBTInput() = default;
58
59 template <typename Stream> inline void Serialize(Stream &s) const {
60 // Write the utxo
61 if (!utxo.IsNull()) {
64 }
65
66 if (final_script_sig.empty()) {
67 // Write any partial signatures
68 for (auto sig_pair : partial_sigs) {
70 Span{sig_pair.second.first});
71 s << sig_pair.second.second;
72 }
73
74 // Write the sighash type
75 if (sighash_type != std::nullopt) {
78 }
79
80 // Write the redeem script
81 if (!redeem_script.empty()) {
83 s << redeem_script;
84 }
85
86 // Write any hd keypaths
88 }
89
90 // Write script sig
91 if (!final_script_sig.empty()) {
94 }
95
96 // Write unknown things
97 for (auto &entry : unknown) {
98 s << entry.first;
99 s << entry.second;
100 }
101
102 s << PSBT_SEPARATOR;
103 }
104
105 template <typename Stream> inline void Unserialize(Stream &s) {
106 // Used for duplicate key detection
107 std::set<std::vector<uint8_t>> key_lookup;
108
109 // Read loop
110 bool found_sep = false;
111 while (!s.empty()) {
112 // Read
113 std::vector<uint8_t> key;
114 s >> key;
115
116 // the key is empty if that was actually a separator byte
117 // This is a special case for key lengths 0 as those are not allowed
118 // (except for separator)
119 if (key.empty()) {
120 found_sep = true;
121 break;
122 }
123
124 // First byte of key is the type
125 uint8_t type = key[0];
126
127 // Do stuff based on type
128 switch (type) {
129 case PSBT_IN_UTXO:
130 if (!key_lookup.emplace(key).second) {
131 throw std::ios_base::failure(
132 "Duplicate Key, input utxo already provided");
133 } else if (key.size() != 1) {
134 throw std::ios_base::failure(
135 "utxo key is more than one byte type");
136 }
138 break;
139 case PSBT_IN_PARTIAL_SIG: {
140 // Make sure that the key is the size of pubkey + 1
141 if (key.size() != CPubKey::SIZE + 1 &&
142 key.size() != CPubKey::COMPRESSED_SIZE + 1) {
143 throw std::ios_base::failure(
144 "Size of key was not the expected size for the "
145 "type partial signature pubkey");
146 }
147 // Read in the pubkey from key
148 CPubKey pubkey(key.begin() + 1, key.end());
149 if (!pubkey.IsFullyValid()) {
150 throw std::ios_base::failure("Invalid pubkey");
151 }
152 if (partial_sigs.count(pubkey.GetID()) > 0) {
153 throw std::ios_base::failure(
154 "Duplicate Key, input partial signature for pubkey "
155 "already provided");
156 }
157
158 // Read in the signature from value
159 std::vector<uint8_t> sig;
160 s >> sig;
161
162 // Add to list
163 partial_sigs.emplace(pubkey.GetID(),
164 SigPair(pubkey, std::move(sig)));
165 break;
166 }
167 case PSBT_IN_SIGHASH:
168 if (!key_lookup.emplace(key).second) {
169 throw std::ios_base::failure(
170 "Duplicate Key, input sighash type already "
171 "provided");
172 } else if (key.size() != 1) {
173 throw std::ios_base::failure(
174 "Sighash type key is more than one byte type");
175 }
176 int sighash;
177 UnserializeFromVector(s, sighash);
178 sighash_type = SigHashType(sighash);
179 break;
181 if (!key_lookup.emplace(key).second) {
182 throw std::ios_base::failure(
183 "Duplicate Key, input redeemScript already "
184 "provided");
185 } else if (key.size() != 1) {
186 throw std::ios_base::failure(
187 "Input redeemScript key is more than one byte "
188 "type");
189 }
190 s >> redeem_script;
191 break;
192 }
195 break;
196 }
197 case PSBT_IN_SCRIPTSIG: {
198 if (!key_lookup.emplace(key).second) {
199 throw std::ios_base::failure(
200 "Duplicate Key, input final scriptSig already "
201 "provided");
202 } else if (key.size() != 1) {
203 throw std::ios_base::failure(
204 "Final scriptSig key is more than one byte type");
205 }
206 s >> final_script_sig;
207 break;
208 }
209 // Unknown stuff
210 default:
211 if (unknown.count(key) > 0) {
212 throw std::ios_base::failure(
213 "Duplicate Key, key for unknown value already "
214 "provided");
215 }
216 // Read in the value
217 std::vector<uint8_t> val_bytes;
218 s >> val_bytes;
219 unknown.emplace(std::move(key), std::move(val_bytes));
220 break;
221 }
222 }
223 if (!found_sep) {
224 throw std::ios_base::failure(
225 "Separator is missing at the end of an input map");
226 }
227 }
228
229 template <typename Stream> PSBTInput(deserialize_type, Stream &s) {
230 Unserialize(s);
231 }
232};
233
237 std::map<CPubKey, KeyOriginInfo> hd_keypaths;
238 std::map<std::vector<uint8_t>, std::vector<uint8_t>> unknown;
239
240 bool IsNull() const;
241 void FillSignatureData(SignatureData &sigdata) const;
242 void FromSignatureData(const SignatureData &sigdata);
243 void Merge(const PSBTOutput &output);
244 PSBTOutput() = default;
245
246 template <typename Stream> inline void Serialize(Stream &s) const {
247 // Write the redeem script
248 if (!redeem_script.empty()) {
250 s << redeem_script;
251 }
252
253 // Write any hd keypaths
255
256 // Write unknown things
257 for (auto &entry : unknown) {
258 s << entry.first;
259 s << entry.second;
260 }
261
262 s << PSBT_SEPARATOR;
263 }
264
265 template <typename Stream> inline void Unserialize(Stream &s) {
266 // Used for duplicate key detection
267 std::set<std::vector<uint8_t>> key_lookup;
268
269 // Read loop
270 bool found_sep = false;
271 while (!s.empty()) {
272 // Read
273 std::vector<uint8_t> key;
274 s >> key;
275
276 // the key is empty if that was actually a separator byte
277 // This is a special case for key lengths 0 as those are not allowed
278 // (except for separator)
279 if (key.empty()) {
280 found_sep = true;
281 break;
282 }
283
284 // First byte of key is the type
285 uint8_t type = key[0];
286
287 // Do stuff based on type
288 switch (type) {
290 if (!key_lookup.emplace(key).second) {
291 throw std::ios_base::failure(
292 "Duplicate Key, output redeemScript already "
293 "provided");
294 } else if (key.size() != 1) {
295 throw std::ios_base::failure(
296 "Output redeemScript key is more than one byte "
297 "type");
298 }
299 s >> redeem_script;
300 break;
301 }
304 break;
305 }
306 // Unknown stuff
307 default: {
308 if (unknown.count(key) > 0) {
309 throw std::ios_base::failure(
310 "Duplicate Key, key for unknown value already "
311 "provided");
312 }
313 // Read in the value
314 std::vector<uint8_t> val_bytes;
315 s >> val_bytes;
316 unknown.emplace(std::move(key), std::move(val_bytes));
317 break;
318 }
319 }
320 }
321
322 if (!found_sep) {
323 throw std::ios_base::failure(
324 "Separator is missing at the end of an output map");
325 }
326 }
327
328 template <typename Stream> PSBTOutput(deserialize_type, Stream &s) {
329 Unserialize(s);
330 }
331};
332
337 std::optional<CMutableTransaction> tx;
338 std::vector<PSBTInput> inputs;
339 std::vector<PSBTOutput> outputs;
340 std::map<std::vector<uint8_t>, std::vector<uint8_t>> unknown;
341
342 bool IsNull() const;
343
349 [[nodiscard]] bool Merge(const PartiallySignedTransaction &psbt);
350 bool AddInput(const CTxIn &txin, PSBTInput &psbtin);
351 bool AddOutput(const CTxOut &txout, const PSBTOutput &psbtout);
361 bool GetInputUTXO(CTxOut &utxo, int input_index) const;
362
363 template <typename Stream> inline void Serialize(Stream &s) const {
364 // magic bytes
365 s << PSBT_MAGIC_BYTES;
366
367 // unsigned tx flag
369
370 // Write serialized tx to a stream
372
373 // Write the unknown things
374 for (auto &entry : unknown) {
375 s << entry.first;
376 s << entry.second;
377 }
378
379 // Separator
380 s << PSBT_SEPARATOR;
381
382 // Write inputs
383 for (const PSBTInput &input : inputs) {
384 s << input;
385 }
386
387 // Write outputs
388 for (const PSBTOutput &output : outputs) {
389 s << output;
390 }
391 }
392
393 template <typename Stream> inline void Unserialize(Stream &s) {
394 // Read the magic bytes
395 uint8_t magic[5];
396 s >> magic;
397 if (!std::equal(magic, magic + 5, PSBT_MAGIC_BYTES)) {
398 throw std::ios_base::failure("Invalid PSBT magic bytes");
399 }
400
401 // Used for duplicate key detection
402 std::set<std::vector<uint8_t>> key_lookup;
403
404 // Read global data
405 bool found_sep = false;
406 while (!s.empty()) {
407 // Read
408 std::vector<uint8_t> key;
409 s >> key;
410
411 // the key is empty if that was actually a separator byte
412 // This is a special case for key lengths 0 as those are not allowed
413 // (except for separator)
414 if (key.empty()) {
415 found_sep = true;
416 break;
417 }
418
419 // First byte of key is the type
420 uint8_t type = key[0];
421
422 // Do stuff based on type
423 switch (type) {
425 if (!key_lookup.emplace(key).second) {
426 throw std::ios_base::failure(
427 "Duplicate Key, unsigned tx already provided");
428 } else if (key.size() != 1) {
429 throw std::ios_base::failure(
430 "Global unsigned tx key is more than one byte "
431 "type");
432 }
434 UnserializeFromVector(s, mtx);
435 tx = std::move(mtx);
436 // Make sure that all scriptSigs are empty.
437 for (const CTxIn &txin : tx->vin) {
438 if (!txin.scriptSig.empty()) {
439 throw std::ios_base::failure(
440 "Unsigned tx does not have empty scriptSigs.");
441 }
442 }
443 break;
444 }
445 // Unknown stuff
446 default: {
447 if (unknown.count(key) > 0) {
448 throw std::ios_base::failure(
449 "Duplicate Key, key for unknown value already "
450 "provided");
451 }
452 // Read in the value
453 std::vector<uint8_t> val_bytes;
454 s >> val_bytes;
455 unknown.emplace(std::move(key), std::move(val_bytes));
456 }
457 }
458 }
459
460 if (!found_sep) {
461 throw std::ios_base::failure(
462 "Separator is missing at the end of the global map");
463 }
464
465 // Make sure that we got an unsigned tx
466 if (!tx) {
467 throw std::ios_base::failure(
468 "No unsigned transcation was provided");
469 }
470
471 // Read input data
472 size_t i = 0;
473 while (!s.empty() && i < tx->vin.size()) {
474 PSBTInput input;
475 s >> input;
476 inputs.push_back(input);
477 ++i;
478 }
479 // Make sure that the number of inputs matches the number of inputs in
480 // the transaction
481 if (inputs.size() != tx->vin.size()) {
482 throw std::ios_base::failure("Inputs provided does not match the "
483 "number of inputs in transaction.");
484 }
485
486 // Read output data
487 i = 0;
488 while (!s.empty() && i < tx->vout.size()) {
489 PSBTOutput output;
490 s >> output;
491 outputs.push_back(output);
492 ++i;
493 }
494 // Make sure that the number of outputs matches the number of outputs in
495 // the transaction
496 if (outputs.size() != tx->vout.size()) {
497 throw std::ios_base::failure("Outputs provided does not match the "
498 "number of outputs in transaction.");
499 }
500 }
501
502 template <typename Stream>
504 Unserialize(s);
505 }
506};
507
508enum class PSBTRole {
509 CREATOR,
510 UPDATER,
511 SIGNER,
512 FINALIZER,
513 EXTRACTOR,
514};
515
516std::string PSBTRoleName(PSBTRole role);
517
519bool PSBTInputSigned(const PSBTInput &input);
520
525bool SignPSBTInput(const SigningProvider &provider,
526 PartiallySignedTransaction &psbt, int index,
527 SigHashType sighash = SigHashType(),
528 SignatureData *out_sigdata = nullptr, bool use_dummy = false,
529 bool finalize = true);
530
537void UpdatePSBTOutput(const SigningProvider &provider,
538 PartiallySignedTransaction &psbt, int index);
539
547
558 CMutableTransaction &result);
559
569[[nodiscard]] bool
571 const std::vector<PartiallySignedTransaction> &psbtxs);
572
574[[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction &decoded_psbt,
575 const std::string &base64_psbt,
576 std::string &error);
578[[nodiscard]] bool DecodeRawPSBT(PartiallySignedTransaction &decoded_psbt,
579 Span<const std::byte> raw_psbt,
580 std::string &error);
581
582#endif // BITCOIN_PSBT_H
A mutable version of CTransaction.
Definition: transaction.h:274
An encapsulated public key.
Definition: pubkey.h:31
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:137
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:37
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:36
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition: pubkey.cpp:261
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:434
An input of a transaction.
Definition: transaction.h:59
CScript scriptSig
Definition: transaction.h:62
An output of a transaction.
Definition: transaction.h:128
bool IsNull() const
Definition: transaction.h:145
Signature hash type wrapper class.
Definition: sighashtype.h:37
An interface to be implemented by keystores that support signing.
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:94
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Definition: span.h:228
bool empty() const
Definition: prevector.h:400
SchnorrSig sig
Definition: processor.cpp:538
static constexpr uint8_t PSBT_IN_UTXO
Definition: psbt.h:23
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
Definition: psbt.cpp:164
static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX
Definition: psbt.h:20
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, SigHashType sighash=SigHashType(), SignatureData *out_sigdata=nullptr, bool use_dummy=false, bool finalize=true)
Signs a PSBTInput, verifying that all provided data matches what is being signed.
Definition: psbt.cpp:186
static constexpr uint8_t PSBT_IN_SCRIPTSIG
Definition: psbt.h:28
std::string PSBTRoleName(PSBTRole role)
Definition: psbt.cpp:285
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT
Definition: psbt.h:31
bool CombinePSBTs(PartiallySignedTransaction &out, const std::vector< PartiallySignedTransaction > &psbtxs)
Combines PSBTs with the same underlying transaction, resulting in a single PSBT with all partial sign...
Definition: psbt.cpp:271
static constexpr uint8_t PSBT_MAGIC_BYTES[5]
Definition: psbt.h:17
static constexpr uint8_t PSBT_SEPARATOR
Definition: psbt.h:37
static constexpr uint8_t PSBT_IN_BIP32_DERIVATION
Definition: psbt.h:27
static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION
Definition: psbt.h:32
PSBTRole
Definition: psbt.h:508
bool DecodeRawPSBT(PartiallySignedTransaction &decoded_psbt, Span< const std::byte > raw_psbt, std::string &error)
Decode a raw (binary blob) PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:312
static constexpr uint8_t PSBT_IN_REDEEMSCRIPT
Definition: psbt.h:26
bool DecodeBase64PSBT(PartiallySignedTransaction &decoded_psbt, const std::string &base64_psbt, std::string &error)
Decode a base64ed PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:302
static constexpr uint8_t PSBT_IN_PARTIAL_SIG
Definition: psbt.h:24
bool FinalizeAndExtractPSBT(PartiallySignedTransaction &psbtx, CMutableTransaction &result)
Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized.
Definition: psbt.cpp:255
static constexpr uint8_t PSBT_IN_SIGHASH
Definition: psbt.h:25
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed.
Definition: psbt.cpp:160
bool FinalizePSBT(PartiallySignedTransaction &psbtx)
Finalizes a PSBT if possible, combining partial signatures.
Definition: psbt.cpp:239
const std::streamsize MAX_FILE_SIZE_PSBT
Definition: psbt.h:41
void UnserializeFromVector(Stream &s, X &...args)
Definition: sign.h:106
void SerializeToVector(Stream &s, const X &...args)
Definition: sign.h:96
void SerializeHDKeypaths(Stream &s, const std::map< CPubKey, KeyOriginInfo > &hd_keypaths, uint8_t type)
Definition: sign.h:156
void DeserializeHDKeypaths(Stream &s, const std::vector< uint8_t > &key, std::map< CPubKey, KeyOriginInfo > &hd_keypaths)
Definition: sign.h:118
std::pair< CPubKey, std::vector< uint8_t > > SigPair
Definition: sign.h:61
A structure for PSBTs which contain per-input information.
Definition: psbt.h:44
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:48
PSBTInput(deserialize_type, Stream &s)
Definition: psbt.h:229
std::map< CKeyID, SigPair > partial_sigs
Definition: psbt.h:49
void Serialize(Stream &s) const
Definition: psbt.h:59
std::optional< SigHashType > sighash_type
Definition: psbt.h:51
void FillSignatureData(SignatureData &sigdata) const
Definition: psbt.cpp:73
bool IsNull() const
Definition: psbt.cpp:68
void Merge(const PSBTInput &input)
Definition: psbt.cpp:112
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:50
void Unserialize(Stream &s)
Definition: psbt.h:105
PSBTInput()=default
CScript redeem_script
Definition: psbt.h:46
CScript final_script_sig
Definition: psbt.h:47
void FromSignatureData(const SignatureData &sigdata)
Definition: psbt.cpp:91
CTxOut utxo
Definition: psbt.h:45
A structure for PSBTs which contains per output information.
Definition: psbt.h:235
bool IsNull() const
Definition: psbt.cpp:147
void Merge(const PSBTOutput &output)
Definition: psbt.cpp:151
CScript redeem_script
Definition: psbt.h:236
void Serialize(Stream &s) const
Definition: psbt.h:246
PSBTOutput(deserialize_type, Stream &s)
Definition: psbt.h:328
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:237
PSBTOutput()=default
void Unserialize(Stream &s)
Definition: psbt.h:265
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:238
void FillSignatureData(SignatureData &sigdata) const
Definition: psbt.cpp:129
void FromSignatureData(const SignatureData &sigdata)
Definition: psbt.cpp:138
A version of CTransaction with the PSBT format.
Definition: psbt.h:336
bool Merge(const PartiallySignedTransaction &psbt)
Merge psbt into this.
Definition: psbt.cpp:21
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:340
bool IsNull() const
Definition: psbt.cpp:17
bool GetInputUTXO(CTxOut &utxo, int input_index) const
Finds the UTXO for a given input index.
Definition: psbt.cpp:57
bool AddOutput(const CTxOut &txout, const PSBTOutput &psbtout)
Definition: psbt.cpp:50
std::vector< PSBTInput > inputs
Definition: psbt.h:338
PartiallySignedTransaction()=default
std::optional< CMutableTransaction > tx
Definition: psbt.h:337
bool AddInput(const CTxIn &txin, PSBTInput &psbtin)
Definition: psbt.cpp:38
std::vector< PSBTOutput > outputs
Definition: psbt.h:339
void Serialize(Stream &s) const
Definition: psbt.h:363
PartiallySignedTransaction(deserialize_type, Stream &s)
Definition: psbt.h:503
void Unserialize(Stream &s)
Definition: psbt.h:393
Dummy data type to identify deserializing constructors.
Definition: serialize.h:52