Bitcoin ABC  0.22.13
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 <attributes.h>
9 #include <node/transaction.h>
10 #include <primitives/transaction.h>
11 #include <pubkey.h>
12 #include <script/sign.h>
13 #include <script/signingprovider.h>
14 
15 // Magic bytes
16 static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff};
17 
18 // Global types
19 static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00;
20 
21 // Input types
22 static constexpr uint8_t PSBT_IN_UTXO = 0x00;
23 static constexpr uint8_t PSBT_IN_PARTIAL_SIG = 0x02;
24 static constexpr uint8_t PSBT_IN_SIGHASH = 0x03;
25 static constexpr uint8_t PSBT_IN_REDEEMSCRIPT = 0x04;
26 static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
27 static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
28 
29 // Output types
30 static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00;
31 static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02;
32 
33 // The separator is 0x00. Reading this in means that the unserializer can
34 // interpret it as a 0 length key which indicates that this is the separator.
35 // The separator has no value.
36 static constexpr uint8_t PSBT_SEPARATOR = 0x00;
37 
38 // BIP 174 does not specify a maximum file size, but we set a limit anyway
39 // to prevent reading a stream indefinitely and running out of memory.
40 const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MiB
41 
43 struct PSBTInput {
47  std::map<CPubKey, KeyOriginInfo> hd_keypaths;
48  std::map<CKeyID, SigPair> partial_sigs;
49  std::map<std::vector<uint8_t>, std::vector<uint8_t>> unknown;
51 
52  bool IsNull() const;
53  void FillSignatureData(SignatureData &sigdata) const;
54  void FromSignatureData(const SignatureData &sigdata);
55  void Merge(const PSBTInput &input);
56  bool IsSane() const;
57  PSBTInput() {}
58 
59  template <typename Stream> inline void Serialize(Stream &s) const {
60  // Write the utxo
61  if (!utxo.IsNull()) {
63  SerializeToVector(s, utxo);
64  }
65 
66  if (final_script_sig.empty()) {
67  // Write any partial signatures
68  for (auto sig_pair : partial_sigs) {
70  MakeSpan(sig_pair.second.first));
71  s << sig_pair.second.second;
72  }
73 
74  // Write the sighash type
75  if (sighash_type.getRawSigHashType() != 0) {
77  SerializeToVector(s, sighash_type);
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()) {
93  s << final_script_sig;
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  }
137  UnserializeFromVector(s, utxo);
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  UnserializeFromVector(s, sighash_type);
177  break;
178  case PSBT_IN_REDEEMSCRIPT: {
179  if (!key_lookup.emplace(key).second) {
180  throw std::ios_base::failure(
181  "Duplicate Key, input redeemScript already "
182  "provided");
183  } else if (key.size() != 1) {
184  throw std::ios_base::failure(
185  "Input redeemScript key is more than one byte "
186  "type");
187  }
188  s >> redeem_script;
189  break;
190  }
192  DeserializeHDKeypaths(s, key, hd_keypaths);
193  break;
194  }
195  case PSBT_IN_SCRIPTSIG: {
196  if (!key_lookup.emplace(key).second) {
197  throw std::ios_base::failure(
198  "Duplicate Key, input final scriptSig already "
199  "provided");
200  } else if (key.size() != 1) {
201  throw std::ios_base::failure(
202  "Final scriptSig key is more than one byte type");
203  }
204  s >> final_script_sig;
205  break;
206  }
207  // Unknown stuff
208  default:
209  if (unknown.count(key) > 0) {
210  throw std::ios_base::failure(
211  "Duplicate Key, key for unknown value already "
212  "provided");
213  }
214  // Read in the value
215  std::vector<uint8_t> val_bytes;
216  s >> val_bytes;
217  unknown.emplace(std::move(key), std::move(val_bytes));
218  break;
219  }
220  }
221  if (!found_sep) {
222  throw std::ios_base::failure(
223  "Separator is missing at the end of an input map");
224  }
225  }
226 
227  template <typename Stream> PSBTInput(deserialize_type, Stream &s) {
228  Unserialize(s);
229  }
230 };
231 
233 struct PSBTOutput {
235  std::map<CPubKey, KeyOriginInfo> hd_keypaths;
236  std::map<std::vector<uint8_t>, std::vector<uint8_t>> unknown;
237 
238  bool IsNull() const;
239  void FillSignatureData(SignatureData &sigdata) const;
240  void FromSignatureData(const SignatureData &sigdata);
241  void Merge(const PSBTOutput &output);
242  bool IsSane() const;
244 
245  template <typename Stream> inline void Serialize(Stream &s) const {
246  // Write the redeem script
247  if (!redeem_script.empty()) {
249  s << redeem_script;
250  }
251 
252  // Write any hd keypaths
254 
255  // Write unknown things
256  for (auto &entry : unknown) {
257  s << entry.first;
258  s << entry.second;
259  }
260 
261  s << PSBT_SEPARATOR;
262  }
263 
264  template <typename Stream> inline void Unserialize(Stream &s) {
265  // Used for duplicate key detection
266  std::set<std::vector<uint8_t>> key_lookup;
267 
268  // Read loop
269  bool found_sep = false;
270  while (!s.empty()) {
271  // Read
272  std::vector<uint8_t> key;
273  s >> key;
274 
275  // the key is empty if that was actually a separator byte
276  // This is a special case for key lengths 0 as those are not allowed
277  // (except for separator)
278  if (key.empty()) {
279  found_sep = true;
280  break;
281  }
282 
283  // First byte of key is the type
284  uint8_t type = key[0];
285 
286  // Do stuff based on type
287  switch (type) {
288  case PSBT_OUT_REDEEMSCRIPT: {
289  if (!key_lookup.emplace(key).second) {
290  throw std::ios_base::failure(
291  "Duplicate Key, output redeemScript already "
292  "provided");
293  } else if (key.size() != 1) {
294  throw std::ios_base::failure(
295  "Output redeemScript key is more than one byte "
296  "type");
297  }
298  s >> redeem_script;
299  break;
300  }
302  DeserializeHDKeypaths(s, key, hd_keypaths);
303  break;
304  }
305  // Unknown stuff
306  default: {
307  if (unknown.count(key) > 0) {
308  throw std::ios_base::failure(
309  "Duplicate Key, key for unknown value already "
310  "provided");
311  }
312  // Read in the value
313  std::vector<uint8_t> val_bytes;
314  s >> val_bytes;
315  unknown.emplace(std::move(key), std::move(val_bytes));
316  break;
317  }
318  }
319  }
320 
321  if (!found_sep) {
322  throw std::ios_base::failure(
323  "Separator is missing at the end of an output map");
324  }
325  }
326 
327  template <typename Stream> PSBTOutput(deserialize_type, Stream &s) {
328  Unserialize(s);
329  }
330 };
331 
336  std::optional<CMutableTransaction> tx;
337  std::vector<PSBTInput> inputs;
338  std::vector<PSBTOutput> outputs;
339  std::map<std::vector<uint8_t>, std::vector<uint8_t>> unknown;
340 
341  bool IsNull() const;
342 
348  NODISCARD bool Merge(const PartiallySignedTransaction &psbt);
349  bool IsSane() const;
350  bool AddInput(const CTxIn &txin, PSBTInput &psbtin);
351  bool AddOutput(const CTxOut &txout, const PSBTOutput &psbtout);
353  explicit PartiallySignedTransaction(const CMutableTransaction &txIn);
361  bool GetInputUTXO(CTxOut &utxo, int input_index) const;
362 
364  operator=(const PartiallySignedTransaction &other) = default;
365 
366  template <typename Stream> inline void Serialize(Stream &s) const {
367  // magic bytes
368  s << PSBT_MAGIC_BYTES;
369 
370  // unsigned tx flag
372 
373  // Write serialized tx to a stream
374  SerializeToVector(s, *tx);
375 
376  // Write the unknown things
377  for (auto &entry : unknown) {
378  s << entry.first;
379  s << entry.second;
380  }
381 
382  // Separator
383  s << PSBT_SEPARATOR;
384 
385  // Write inputs
386  for (const PSBTInput &input : inputs) {
387  s << input;
388  }
389 
390  // Write outputs
391  for (const PSBTOutput &output : outputs) {
392  s << output;
393  }
394  }
395 
396  template <typename Stream> inline void Unserialize(Stream &s) {
397  // Read the magic bytes
398  uint8_t magic[5];
399  s >> magic;
400  if (!std::equal(magic, magic + 5, PSBT_MAGIC_BYTES)) {
401  throw std::ios_base::failure("Invalid PSBT magic bytes");
402  }
403 
404  // Used for duplicate key detection
405  std::set<std::vector<uint8_t>> key_lookup;
406 
407  // Read global data
408  bool found_sep = false;
409  while (!s.empty()) {
410  // Read
411  std::vector<uint8_t> key;
412  s >> key;
413 
414  // the key is empty if that was actually a separator byte
415  // This is a special case for key lengths 0 as those are not allowed
416  // (except for separator)
417  if (key.empty()) {
418  found_sep = true;
419  break;
420  }
421 
422  // First byte of key is the type
423  uint8_t type = key[0];
424 
425  // Do stuff based on type
426  switch (type) {
428  if (!key_lookup.emplace(key).second) {
429  throw std::ios_base::failure(
430  "Duplicate Key, unsigned tx already provided");
431  } else if (key.size() != 1) {
432  throw std::ios_base::failure(
433  "Global unsigned tx key is more than one byte "
434  "type");
435  }
437  UnserializeFromVector(s, mtx);
438  tx = std::move(mtx);
439  // Make sure that all scriptSigs are empty.
440  for (const CTxIn &txin : tx->vin) {
441  if (!txin.scriptSig.empty()) {
442  throw std::ios_base::failure(
443  "Unsigned tx does not have empty scriptSigs.");
444  }
445  }
446  break;
447  }
448  // Unknown stuff
449  default: {
450  if (unknown.count(key) > 0) {
451  throw std::ios_base::failure(
452  "Duplicate Key, key for unknown value already "
453  "provided");
454  }
455  // Read in the value
456  std::vector<uint8_t> val_bytes;
457  s >> val_bytes;
458  unknown.emplace(std::move(key), std::move(val_bytes));
459  }
460  }
461  }
462 
463  if (!found_sep) {
464  throw std::ios_base::failure(
465  "Separator is missing at the end of the global map");
466  }
467 
468  // Make sure that we got an unsigned tx
469  if (!tx) {
470  throw std::ios_base::failure(
471  "No unsigned transcation was provided");
472  }
473 
474  // Read input data
475  size_t i = 0;
476  while (!s.empty() && i < tx->vin.size()) {
477  PSBTInput input;
478  s >> input;
479  inputs.push_back(input);
480  ++i;
481  }
482  // Make sure that the number of inputs matches the number of inputs in
483  // the transaction
484  if (inputs.size() != tx->vin.size()) {
485  throw std::ios_base::failure("Inputs provided does not match the "
486  "number of inputs in transaction.");
487  }
488 
489  // Read output data
490  i = 0;
491  while (!s.empty() && i < tx->vout.size()) {
492  PSBTOutput output;
493  s >> output;
494  outputs.push_back(output);
495  ++i;
496  }
497  // Make sure that the number of outputs matches the number of outputs in
498  // the transaction
499  if (outputs.size() != tx->vout.size()) {
500  throw std::ios_base::failure("Outputs provided does not match the "
501  "number of outputs in transaction.");
502  }
503  // Sanity check
504  if (!IsSane()) {
505  throw std::ios_base::failure("PSBT is not sane.");
506  }
507  }
508 
509  template <typename Stream>
511  Unserialize(s);
512  }
513 };
514 
515 enum class PSBTRole {
516  CREATOR,
517  UPDATER,
518  SIGNER,
519  FINALIZER,
520  EXTRACTOR,
521 };
522 
523 std::string PSBTRoleName(PSBTRole role);
524 
526 bool PSBTInputSigned(const PSBTInput &input);
527 
532 bool SignPSBTInput(const SigningProvider &provider,
533  PartiallySignedTransaction &psbt, int index,
534  SigHashType sighash = SigHashType(),
535  SignatureData *out_sigdata = nullptr,
536  bool use_dummy = false);
537 
544 void UpdatePSBTOutput(const SigningProvider &provider,
545  PartiallySignedTransaction &psbt, int index);
546 
554 
565  CMutableTransaction &result);
566 
578  const std::vector<PartiallySignedTransaction> &psbtxs);
579 
582  const std::string &base64_psbt,
583  std::string &error);
586  const std::string &raw_psbt, std::string &error);
587 
588 #endif // BITCOIN_PSBT_H
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:236
std::array< uint8_t, 64 > sig
Definition: processor.cpp:248
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:36
void SerializeToVector(Stream &s, const X &... args)
Definition: sign.h:95
uint32_t getRawSigHashType() const
Definition: sighashtype.h:83
static constexpr uint8_t PSBT_SEPARATOR
Definition: psbt.h:36
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT
Definition: psbt.h:30
static constexpr uint8_t PSBT_IN_PARTIAL_SIG
Definition: psbt.h:23
PSBTInput(deserialize_type, Stream &s)
Definition: psbt.h:227
void Serialize(Stream &s) const
Definition: psbt.h:366
void FromSignatureData(const SignatureData &sigdata)
Definition: psbt.cpp:99
A version of CTransaction with the PSBT format.
Definition: psbt.h:335
constexpr Span< A > MakeSpan(A(&a)[N])
Create a span to a container exposing data() and size().
Definition: span.h:108
void Serialize(Stream &s) const
Definition: psbt.h:245
NODISCARD bool DecodeRawPSBT(PartiallySignedTransaction &decoded_psbt, const std::string &raw_psbt, std::string &error)
Decode a raw (binary blob) PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:327
void Serialize(Stream &s) const
Definition: psbt.h:59
std::string PSBTRoleName(PSBTRole role)
Definition: psbt.cpp:299
CScript redeem_script
Definition: psbt.h:45
Dummy data type to identify deserializing constructors.
Definition: serialize.h:44
void UnserializeFromVector(Stream &s, X &... args)
Definition: sign.h:103
void Merge(const PSBTInput &input)
Definition: psbt.cpp:120
static constexpr uint8_t PSBT_IN_BIP32_DERIVATION
Definition: psbt.h:26
bool IsNull() const
Definition: transaction.h:164
bool FinalizePSBT(PartiallySignedTransaction &psbtx)
Finalizes a PSBT if possible, combining partial signatures.
Definition: psbt.cpp:249
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, SigHashType sighash=SigHashType(), SignatureData *out_sigdata=nullptr, bool use_dummy=false)
Signs a PSBTInput, verifying that all provided data matches what is being signed. ...
Definition: psbt.cpp:198
PSBTRole
Definition: psbt.h:515
A structure for PSBTs which contains per output information.
Definition: psbt.h:233
CTxOut utxo
Definition: psbt.h:44
std::vector< PSBTOutput > outputs
Definition: psbt.h:338
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:235
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:37
NODISCARD bool DecodeBase64PSBT(PartiallySignedTransaction &decoded_psbt, const std::string &base64_psbt, std::string &error)
Decode a base64ed PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:316
An input of a transaction.
Definition: transaction.h:67
#define NODISCARD
Definition: attributes.h:18
static constexpr uint8_t PSBT_IN_SCRIPTSIG
Definition: psbt.h:27
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:47
std::map< CKeyID, SigPair > partial_sigs
Definition: psbt.h:48
An encapsulated public key.
Definition: pubkey.h:31
const std::streamsize MAX_FILE_SIZE_PSBT
Definition: psbt.h:40
static constexpr uint8_t PSBT_IN_SIGHASH
Definition: psbt.h:24
static constexpr uint8_t PSBT_IN_UTXO
Definition: psbt.h:22
A structure for PSBTs which contain per-input information.
Definition: psbt.h:43
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed.
Definition: psbt.cpp:172
void Unserialize(Stream &s)
Definition: psbt.h:396
An output of a transaction.
Definition: transaction.h:141
static constexpr uint8_t PSBT_IN_REDEEMSCRIPT
Definition: psbt.h:25
static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX
Definition: psbt.h:19
std::pair< CPubKey, std::vector< uint8_t > > SigPair
Definition: sign.h:60
PSBTInput()
Definition: psbt.h:57
PSBTOutput()
Definition: psbt.h:243
std::vector< PSBTInput > inputs
Definition: psbt.h:337
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
Definition: psbt.cpp:176
SigHashType sighash_type
Definition: psbt.h:50
CScript scriptSig
Definition: transaction.h:70
bool IsSane() const
Definition: psbt.cpp:137
An interface to be implemented by keystores that support signing.
void SerializeHDKeypaths(Stream &s, const std::map< CPubKey, KeyOriginInfo > &hd_keypaths, uint8_t type)
Definition: sign.h:153
NODISCARD TransactionError 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:281
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:430
CScript redeem_script
Definition: psbt.h:234
bool empty() const
Definition: prevector.h:386
void DeserializeHDKeypaths(Stream &s, const std::vector< uint8_t > &key, std::map< CPubKey, KeyOriginInfo > &hd_keypaths)
Definition: sign.h:115
A mutable version of CTransaction.
Definition: transaction.h:297
TransactionError
Definition: error.h:22
void Unserialize(Stream &s)
Definition: psbt.h:264
void Unserialize(Stream &s)
Definition: psbt.h:105
static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION
Definition: psbt.h:31
PSBTOutput(deserialize_type, Stream &s)
Definition: psbt.h:327
CScript final_script_sig
Definition: psbt.h:46
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:264
std::optional< CMutableTransaction > tx
Definition: psbt.h:336
void FillSignatureData(SignatureData &sigdata) const
Definition: psbt.cpp:81
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:49
PartiallySignedTransaction(deserialize_type, Stream &s)
Definition: psbt.h:510
bool error(const char *fmt, const Args &... args)
Definition: system.h:47
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:339
static constexpr uint8_t PSBT_MAGIC_BYTES[5]
Definition: psbt.h:16
bool IsNull() const
Definition: psbt.cpp:76
Signature hash type wrapper class.
Definition: sighashtype.h:37