49 std::map<std::vector<uint8_t>, std::vector<uint8_t>>
unknown;
59 template <
typename Stream>
inline void Serialize(Stream &s)
const {
66 if (final_script_sig.
empty()) {
68 for (
auto sig_pair : partial_sigs) {
71 s << sig_pair.second.second;
81 if (!redeem_script.
empty()) {
91 if (!final_script_sig.
empty()) {
97 for (
auto &entry : unknown) {
107 std::set<std::vector<uint8_t>> key_lookup;
110 bool found_sep =
false;
113 std::vector<uint8_t> key;
125 uint8_t type = key[0];
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");
143 throw std::ios_base::failure(
144 "Size of key was not the expected size for the " 145 "type partial signature pubkey");
148 CPubKey pubkey(key.begin() + 1, key.end());
149 if (!pubkey.IsFullyValid()) {
150 throw std::ios_base::failure(
"Invalid pubkey");
152 if (partial_sigs.count(pubkey.GetID()) > 0) {
153 throw std::ios_base::failure(
154 "Duplicate Key, input partial signature for pubkey " 159 std::vector<uint8_t>
sig;
163 partial_sigs.emplace(pubkey.GetID(),
164 SigPair(pubkey, std::move(sig)));
168 if (!key_lookup.emplace(key).second) {
169 throw std::ios_base::failure(
170 "Duplicate Key, input sighash type already " 172 }
else if (key.size() != 1) {
173 throw std::ios_base::failure(
174 "Sighash type key is more than one byte type");
179 if (!key_lookup.emplace(key).second) {
180 throw std::ios_base::failure(
181 "Duplicate Key, input redeemScript already " 183 }
else if (key.size() != 1) {
184 throw std::ios_base::failure(
185 "Input redeemScript key is more than one byte " 196 if (!key_lookup.emplace(key).second) {
197 throw std::ios_base::failure(
198 "Duplicate Key, input final scriptSig already " 200 }
else if (key.size() != 1) {
201 throw std::ios_base::failure(
202 "Final scriptSig key is more than one byte type");
209 if (unknown.count(key) > 0) {
210 throw std::ios_base::failure(
211 "Duplicate Key, key for unknown value already " 215 std::vector<uint8_t> val_bytes;
217 unknown.emplace(std::move(key), std::move(val_bytes));
222 throw std::ios_base::failure(
223 "Separator is missing at the end of an input map");
236 std::map<std::vector<uint8_t>, std::vector<uint8_t>>
unknown;
245 template <
typename Stream>
inline void Serialize(Stream &s)
const {
247 if (!redeem_script.
empty()) {
256 for (
auto &entry : unknown) {
266 std::set<std::vector<uint8_t>> key_lookup;
269 bool found_sep =
false;
272 std::vector<uint8_t> key;
284 uint8_t type = key[0];
289 if (!key_lookup.emplace(key).second) {
290 throw std::ios_base::failure(
291 "Duplicate Key, output redeemScript already " 293 }
else if (key.size() != 1) {
294 throw std::ios_base::failure(
295 "Output redeemScript key is more than one byte " 307 if (unknown.count(key) > 0) {
308 throw std::ios_base::failure(
309 "Duplicate Key, key for unknown value already " 313 std::vector<uint8_t> val_bytes;
315 unknown.emplace(std::move(key), std::move(val_bytes));
322 throw std::ios_base::failure(
323 "Separator is missing at the end of an output map");
336 std::optional<CMutableTransaction>
tx;
339 std::map<std::vector<uint8_t>, std::vector<uint8_t>>
unknown;
361 bool GetInputUTXO(
CTxOut &
utxo,
int input_index)
const;
366 template <
typename Stream>
inline void Serialize(Stream &s)
const {
377 for (
auto &entry : unknown) {
401 throw std::ios_base::failure(
"Invalid PSBT magic bytes");
405 std::set<std::vector<uint8_t>> key_lookup;
408 bool found_sep =
false;
411 std::vector<uint8_t> key;
423 uint8_t type = key[0];
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 " 440 for (
const CTxIn &txin : tx->vin) {
442 throw std::ios_base::failure(
443 "Unsigned tx does not have empty scriptSigs.");
450 if (unknown.count(key) > 0) {
451 throw std::ios_base::failure(
452 "Duplicate Key, key for unknown value already " 456 std::vector<uint8_t> val_bytes;
458 unknown.emplace(std::move(key), std::move(val_bytes));
464 throw std::ios_base::failure(
465 "Separator is missing at the end of the global map");
470 throw std::ios_base::failure(
471 "No unsigned transcation was provided");
476 while (!s.empty() && i < tx->vin.size()) {
479 inputs.push_back(input);
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.");
491 while (!s.empty() && i < tx->vout.size()) {
494 outputs.push_back(output);
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.");
505 throw std::ios_base::failure(
"PSBT is not sane.");
509 template <
typename Stream>
536 bool use_dummy =
false);
578 const std::vector<PartiallySignedTransaction> &psbtxs);
582 const std::string &base64_psbt,
586 const std::string &raw_psbt, std::string &
error);
588 #endif // BITCOIN_PSBT_H std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
std::array< uint8_t, 64 > sig
static constexpr unsigned int SIZE
secp256k1:
void SerializeToVector(Stream &s, const X &... args)
uint32_t getRawSigHashType() const
static constexpr uint8_t PSBT_SEPARATOR
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT
static constexpr uint8_t PSBT_IN_PARTIAL_SIG
void Serialize(Stream &s) const
A version of CTransaction with the PSBT format.
constexpr Span< A > MakeSpan(A(&a)[N])
Create a span to a container exposing data() and size().
void Serialize(Stream &s) const
NODISCARD bool DecodeRawPSBT(PartiallySignedTransaction &decoded_psbt, const std::string &raw_psbt, std::string &error)
Decode a raw (binary blob) PSBT into a PartiallySignedTransaction.
std::string PSBTRoleName(PSBTRole role)
Dummy data type to identify deserializing constructors.
void UnserializeFromVector(Stream &s, X &... args)
static constexpr uint8_t PSBT_IN_BIP32_DERIVATION
bool FinalizePSBT(PartiallySignedTransaction &psbtx)
Finalizes a PSBT if possible, combining partial signatures.
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. ...
A structure for PSBTs which contains per output information.
std::vector< PSBTOutput > outputs
std::map< CPubKey, KeyOriginInfo > hd_keypaths
static constexpr unsigned int COMPRESSED_SIZE
NODISCARD bool DecodeBase64PSBT(PartiallySignedTransaction &decoded_psbt, const std::string &base64_psbt, std::string &error)
Decode a base64ed PSBT into a PartiallySignedTransaction.
An input of a transaction.
static constexpr uint8_t PSBT_IN_SCRIPTSIG
An encapsulated public key.
const std::streamsize MAX_FILE_SIZE_PSBT
static constexpr uint8_t PSBT_IN_SIGHASH
static constexpr uint8_t PSBT_IN_UTXO
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed.
void Unserialize(Stream &s)
An output of a transaction.
static constexpr uint8_t PSBT_IN_REDEEMSCRIPT
static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX
std::pair< CPubKey, std::vector< uint8_t > > SigPair
std::vector< PSBTInput > inputs
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
An interface to be implemented by keystores that support signing.
void SerializeHDKeypaths(Stream &s, const std::map< CPubKey, KeyOriginInfo > &hd_keypaths, uint8_t type)
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...
Serialized script, used inside transaction inputs and outputs.
void DeserializeHDKeypaths(Stream &s, const std::vector< uint8_t > &key, std::map< CPubKey, KeyOriginInfo > &hd_keypaths)
A mutable version of CTransaction.
void Unserialize(Stream &s)
static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION
PSBTOutput(deserialize_type, Stream &s)
bool FinalizeAndExtractPSBT(PartiallySignedTransaction &psbtx, CMutableTransaction &result)
Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized...
std::optional< CMutableTransaction > tx
PartiallySignedTransaction(deserialize_type, Stream &s)
bool error(const char *fmt, const Args &... args)
PartiallySignedTransaction()
std::map< std::vector< uint8_t >, std::vector< uint8_t > > unknown
static constexpr uint8_t PSBT_MAGIC_BYTES[5]
Signature hash type wrapper class.