58 std::map<std::vector<unsigned char>, std::vector<unsigned char>>
unknown;
67 template <
typename Stream>
70 if (non_witness_utxo) {
75 if (!witness_utxo.
IsNull()) {
80 if (final_script_sig.empty() && final_script_witness.
IsNull()) {
82 for (
auto sig_pair : partial_sigs) {
84 s << sig_pair.second.second;
88 if (sighash_type > 0) {
94 if (!redeem_script.empty()) {
100 if (!witness_script.empty()) {
110 if (!final_script_sig.empty()) {
115 if (!final_script_witness.
IsNull()) {
121 for (
auto& entry : unknown) {
130 template <
typename Stream>
133 std::set<std::vector<unsigned char>> key_lookup;
136 bool found_sep =
false;
139 std::vector<unsigned char> key;
150 unsigned char type = key[0];
156 if (!key_lookup.emplace(key).second) {
157 throw std::ios_base::failure(
"Duplicate Key, input non-witness utxo already provided");
158 }
else if (key.size() != 1) {
159 throw std::ios_base::failure(
"Non-witness utxo key is more than one byte type");
167 if (!key_lookup.emplace(key).second) {
168 throw std::ios_base::failure(
"Duplicate Key, input witness utxo already provided");
169 }
else if (key.size() != 1) {
170 throw std::ios_base::failure(
"Witness utxo key is more than one byte type");
178 throw std::ios_base::failure(
"Size of key was not the expected size for the type partial signature pubkey");
181 CPubKey pubkey(key.begin() + 1, key.end());
182 if (!pubkey.IsFullyValid()) {
183 throw std::ios_base::failure(
"Invalid pubkey");
185 if (partial_sigs.count(pubkey.GetID()) > 0) {
186 throw std::ios_base::failure(
"Duplicate Key, input partial signature for pubkey already provided");
190 std::vector<unsigned char> sig;
194 partial_sigs.emplace(pubkey.GetID(),
SigPair(pubkey, std::move(sig)));
198 if (!key_lookup.emplace(key).second) {
199 throw std::ios_base::failure(
"Duplicate Key, input sighash type already provided");
200 }
else if (key.size() != 1) {
201 throw std::ios_base::failure(
"Sighash type key is more than one byte type");
207 if (!key_lookup.emplace(key).second) {
208 throw std::ios_base::failure(
"Duplicate Key, input redeemScript already provided");
209 }
else if (key.size() != 1) {
210 throw std::ios_base::failure(
"Input redeemScript key is more than one byte type");
217 if (!key_lookup.emplace(key).second) {
218 throw std::ios_base::failure(
"Duplicate Key, input witnessScript already provided");
219 }
else if (key.size() != 1) {
220 throw std::ios_base::failure(
"Input witnessScript key is more than one byte type");
232 if (!key_lookup.emplace(key).second) {
233 throw std::ios_base::failure(
"Duplicate Key, input final scriptSig already provided");
234 }
else if (key.size() != 1) {
235 throw std::ios_base::failure(
"Final scriptSig key is more than one byte type");
242 if (!key_lookup.emplace(key).second) {
243 throw std::ios_base::failure(
"Duplicate Key, input final scriptWitness already provided");
244 }
else if (key.size() != 1) {
245 throw std::ios_base::failure(
"Final scriptWitness key is more than one byte type");
252 if (unknown.count(key) > 0) {
253 throw std::ios_base::failure(
"Duplicate Key, key for unknown value already provided");
256 std::vector<unsigned char> val_bytes;
258 unknown.emplace(std::move(key), std::move(val_bytes));
264 throw std::ios_base::failure(
"Separator is missing at the end of an input map");
268 template <
typename Stream>
280 std::map<std::vector<unsigned char>, std::vector<unsigned char>>
unknown;
288 template <
typename Stream>
291 if (!redeem_script.empty()) {
297 if (!witness_script.empty()) {
306 for (
auto& entry : unknown) {
315 template <
typename Stream>
318 std::set<std::vector<unsigned char>> key_lookup;
321 bool found_sep =
false;
324 std::vector<unsigned char> key;
335 unsigned char type = key[0];
341 if (!key_lookup.emplace(key).second) {
342 throw std::ios_base::failure(
"Duplicate Key, output redeemScript already provided");
343 }
else if (key.size() != 1) {
344 throw std::ios_base::failure(
"Output redeemScript key is more than one byte type");
351 if (!key_lookup.emplace(key).second) {
352 throw std::ios_base::failure(
"Duplicate Key, output witnessScript already provided");
353 }
else if (key.size() != 1) {
354 throw std::ios_base::failure(
"Output witnessScript key is more than one byte type");
366 if (unknown.count(key) > 0) {
367 throw std::ios_base::failure(
"Duplicate Key, key for unknown value already provided");
370 std::vector<unsigned char> val_bytes;
372 unknown.emplace(std::move(key), std::move(val_bytes));
379 throw std::ios_base::failure(
"Separator is missing at the end of an output map");
383 template <
typename Stream>
395 std::map<std::vector<unsigned char>, std::vector<unsigned char>>
unknown;
415 template <
typename Stream>
429 for (
auto& entry : unknown) {
448 template <
typename Stream>
454 throw std::ios_base::failure(
"Invalid PSBT magic bytes");
458 std::set<std::vector<unsigned char>> key_lookup;
461 bool found_sep =
false;
464 std::vector<unsigned char> key;
475 unsigned char type = key[0];
481 if (!key_lookup.emplace(key).second) {
482 throw std::ios_base::failure(
"Duplicate Key, unsigned tx already provided");
483 }
else if (key.size() != 1) {
484 throw std::ios_base::failure(
"Global unsigned tx key is more than one byte type");
492 for (
const CTxIn& txin : tx->vin) {
494 throw std::ios_base::failure(
"Unsigned tx does not have empty scriptSigs and scriptWitnesses.");
501 if (unknown.count(key) > 0) {
502 throw std::ios_base::failure(
"Duplicate Key, key for unknown value already provided");
505 std::vector<unsigned char> val_bytes;
507 unknown.emplace(std::move(key), std::move(val_bytes));
513 throw std::ios_base::failure(
"Separator is missing at the end of the global map");
518 throw std::ios_base::failure(
"No unsigned transcation was provided");
523 while (!s.empty() && i < tx->vin.size()) {
526 inputs.push_back(input);
529 if (input.non_witness_utxo && input.non_witness_utxo->GetHash() != tx->vin[i].prevout.hash) {
530 throw std::ios_base::failure(
"Non-witness UTXO does not match outpoint hash");
535 if (inputs.size() != tx->vin.size()) {
536 throw std::ios_base::failure(
"Inputs provided does not match the number of inputs in transaction.");
541 while (!s.empty() && i < tx->vout.size()) {
544 outputs.push_back(output);
548 if (outputs.size() != tx->vout.size()) {
549 throw std::ios_base::failure(
"Outputs provided does not match the number of outputs in transaction.");
553 template <
typename Stream>
615 #endif // BITCOIN_PSBT_H
std::shared_ptr< const CTransaction > CTransactionRef
bool AddInput(const CTxIn &txin, PSBTInput &psbtin)
bool GetInputUTXO(CTxOut &utxo, int input_index) const
Finds the UTXO for a given input index.
static const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
static constexpr unsigned int SIZE
secp256k1:
void FillSignatureData(SignatureData &sigdata) const
static constexpr uint8_t PSBT_SEPARATOR
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT
Optional< CMutableTransaction > tx
void Serialize(Stream &s) const
CScriptWitness scriptWitness
Only serialized through CTransaction.
static constexpr uint8_t PSBT_IN_PARTIAL_SIG
static constexpr uint8_t PSBT_IN_SCRIPTWITNESS
std::vector< std::vector< unsigned char > > stack
void Merge(const PSBTOutput &output)
A version of CTransaction with the PSBT format.
bool AddOutput(const CTxOut &txout, const PSBTOutput &psbtout)
void DeserializeHDKeypaths(Stream &s, const std::vector< unsigned char > &key, std::map< CPubKey, KeyOriginInfo > &hd_keypaths)
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.
static constexpr uint8_t PSBT_IN_WITNESS_UTXO
static constexpr uint8_t PSBT_IN_BIP32_DERIVATION
void FromSignatureData(const SignatureData &sigdata)
bool FinalizePSBT(PartiallySignedTransaction &psbtx)
Finalizes a PSBT if possible, combining partial signatures.
A structure for PSBTs which contains per output information.
std::vector< PSBTOutput > outputs
std::map< CPubKey, KeyOriginInfo > hd_keypaths
bool error(const char *fmt, const Args &...args)
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.
void SerializeToVector(Stream &s, const X &...args)
An input of a transaction.
static constexpr uint8_t PSBT_IN_SCRIPTSIG
An encapsulated public key.
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, int sighash=SIGHASH_ALL, SignatureData *out_sigdata=nullptr, bool use_dummy=false)
Signs a PSBTInput, verifying that all provided data matches what is being signed. ...
std::pair< CPubKey, std::vector< unsigned char > > SigPair
std::map< std::vector< unsigned char >, std::vector< unsigned char > > unknown
const std::streamsize MAX_FILE_SIZE_PSBT
static constexpr uint8_t PSBT_IN_SIGHASH
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::vector< PSBTInput > inputs
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
static constexpr uint8_t PSBT_IN_WITNESSSCRIPT
NODISCARD bool Merge(const PartiallySignedTransaction &psbt)
Merge psbt into this.
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 Serialize(Stream &s) const
void Unserialize(Stream &s)
static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION
A mutable version of CTransaction.
PSBTOutput(deserialize_type, Stream &s)
static constexpr uint8_t PSBT_IN_NON_WITNESS_UTXO
boost::optional< T > Optional
Substitute for C++17 std::optional.
static constexpr uint8_t PSBT_OUT_WITNESSSCRIPT
bool FinalizeAndExtractPSBT(PartiallySignedTransaction &psbtx, CMutableTransaction &result)
Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized...
PartiallySignedTransaction(deserialize_type, Stream &s)
PartiallySignedTransaction()
std::map< std::vector< unsigned char >, std::vector< unsigned char > > unknown
static constexpr uint8_t PSBT_MAGIC_BYTES[5]
size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction &psbt)
Counts the unsigned inputs of a PSBT.
Span< A > constexpr MakeSpan(A(&a)[N])
MakeSpan for arrays:
void UnserializeFromVector(Stream &s, X &...args)