diff options
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/sign.cpp | 221 | ||||
-rw-r--r-- | src/script/sign.h | 540 |
2 files changed, 0 insertions, 761 deletions
diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 792fb2997f..9d6a390ea2 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -232,67 +232,6 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato return sigdata.complete; } -bool PSBTInputSigned(PSBTInput& input) -{ - return !input.final_script_sig.empty() || !input.final_script_witness.IsNull(); -} - -bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash) -{ - PSBTInput& input = psbt.inputs.at(index); - const CMutableTransaction& tx = *psbt.tx; - - if (PSBTInputSigned(input)) { - return true; - } - - // Fill SignatureData with input info - SignatureData sigdata; - input.FillSignatureData(sigdata); - - // Get UTXO - bool require_witness_sig = false; - CTxOut utxo; - - // Verify input sanity, which checks that at most one of witness or non-witness utxos is provided. - if (!input.IsSane()) { - return false; - } - - if (input.non_witness_utxo) { - // If we're taking our information from a non-witness UTXO, verify that it matches the prevout. - COutPoint prevout = tx.vin[index].prevout; - if (input.non_witness_utxo->GetHash() != prevout.hash) { - return false; - } - utxo = input.non_witness_utxo->vout[prevout.n]; - } else if (!input.witness_utxo.IsNull()) { - utxo = input.witness_utxo; - // When we're taking our information from a witness UTXO, we can't verify it is actually data from - // the output being spent. This is safe in case a witness signature is produced (which includes this - // information directly in the hash), but not for non-witness signatures. Remember that we require - // a witness signature in this situation. - require_witness_sig = true; - } else { - return false; - } - - MutableTransactionSignatureCreator creator(&tx, index, utxo.nValue, sighash); - sigdata.witness = false; - bool sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, sigdata); - // Verify that a witness signature was produced in case one was required. - if (require_witness_sig && !sigdata.witness) return false; - input.FromSignatureData(sigdata); - - // If we have a witness signature, use the smaller witness UTXO. - if (sigdata.witness) { - input.witness_utxo = utxo; - input.non_witness_utxo = nullptr; - } - - return sig_complete; -} - class SignatureExtractorChecker final : public BaseSignatureChecker { private: @@ -509,166 +448,6 @@ bool IsSolvable(const SigningProvider& provider, const CScript& script) return false; } -PartiallySignedTransaction::PartiallySignedTransaction(const CMutableTransaction& tx) : tx(tx) -{ - inputs.resize(tx.vin.size()); - outputs.resize(tx.vout.size()); -} - -bool PartiallySignedTransaction::IsNull() const -{ - return !tx && inputs.empty() && outputs.empty() && unknown.empty(); -} - -void PartiallySignedTransaction::Merge(const PartiallySignedTransaction& psbt) -{ - for (unsigned int i = 0; i < inputs.size(); ++i) { - inputs[i].Merge(psbt.inputs[i]); - } - for (unsigned int i = 0; i < outputs.size(); ++i) { - outputs[i].Merge(psbt.outputs[i]); - } - unknown.insert(psbt.unknown.begin(), psbt.unknown.end()); -} - -bool PartiallySignedTransaction::IsSane() const -{ - for (PSBTInput input : inputs) { - if (!input.IsSane()) return false; - } - return true; -} - -bool PSBTInput::IsNull() const -{ - return !non_witness_utxo && witness_utxo.IsNull() && partial_sigs.empty() && unknown.empty() && hd_keypaths.empty() && redeem_script.empty() && witness_script.empty(); -} - -void PSBTInput::FillSignatureData(SignatureData& sigdata) const -{ - if (!final_script_sig.empty()) { - sigdata.scriptSig = final_script_sig; - sigdata.complete = true; - } - if (!final_script_witness.IsNull()) { - sigdata.scriptWitness = final_script_witness; - sigdata.complete = true; - } - if (sigdata.complete) { - return; - } - - sigdata.signatures.insert(partial_sigs.begin(), partial_sigs.end()); - if (!redeem_script.empty()) { - sigdata.redeem_script = redeem_script; - } - if (!witness_script.empty()) { - sigdata.witness_script = witness_script; - } - for (const auto& key_pair : hd_keypaths) { - sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair); - } -} - -void PSBTInput::FromSignatureData(const SignatureData& sigdata) -{ - if (sigdata.complete) { - partial_sigs.clear(); - hd_keypaths.clear(); - redeem_script.clear(); - witness_script.clear(); - - if (!sigdata.scriptSig.empty()) { - final_script_sig = sigdata.scriptSig; - } - if (!sigdata.scriptWitness.IsNull()) { - final_script_witness = sigdata.scriptWitness; - } - return; - } - - partial_sigs.insert(sigdata.signatures.begin(), sigdata.signatures.end()); - if (redeem_script.empty() && !sigdata.redeem_script.empty()) { - redeem_script = sigdata.redeem_script; - } - if (witness_script.empty() && !sigdata.witness_script.empty()) { - witness_script = sigdata.witness_script; - } - for (const auto& entry : sigdata.misc_pubkeys) { - hd_keypaths.emplace(entry.second); - } -} - -void PSBTInput::Merge(const PSBTInput& input) -{ - if (!non_witness_utxo && input.non_witness_utxo) non_witness_utxo = input.non_witness_utxo; - if (witness_utxo.IsNull() && !input.witness_utxo.IsNull()) { - witness_utxo = input.witness_utxo; - non_witness_utxo = nullptr; // Clear out any non-witness utxo when we set a witness one. - } - - partial_sigs.insert(input.partial_sigs.begin(), input.partial_sigs.end()); - hd_keypaths.insert(input.hd_keypaths.begin(), input.hd_keypaths.end()); - unknown.insert(input.unknown.begin(), input.unknown.end()); - - if (redeem_script.empty() && !input.redeem_script.empty()) redeem_script = input.redeem_script; - if (witness_script.empty() && !input.witness_script.empty()) witness_script = input.witness_script; - if (final_script_sig.empty() && !input.final_script_sig.empty()) final_script_sig = input.final_script_sig; - if (final_script_witness.IsNull() && !input.final_script_witness.IsNull()) final_script_witness = input.final_script_witness; -} - -bool PSBTInput::IsSane() const -{ - // Cannot have both witness and non-witness utxos - if (!witness_utxo.IsNull() && non_witness_utxo) return false; - - // If we have a witness_script or a scriptWitness, we must also have a witness utxo - if (!witness_script.empty() && witness_utxo.IsNull()) return false; - if (!final_script_witness.IsNull() && witness_utxo.IsNull()) return false; - - return true; -} - -void PSBTOutput::FillSignatureData(SignatureData& sigdata) const -{ - if (!redeem_script.empty()) { - sigdata.redeem_script = redeem_script; - } - if (!witness_script.empty()) { - sigdata.witness_script = witness_script; - } - for (const auto& key_pair : hd_keypaths) { - sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair); - } -} - -void PSBTOutput::FromSignatureData(const SignatureData& sigdata) -{ - if (redeem_script.empty() && !sigdata.redeem_script.empty()) { - redeem_script = sigdata.redeem_script; - } - if (witness_script.empty() && !sigdata.witness_script.empty()) { - witness_script = sigdata.witness_script; - } - for (const auto& entry : sigdata.misc_pubkeys) { - hd_keypaths.emplace(entry.second); - } -} - -bool PSBTOutput::IsNull() const -{ - return redeem_script.empty() && witness_script.empty() && hd_keypaths.empty() && unknown.empty(); -} - -void PSBTOutput::Merge(const PSBTOutput& output) -{ - hd_keypaths.insert(output.hd_keypaths.begin(), output.hd_keypaths.end()); - unknown.insert(output.unknown.begin(), output.unknown.end()); - - if (redeem_script.empty() && !output.redeem_script.empty()) redeem_script = output.redeem_script; - if (witness_script.empty() && !output.witness_script.empty()) witness_script = output.witness_script; -} - bool HidingSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return m_provider->GetCScript(scriptid, script); diff --git a/src/script/sign.h b/src/script/sign.h index e884f4c480..64eb3eb8e5 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -123,32 +123,6 @@ struct SignatureData { void MergeSignatureData(SignatureData sigdata); }; -// Magic bytes -static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff}; - -// Global types -static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00; - -// Input types -static constexpr uint8_t PSBT_IN_NON_WITNESS_UTXO = 0x00; -static constexpr uint8_t PSBT_IN_WITNESS_UTXO = 0x01; -static constexpr uint8_t PSBT_IN_PARTIAL_SIG = 0x02; -static constexpr uint8_t PSBT_IN_SIGHASH = 0x03; -static constexpr uint8_t PSBT_IN_REDEEMSCRIPT = 0x04; -static constexpr uint8_t PSBT_IN_WITNESSSCRIPT = 0x05; -static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06; -static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07; -static constexpr uint8_t PSBT_IN_SCRIPTWITNESS = 0x08; - -// Output types -static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00; -static constexpr uint8_t PSBT_OUT_WITNESSSCRIPT = 0x01; -static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02; - -// The separator is 0x00. Reading this in means that the unserializer can interpret it -// as a 0 length key which indicates that this is the separator. The separator has no value. -static constexpr uint8_t PSBT_SEPARATOR = 0x00; - // Takes a stream and multiple arguments and serializes them as if first serialized into a vector and then into the stream // The resulting output into the stream has the total serialized length of all of the objects followed by all objects concatenated with each other. template<typename Stream, typename... X> @@ -223,514 +197,6 @@ void SerializeHDKeypaths(Stream& s, const std::map<CPubKey, KeyOriginInfo>& hd_k } } -/** A structure for PSBTs which contain per-input information */ -struct PSBTInput -{ - CTransactionRef non_witness_utxo; - CTxOut witness_utxo; - CScript redeem_script; - CScript witness_script; - CScript final_script_sig; - CScriptWitness final_script_witness; - std::map<CPubKey, KeyOriginInfo> hd_keypaths; - std::map<CKeyID, SigPair> partial_sigs; - std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown; - int sighash_type = 0; - - bool IsNull() const; - void FillSignatureData(SignatureData& sigdata) const; - void FromSignatureData(const SignatureData& sigdata); - void Merge(const PSBTInput& input); - bool IsSane() const; - PSBTInput() {} - - template <typename Stream> - inline void Serialize(Stream& s) const { - // Write the utxo - // If there is a non-witness utxo, then don't add the witness one. - if (non_witness_utxo) { - SerializeToVector(s, PSBT_IN_NON_WITNESS_UTXO); - OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS); - SerializeToVector(os, non_witness_utxo); - } else if (!witness_utxo.IsNull()) { - SerializeToVector(s, PSBT_IN_WITNESS_UTXO); - SerializeToVector(s, witness_utxo); - } - - if (final_script_sig.empty() && final_script_witness.IsNull()) { - // Write any partial signatures - for (auto sig_pair : partial_sigs) { - SerializeToVector(s, PSBT_IN_PARTIAL_SIG, MakeSpan(sig_pair.second.first)); - s << sig_pair.second.second; - } - - // Write the sighash type - if (sighash_type > 0) { - SerializeToVector(s, PSBT_IN_SIGHASH); - SerializeToVector(s, sighash_type); - } - - // Write the redeem script - if (!redeem_script.empty()) { - SerializeToVector(s, PSBT_IN_REDEEMSCRIPT); - s << redeem_script; - } - - // Write the witness script - if (!witness_script.empty()) { - SerializeToVector(s, PSBT_IN_WITNESSSCRIPT); - s << witness_script; - } - - // Write any hd keypaths - SerializeHDKeypaths(s, hd_keypaths, PSBT_IN_BIP32_DERIVATION); - } - - // Write script sig - if (!final_script_sig.empty()) { - SerializeToVector(s, PSBT_IN_SCRIPTSIG); - s << final_script_sig; - } - // write script witness - if (!final_script_witness.IsNull()) { - SerializeToVector(s, PSBT_IN_SCRIPTWITNESS); - SerializeToVector(s, final_script_witness.stack); - } - - // Write unknown things - for (auto& entry : unknown) { - s << entry.first; - s << entry.second; - } - - s << PSBT_SEPARATOR; - } - - - template <typename Stream> - inline void Unserialize(Stream& s) { - // Read loop - bool found_sep = false; - while(!s.empty()) { - // Read - std::vector<unsigned char> key; - s >> key; - - // the key is empty if that was actually a separator byte - // This is a special case for key lengths 0 as those are not allowed (except for separator) - if (key.empty()) { - found_sep = true; - break; - } - - // First byte of key is the type - unsigned char type = key[0]; - - // Do stuff based on type - switch(type) { - case PSBT_IN_NON_WITNESS_UTXO: - { - if (non_witness_utxo) { - throw std::ios_base::failure("Duplicate Key, input non-witness utxo already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Non-witness utxo key is more than one byte type"); - } - // Set the stream to unserialize with witness since this is always a valid network transaction - OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() & ~SERIALIZE_TRANSACTION_NO_WITNESS); - UnserializeFromVector(os, non_witness_utxo); - break; - } - case PSBT_IN_WITNESS_UTXO: - if (!witness_utxo.IsNull()) { - throw std::ios_base::failure("Duplicate Key, input witness utxo already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Witness utxo key is more than one byte type"); - } - UnserializeFromVector(s, witness_utxo); - break; - case PSBT_IN_PARTIAL_SIG: - { - // Make sure that the key is the size of pubkey + 1 - if (key.size() != CPubKey::PUBLIC_KEY_SIZE + 1 && key.size() != CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 1) { - throw std::ios_base::failure("Size of key was not the expected size for the type partial signature pubkey"); - } - // Read in the pubkey from key - CPubKey pubkey(key.begin() + 1, key.end()); - if (!pubkey.IsFullyValid()) { - throw std::ios_base::failure("Invalid pubkey"); - } - if (partial_sigs.count(pubkey.GetID()) > 0) { - throw std::ios_base::failure("Duplicate Key, input partial signature for pubkey already provided"); - } - - // Read in the signature from value - std::vector<unsigned char> sig; - s >> sig; - - // Add to list - partial_sigs.emplace(pubkey.GetID(), SigPair(pubkey, std::move(sig))); - break; - } - case PSBT_IN_SIGHASH: - if (sighash_type > 0) { - throw std::ios_base::failure("Duplicate Key, input sighash type already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Sighash type key is more than one byte type"); - } - UnserializeFromVector(s, sighash_type); - break; - case PSBT_IN_REDEEMSCRIPT: - { - if (!redeem_script.empty()) { - throw std::ios_base::failure("Duplicate Key, input redeemScript already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Input redeemScript key is more than one byte type"); - } - s >> redeem_script; - break; - } - case PSBT_IN_WITNESSSCRIPT: - { - if (!witness_script.empty()) { - throw std::ios_base::failure("Duplicate Key, input witnessScript already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Input witnessScript key is more than one byte type"); - } - s >> witness_script; - break; - } - case PSBT_IN_BIP32_DERIVATION: - { - DeserializeHDKeypaths(s, key, hd_keypaths); - break; - } - case PSBT_IN_SCRIPTSIG: - { - if (!final_script_sig.empty()) { - throw std::ios_base::failure("Duplicate Key, input final scriptSig already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Final scriptSig key is more than one byte type"); - } - s >> final_script_sig; - break; - } - case PSBT_IN_SCRIPTWITNESS: - { - if (!final_script_witness.IsNull()) { - throw std::ios_base::failure("Duplicate Key, input final scriptWitness already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Final scriptWitness key is more than one byte type"); - } - UnserializeFromVector(s, final_script_witness.stack); - break; - } - // Unknown stuff - default: - if (unknown.count(key) > 0) { - throw std::ios_base::failure("Duplicate Key, key for unknown value already provided"); - } - // Read in the value - std::vector<unsigned char> val_bytes; - s >> val_bytes; - unknown.emplace(std::move(key), std::move(val_bytes)); - break; - } - } - - if (!found_sep) { - throw std::ios_base::failure("Separator is missing at the end of an input map"); - } - } - - template <typename Stream> - PSBTInput(deserialize_type, Stream& s) { - Unserialize(s); - } -}; - -/** A structure for PSBTs which contains per output information */ -struct PSBTOutput -{ - CScript redeem_script; - CScript witness_script; - std::map<CPubKey, KeyOriginInfo> hd_keypaths; - std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown; - - bool IsNull() const; - void FillSignatureData(SignatureData& sigdata) const; - void FromSignatureData(const SignatureData& sigdata); - void Merge(const PSBTOutput& output); - bool IsSane() const; - PSBTOutput() {} - - template <typename Stream> - inline void Serialize(Stream& s) const { - // Write the redeem script - if (!redeem_script.empty()) { - SerializeToVector(s, PSBT_OUT_REDEEMSCRIPT); - s << redeem_script; - } - - // Write the witness script - if (!witness_script.empty()) { - SerializeToVector(s, PSBT_OUT_WITNESSSCRIPT); - s << witness_script; - } - - // Write any hd keypaths - SerializeHDKeypaths(s, hd_keypaths, PSBT_OUT_BIP32_DERIVATION); - - // Write unknown things - for (auto& entry : unknown) { - s << entry.first; - s << entry.second; - } - - s << PSBT_SEPARATOR; - } - - - template <typename Stream> - inline void Unserialize(Stream& s) { - // Read loop - bool found_sep = false; - while(!s.empty()) { - // Read - std::vector<unsigned char> key; - s >> key; - - // the key is empty if that was actually a separator byte - // This is a special case for key lengths 0 as those are not allowed (except for separator) - if (key.empty()) { - found_sep = true; - break; - } - - // First byte of key is the type - unsigned char type = key[0]; - - // Do stuff based on type - switch(type) { - case PSBT_OUT_REDEEMSCRIPT: - { - if (!redeem_script.empty()) { - throw std::ios_base::failure("Duplicate Key, output redeemScript already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Output redeemScript key is more than one byte type"); - } - s >> redeem_script; - break; - } - case PSBT_OUT_WITNESSSCRIPT: - { - if (!witness_script.empty()) { - throw std::ios_base::failure("Duplicate Key, output witnessScript already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Output witnessScript key is more than one byte type"); - } - s >> witness_script; - break; - } - case PSBT_OUT_BIP32_DERIVATION: - { - DeserializeHDKeypaths(s, key, hd_keypaths); - break; - } - // Unknown stuff - default: { - if (unknown.count(key) > 0) { - throw std::ios_base::failure("Duplicate Key, key for unknown value already provided"); - } - // Read in the value - std::vector<unsigned char> val_bytes; - s >> val_bytes; - unknown.emplace(std::move(key), std::move(val_bytes)); - break; - } - } - } - - if (!found_sep) { - throw std::ios_base::failure("Separator is missing at the end of an output map"); - } - } - - template <typename Stream> - PSBTOutput(deserialize_type, Stream& s) { - Unserialize(s); - } -}; - -/** A version of CTransaction with the PSBT format*/ -struct PartiallySignedTransaction -{ - boost::optional<CMutableTransaction> tx; - std::vector<PSBTInput> inputs; - std::vector<PSBTOutput> outputs; - std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown; - - bool IsNull() const; - void Merge(const PartiallySignedTransaction& psbt); - bool IsSane() const; - PartiallySignedTransaction() {} - PartiallySignedTransaction(const PartiallySignedTransaction& psbt_in) : tx(psbt_in.tx), inputs(psbt_in.inputs), outputs(psbt_in.outputs), unknown(psbt_in.unknown) {} - explicit PartiallySignedTransaction(const CMutableTransaction& tx); - - // Only checks if they refer to the same transaction - friend bool operator==(const PartiallySignedTransaction& a, const PartiallySignedTransaction &b) - { - return a.tx->GetHash() == b.tx->GetHash(); - } - friend bool operator!=(const PartiallySignedTransaction& a, const PartiallySignedTransaction &b) - { - return !(a == b); - } - - template <typename Stream> - inline void Serialize(Stream& s) const { - - // magic bytes - s << PSBT_MAGIC_BYTES; - - // unsigned tx flag - SerializeToVector(s, PSBT_GLOBAL_UNSIGNED_TX); - - // Write serialized tx to a stream - OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS); - SerializeToVector(os, *tx); - - // Write the unknown things - for (auto& entry : unknown) { - s << entry.first; - s << entry.second; - } - - // Separator - s << PSBT_SEPARATOR; - - // Write inputs - for (const PSBTInput& input : inputs) { - s << input; - } - // Write outputs - for (const PSBTOutput& output : outputs) { - s << output; - } - } - - - template <typename Stream> - inline void Unserialize(Stream& s) { - // Read the magic bytes - uint8_t magic[5]; - s >> magic; - if (!std::equal(magic, magic + 5, PSBT_MAGIC_BYTES)) { - throw std::ios_base::failure("Invalid PSBT magic bytes"); - } - - // Read global data - bool found_sep = false; - while(!s.empty()) { - // Read - std::vector<unsigned char> key; - s >> key; - - // the key is empty if that was actually a separator byte - // This is a special case for key lengths 0 as those are not allowed (except for separator) - if (key.empty()) { - found_sep = true; - break; - } - - // First byte of key is the type - unsigned char type = key[0]; - - // Do stuff based on type - switch(type) { - case PSBT_GLOBAL_UNSIGNED_TX: - { - if (tx) { - throw std::ios_base::failure("Duplicate Key, unsigned tx already provided"); - } else if (key.size() != 1) { - throw std::ios_base::failure("Global unsigned tx key is more than one byte type"); - } - CMutableTransaction mtx; - // Set the stream to serialize with non-witness since this should always be non-witness - OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS); - UnserializeFromVector(os, mtx); - tx = std::move(mtx); - // Make sure that all scriptSigs and scriptWitnesses are empty - for (const CTxIn& txin : tx->vin) { - if (!txin.scriptSig.empty() || !txin.scriptWitness.IsNull()) { - throw std::ios_base::failure("Unsigned tx does not have empty scriptSigs and scriptWitnesses."); - } - } - break; - } - // Unknown stuff - default: { - if (unknown.count(key) > 0) { - throw std::ios_base::failure("Duplicate Key, key for unknown value already provided"); - } - // Read in the value - std::vector<unsigned char> val_bytes; - s >> val_bytes; - unknown.emplace(std::move(key), std::move(val_bytes)); - } - } - } - - if (!found_sep) { - throw std::ios_base::failure("Separator is missing at the end of the global map"); - } - - // Make sure that we got an unsigned tx - if (!tx) { - throw std::ios_base::failure("No unsigned transcation was provided"); - } - - // Read input data - unsigned int i = 0; - while (!s.empty() && i < tx->vin.size()) { - PSBTInput input; - s >> input; - inputs.push_back(input); - - // Make sure the non-witness utxo matches the outpoint - if (input.non_witness_utxo && input.non_witness_utxo->GetHash() != tx->vin[i].prevout.hash) { - throw std::ios_base::failure("Non-witness UTXO does not match outpoint hash"); - } - ++i; - } - // Make sure that the number of inputs matches the number of inputs in the transaction - if (inputs.size() != tx->vin.size()) { - throw std::ios_base::failure("Inputs provided does not match the number of inputs in transaction."); - } - - // Read output data - i = 0; - while (!s.empty() && i < tx->vout.size()) { - PSBTOutput output; - s >> output; - outputs.push_back(output); - ++i; - } - // Make sure that the number of outputs matches the number of outputs in the transaction - if (outputs.size() != tx->vout.size()) { - throw std::ios_base::failure("Outputs provided does not match the number of outputs in transaction."); - } - // Sanity check - if (!IsSane()) { - throw std::ios_base::failure("PSBT is not sane."); - } - } - - template <typename Stream> - PartiallySignedTransaction(deserialize_type, Stream& s) { - Unserialize(s); - } -}; - /** Produce a script signature using a generic signature creator. */ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata); @@ -738,12 +204,6 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType); bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType); -/** Checks whether a PSBTInput is already signed. */ -bool PSBTInputSigned(PSBTInput& input); - -/** Signs a PSBTInput, verifying that all provided data matches what is being signed. */ -bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash = SIGHASH_ALL); - /** Extract signature data from a transaction input, and insert it. */ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout); void UpdateInput(CTxIn& input, const SignatureData& data); |