Bitcoin ABC 0.30.5
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;
52
53 bool IsNull() const;
54 void FillSignatureData(SignatureData &sigdata) const;
55 void FromSignatureData(const SignatureData &sigdata);
56 void Merge(const PSBTInput &input);
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
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 }
177 break;
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
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) {
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);
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
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
506enum class PSBTRole {
507 CREATOR,
508 UPDATER,
509 SIGNER,
510 FINALIZER,
511 EXTRACTOR,
512};
513
514std::string PSBTRoleName(PSBTRole role);
515
517bool PSBTInputSigned(const PSBTInput &input);
518
523bool SignPSBTInput(const SigningProvider &provider,
524 PartiallySignedTransaction &psbt, int index,
525 SigHashType sighash = SigHashType(),
526 SignatureData *out_sigdata = nullptr,
527 bool use_dummy = false);
528
535void 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 Span<const std::byte> 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: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: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:227
bool empty() const
Definition: prevector.h:396
TransactionError
Definition: error.h:22
bool error(const char *fmt, const Args &...args)
Definition: logging.h:226
SchnorrSig sig
Definition: processor.cpp:498
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
PSBTRole
Definition: psbt.h:506
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:306
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