Bitcoin ABC  0.26.3
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>
12 #include <script/signingprovider.h>
13 
14 #include <optional>
15 
16 // Magic bytes
17 static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff};
18 
19 // Global types
20 static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00;
21 
22 // Input types
23 static constexpr uint8_t PSBT_IN_UTXO = 0x00;
24 static constexpr uint8_t PSBT_IN_PARTIAL_SIG = 0x02;
25 static constexpr uint8_t PSBT_IN_SIGHASH = 0x03;
26 static constexpr uint8_t PSBT_IN_REDEEMSCRIPT = 0x04;
27 static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
28 static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
29 
30 // Output types
31 static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00;
32 static 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.
37 static 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.
41 const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MiB
42 
44 struct 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;
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() {}
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.getRawSigHashType() != 0) {
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  }
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  }
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  }
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);
243 
244  template <typename Stream> inline void Serialize(Stream &s) const {
245  // Write the redeem script
246  if (!redeem_script.empty()) {
248  s << redeem_script;
249  }
250 
251  // Write any hd keypaths
253 
254  // Write unknown things
255  for (auto &entry : unknown) {
256  s << entry.first;
257  s << entry.second;
258  }
259 
260  s << PSBT_SEPARATOR;
261  }
262 
263  template <typename Stream> inline void Unserialize(Stream &s) {
264  // Used for duplicate key detection
265  std::set<std::vector<uint8_t>> key_lookup;
266 
267  // Read loop
268  bool found_sep = false;
269  while (!s.empty()) {
270  // Read
271  std::vector<uint8_t> key;
272  s >> key;
273 
274  // the key is empty if that was actually a separator byte
275  // This is a special case for key lengths 0 as those are not allowed
276  // (except for separator)
277  if (key.empty()) {
278  found_sep = true;
279  break;
280  }
281 
282  // First byte of key is the type
283  uint8_t type = key[0];
284 
285  // Do stuff based on type
286  switch (type) {
287  case PSBT_OUT_REDEEMSCRIPT: {
288  if (!key_lookup.emplace(key).second) {
289  throw std::ios_base::failure(
290  "Duplicate Key, output redeemScript already "
291  "provided");
292  } else if (key.size() != 1) {
293  throw std::ios_base::failure(
294  "Output redeemScript key is more than one byte "
295  "type");
296  }
297  s >> redeem_script;
298  break;
299  }
302  break;
303  }
304  // Unknown stuff
305  default: {
306  if (unknown.count(key) > 0) {
307  throw std::ios_base::failure(
308  "Duplicate Key, key for unknown value already "
309  "provided");
310  }
311  // Read in the value
312  std::vector<uint8_t> val_bytes;
313  s >> val_bytes;
314  unknown.emplace(std::move(key), std::move(val_bytes));
315  break;
316  }
317  }
318  }
319 
320  if (!found_sep) {
321  throw std::ios_base::failure(
322  "Separator is missing at the end of an output map");
323  }
324  }
325 
326  template <typename Stream> PSBTOutput(deserialize_type, Stream &s) {
327  Unserialize(s);
328  }
329 };
330 
335  std::optional<CMutableTransaction> tx;
336  std::vector<PSBTInput> inputs;
337  std::vector<PSBTOutput> outputs;
338  std::map<std::vector<uint8_t>, std::vector<uint8_t>> unknown;
339 
340  bool IsNull() const;
341 
347  [[nodiscard]] bool Merge(const PartiallySignedTransaction &psbt);
348  bool AddInput(const CTxIn &txin, PSBTInput &psbtin);
349  bool AddOutput(const CTxOut &txout, const PSBTOutput &psbtout);
351  explicit PartiallySignedTransaction(const CMutableTransaction &txIn);
359  bool GetInputUTXO(CTxOut &utxo, int input_index) const;
360 
361  template <typename Stream> inline void Serialize(Stream &s) const {
362  // magic bytes
363  s << PSBT_MAGIC_BYTES;
364 
365  // unsigned tx flag
367 
368  // Write serialized tx to a stream
369  SerializeToVector(s, *tx);
370 
371  // Write the unknown things
372  for (auto &entry : unknown) {
373  s << entry.first;
374  s << entry.second;
375  }
376 
377  // Separator
378  s << PSBT_SEPARATOR;
379 
380  // Write inputs
381  for (const PSBTInput &input : inputs) {
382  s << input;
383  }
384 
385  // Write outputs
386  for (const PSBTOutput &output : outputs) {
387  s << output;
388  }
389  }
390 
391  template <typename Stream> inline void Unserialize(Stream &s) {
392  // Read the magic bytes
393  uint8_t magic[5];
394  s >> magic;
395  if (!std::equal(magic, magic + 5, PSBT_MAGIC_BYTES)) {
396  throw std::ios_base::failure("Invalid PSBT magic bytes");
397  }
398 
399  // Used for duplicate key detection
400  std::set<std::vector<uint8_t>> key_lookup;
401 
402  // Read global data
403  bool found_sep = false;
404  while (!s.empty()) {
405  // Read
406  std::vector<uint8_t> key;
407  s >> key;
408 
409  // the key is empty if that was actually a separator byte
410  // This is a special case for key lengths 0 as those are not allowed
411  // (except for separator)
412  if (key.empty()) {
413  found_sep = true;
414  break;
415  }
416 
417  // First byte of key is the type
418  uint8_t type = key[0];
419 
420  // Do stuff based on type
421  switch (type) {
423  if (!key_lookup.emplace(key).second) {
424  throw std::ios_base::failure(
425  "Duplicate Key, unsigned tx already provided");
426  } else if (key.size() != 1) {
427  throw std::ios_base::failure(
428  "Global unsigned tx key is more than one byte "
429  "type");
430  }
432  UnserializeFromVector(s, mtx);
433  tx = std::move(mtx);
434  // Make sure that all scriptSigs are empty.
435  for (const CTxIn &txin : tx->vin) {
436  if (!txin.scriptSig.empty()) {
437  throw std::ios_base::failure(
438  "Unsigned tx does not have empty scriptSigs.");
439  }
440  }
441  break;
442  }
443  // Unknown stuff
444  default: {
445  if (unknown.count(key) > 0) {
446  throw std::ios_base::failure(
447  "Duplicate Key, key for unknown value already "
448  "provided");
449  }
450  // Read in the value
451  std::vector<uint8_t> val_bytes;
452  s >> val_bytes;
453  unknown.emplace(std::move(key), std::move(val_bytes));
454  }
455  }
456  }
457 
458  if (!found_sep) {
459  throw std::ios_base::failure(
460  "Separator is missing at the end of the global map");
461  }
462 
463  // Make sure that we got an unsigned tx
464  if (!tx) {
465  throw std::ios_base::failure(
466  "No unsigned transcation was provided");
467  }
468 
469  // Read input data
470  size_t i = 0;
471  while (!s.empty() && i < tx->vin.size()) {
472  PSBTInput input;
473  s >> input;
474  inputs.push_back(input);
475  ++i;
476  }
477  // Make sure that the number of inputs matches the number of inputs in
478  // the transaction
479  if (inputs.size() != tx->vin.size()) {
480  throw std::ios_base::failure("Inputs provided does not match the "
481  "number of inputs in transaction.");
482  }
483 
484  // Read output data
485  i = 0;
486  while (!s.empty() && i < tx->vout.size()) {
487  PSBTOutput output;
488  s >> output;
489  outputs.push_back(output);
490  ++i;
491  }
492  // Make sure that the number of outputs matches the number of outputs in
493  // the transaction
494  if (outputs.size() != tx->vout.size()) {
495  throw std::ios_base::failure("Outputs provided does not match the "
496  "number of outputs in transaction.");
497  }
498  }
499 
500  template <typename Stream>
502  Unserialize(s);
503  }
504 };
505 
506 enum class PSBTRole {
507  CREATOR,
508  UPDATER,
509  SIGNER,
510  FINALIZER,
511  EXTRACTOR,
512 };
513 
514 std::string PSBTRoleName(PSBTRole role);
515 
517 bool PSBTInputSigned(const PSBTInput &input);
518 
523 bool SignPSBTInput(const SigningProvider &provider,
524  PartiallySignedTransaction &psbt, int index,
525  SigHashType sighash = SigHashType(),
526  SignatureData *out_sigdata = nullptr,
527  bool use_dummy = false);
528 
535 void UpdatePSBTOutput(const SigningProvider &provider,
536  PartiallySignedTransaction &psbt, int index);
537 
545 
556  CMutableTransaction &result);
557 
567 [[nodiscard]] TransactionError
569  const std::vector<PartiallySignedTransaction> &psbtxs);
570 
572 [[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction &decoded_psbt,
573  const std::string &base64_psbt,
574  std::string &error);
576 [[nodiscard]] bool DecodeRawPSBT(PartiallySignedTransaction &decoded_psbt,
577  const std::string &raw_psbt,
578  std::string &error);
579 
580 #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:140
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:256
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:431
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
uint32_t getRawSigHashType() const
Definition: sighashtype.h:83
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:93
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Definition: span.h:224
bool empty() const
Definition: prevector.h:388
TransactionError
Definition: error.h:22
SchnorrSig sig
Definition: processor.cpp:491
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:186
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
static constexpr uint8_t PSBT_IN_SCRIPTSIG
Definition: psbt.h:28
std::string PSBTRoleName(PSBTRole role)
Definition: psbt.cpp:279
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT
Definition: psbt.h:31
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
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:307
PSBTRole
Definition: psbt.h:506
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:296
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:247
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
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:264
bool FinalizePSBT(PartiallySignedTransaction &psbtx)
Finalizes a PSBT if possible, combining partial signatures.
Definition: psbt.cpp:232
const std::streamsize MAX_FILE_SIZE_PSBT
Definition: psbt.h:41
void UnserializeFromVector(Stream &s, X &...args)
Definition: sign.h:103
void SerializeToVector(Stream &s, const X &...args)
Definition: sign.h:95
void SerializeHDKeypaths(Stream &s, const std::map< CPubKey, KeyOriginInfo > &hd_keypaths, uint8_t type)
Definition: sign.h:153
void DeserializeHDKeypaths(Stream &s, const std::vector< uint8_t > &key, std::map< CPubKey, KeyOriginInfo > &hd_keypaths)
Definition: sign.h:115
std::pair< CPubKey, std::vector< uint8_t > > SigPair
Definition: sign.h:60
A structure for PSBTs which contain per-input information.
Definition: psbt.h:44
PSBTInput()
Definition: psbt.h:57
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:48
PSBTInput(deserialize_type, Stream &s)
Definition: psbt.h:227
std::map< CKeyID, SigPair > partial_sigs
Definition: psbt.h:49
SigHashType sighash_type
Definition: psbt.h:51
void Serialize(Stream &s) const
Definition: psbt.h:59
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
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:233
bool IsNull() const
Definition: psbt.cpp:147
void Merge(const PSBTOutput &output)
Definition: psbt.cpp:151
CScript redeem_script
Definition: psbt.h:234
void Serialize(Stream &s) const
Definition: psbt.h:244
PSBTOutput()
Definition: psbt.h:242
PSBTOutput(deserialize_type, Stream &s)
Definition: psbt.h:326
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:235
void Unserialize(Stream &s)
Definition: psbt.h:263
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
Definition: psbt.h:236
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:334
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:338
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:336
std::optional< CMutableTransaction > tx
Definition: psbt.h:335
bool AddInput(const CTxIn &txin, PSBTInput &psbtin)
Definition: psbt.cpp:38
std::vector< PSBTOutput > outputs
Definition: psbt.h:337
void Serialize(Stream &s) const
Definition: psbt.h:361
PartiallySignedTransaction(deserialize_type, Stream &s)
Definition: psbt.h:501
void Unserialize(Stream &s)
Definition: psbt.h:391
Dummy data type to identify deserializing constructors.
Definition: serialize.h:49
bool error(const char *fmt, const Args &...args)
Definition: system.h:45