|
| 1 | +// Copyright (c) 2009-2018 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 | +#include <psbt.h> |
| 6 | +#include <util/strencodings.h> |
| 7 | + |
| 8 | +PartiallySignedTransaction::PartiallySignedTransaction(const CMutableTransaction& tx) : tx(tx) |
| 9 | +{ |
| 10 | + inputs.resize(tx.vin.size()); |
| 11 | + outputs.resize(tx.vout.size()); |
| 12 | +} |
| 13 | + |
| 14 | +bool PartiallySignedTransaction::IsNull() const |
| 15 | +{ |
| 16 | + return !tx && inputs.empty() && outputs.empty() && unknown.empty(); |
| 17 | +} |
| 18 | + |
| 19 | +void PartiallySignedTransaction::Merge(const PartiallySignedTransaction& psbt) |
| 20 | +{ |
| 21 | + for (unsigned int i = 0; i < inputs.size(); ++i) { |
| 22 | + inputs[i].Merge(psbt.inputs[i]); |
| 23 | + } |
| 24 | + for (unsigned int i = 0; i < outputs.size(); ++i) { |
| 25 | + outputs[i].Merge(psbt.outputs[i]); |
| 26 | + } |
| 27 | + unknown.insert(psbt.unknown.begin(), psbt.unknown.end()); |
| 28 | +} |
| 29 | + |
| 30 | +bool PartiallySignedTransaction::IsSane() const |
| 31 | +{ |
| 32 | + for (PSBTInput input : inputs) { |
| 33 | + if (!input.IsSane()) return false; |
| 34 | + } |
| 35 | + return true; |
| 36 | +} |
| 37 | + |
| 38 | +bool PSBTInput::IsNull() const |
| 39 | +{ |
| 40 | + return !non_witness_utxo && witness_utxo.IsNull() && partial_sigs.empty() && unknown.empty() && hd_keypaths.empty() && redeem_script.empty() && witness_script.empty(); |
| 41 | +} |
| 42 | + |
| 43 | +void PSBTInput::FillSignatureData(SignatureData& sigdata) const |
| 44 | +{ |
| 45 | + if (!final_script_sig.empty()) { |
| 46 | + sigdata.scriptSig = final_script_sig; |
| 47 | + sigdata.complete = true; |
| 48 | + } |
| 49 | + if (!final_script_witness.IsNull()) { |
| 50 | + sigdata.scriptWitness = final_script_witness; |
| 51 | + sigdata.complete = true; |
| 52 | + } |
| 53 | + if (sigdata.complete) { |
| 54 | + return; |
| 55 | + } |
| 56 | + |
| 57 | + sigdata.signatures.insert(partial_sigs.begin(), partial_sigs.end()); |
| 58 | + if (!redeem_script.empty()) { |
| 59 | + sigdata.redeem_script = redeem_script; |
| 60 | + } |
| 61 | + if (!witness_script.empty()) { |
| 62 | + sigdata.witness_script = witness_script; |
| 63 | + } |
| 64 | + for (const auto& key_pair : hd_keypaths) { |
| 65 | + sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair); |
| 66 | + } |
| 67 | +} |
| 68 | + |
| 69 | +void PSBTInput::FromSignatureData(const SignatureData& sigdata) |
| 70 | +{ |
| 71 | + if (sigdata.complete) { |
| 72 | + partial_sigs.clear(); |
| 73 | + hd_keypaths.clear(); |
| 74 | + redeem_script.clear(); |
| 75 | + witness_script.clear(); |
| 76 | + |
| 77 | + if (!sigdata.scriptSig.empty()) { |
| 78 | + final_script_sig = sigdata.scriptSig; |
| 79 | + } |
| 80 | + if (!sigdata.scriptWitness.IsNull()) { |
| 81 | + final_script_witness = sigdata.scriptWitness; |
| 82 | + } |
| 83 | + return; |
| 84 | + } |
| 85 | + |
| 86 | + partial_sigs.insert(sigdata.signatures.begin(), sigdata.signatures.end()); |
| 87 | + if (redeem_script.empty() && !sigdata.redeem_script.empty()) { |
| 88 | + redeem_script = sigdata.redeem_script; |
| 89 | + } |
| 90 | + if (witness_script.empty() && !sigdata.witness_script.empty()) { |
| 91 | + witness_script = sigdata.witness_script; |
| 92 | + } |
| 93 | + for (const auto& entry : sigdata.misc_pubkeys) { |
| 94 | + hd_keypaths.emplace(entry.second); |
| 95 | + } |
| 96 | +} |
| 97 | + |
| 98 | +void PSBTInput::Merge(const PSBTInput& input) |
| 99 | +{ |
| 100 | + if (!non_witness_utxo && input.non_witness_utxo) non_witness_utxo = input.non_witness_utxo; |
| 101 | + if (witness_utxo.IsNull() && !input.witness_utxo.IsNull()) { |
| 102 | + witness_utxo = input.witness_utxo; |
| 103 | + non_witness_utxo = nullptr; // Clear out any non-witness utxo when we set a witness one. |
| 104 | + } |
| 105 | + |
| 106 | + partial_sigs.insert(input.partial_sigs.begin(), input.partial_sigs.end()); |
| 107 | + hd_keypaths.insert(input.hd_keypaths.begin(), input.hd_keypaths.end()); |
| 108 | + unknown.insert(input.unknown.begin(), input.unknown.end()); |
| 109 | + |
| 110 | + if (redeem_script.empty() && !input.redeem_script.empty()) redeem_script = input.redeem_script; |
| 111 | + if (witness_script.empty() && !input.witness_script.empty()) witness_script = input.witness_script; |
| 112 | + if (final_script_sig.empty() && !input.final_script_sig.empty()) final_script_sig = input.final_script_sig; |
| 113 | + if (final_script_witness.IsNull() && !input.final_script_witness.IsNull()) final_script_witness = input.final_script_witness; |
| 114 | +} |
| 115 | + |
| 116 | +bool PSBTInput::IsSane() const |
| 117 | +{ |
| 118 | + // Cannot have both witness and non-witness utxos |
| 119 | + if (!witness_utxo.IsNull() && non_witness_utxo) return false; |
| 120 | + |
| 121 | + // If we have a witness_script or a scriptWitness, we must also have a witness utxo |
| 122 | + if (!witness_script.empty() && witness_utxo.IsNull()) return false; |
| 123 | + if (!final_script_witness.IsNull() && witness_utxo.IsNull()) return false; |
| 124 | + |
| 125 | + return true; |
| 126 | +} |
| 127 | + |
| 128 | +void PSBTOutput::FillSignatureData(SignatureData& sigdata) const |
| 129 | +{ |
| 130 | + if (!redeem_script.empty()) { |
| 131 | + sigdata.redeem_script = redeem_script; |
| 132 | + } |
| 133 | + if (!witness_script.empty()) { |
| 134 | + sigdata.witness_script = witness_script; |
| 135 | + } |
| 136 | + for (const auto& key_pair : hd_keypaths) { |
| 137 | + sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair); |
| 138 | + } |
| 139 | +} |
| 140 | + |
| 141 | +void PSBTOutput::FromSignatureData(const SignatureData& sigdata) |
| 142 | +{ |
| 143 | + if (redeem_script.empty() && !sigdata.redeem_script.empty()) { |
| 144 | + redeem_script = sigdata.redeem_script; |
| 145 | + } |
| 146 | + if (witness_script.empty() && !sigdata.witness_script.empty()) { |
| 147 | + witness_script = sigdata.witness_script; |
| 148 | + } |
| 149 | + for (const auto& entry : sigdata.misc_pubkeys) { |
| 150 | + hd_keypaths.emplace(entry.second); |
| 151 | + } |
| 152 | +} |
| 153 | + |
| 154 | +bool PSBTOutput::IsNull() const |
| 155 | +{ |
| 156 | + return redeem_script.empty() && witness_script.empty() && hd_keypaths.empty() && unknown.empty(); |
| 157 | +} |
| 158 | + |
| 159 | +void PSBTOutput::Merge(const PSBTOutput& output) |
| 160 | +{ |
| 161 | + hd_keypaths.insert(output.hd_keypaths.begin(), output.hd_keypaths.end()); |
| 162 | + unknown.insert(output.unknown.begin(), output.unknown.end()); |
| 163 | + |
| 164 | + if (redeem_script.empty() && !output.redeem_script.empty()) redeem_script = output.redeem_script; |
| 165 | + if (witness_script.empty() && !output.witness_script.empty()) witness_script = output.witness_script; |
| 166 | +} |
| 167 | + |
| 168 | +bool PSBTInputSigned(PSBTInput& input) |
| 169 | +{ |
| 170 | + return !input.final_script_sig.empty() || !input.final_script_witness.IsNull(); |
| 171 | +} |
| 172 | + |
| 173 | +bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash) |
| 174 | +{ |
| 175 | + PSBTInput& input = psbt.inputs.at(index); |
| 176 | + const CMutableTransaction& tx = *psbt.tx; |
| 177 | + |
| 178 | + if (PSBTInputSigned(input)) { |
| 179 | + return true; |
| 180 | + } |
| 181 | + |
| 182 | + // Fill SignatureData with input info |
| 183 | + SignatureData sigdata; |
| 184 | + input.FillSignatureData(sigdata); |
| 185 | + |
| 186 | + // Get UTXO |
| 187 | + bool require_witness_sig = false; |
| 188 | + CTxOut utxo; |
| 189 | + |
| 190 | + // Verify input sanity, which checks that at most one of witness or non-witness utxos is provided. |
| 191 | + if (!input.IsSane()) { |
| 192 | + return false; |
| 193 | + } |
| 194 | + |
| 195 | + if (input.non_witness_utxo) { |
| 196 | + // If we're taking our information from a non-witness UTXO, verify that it matches the prevout. |
| 197 | + COutPoint prevout = tx.vin[index].prevout; |
| 198 | + if (input.non_witness_utxo->GetHash() != prevout.hash) { |
| 199 | + return false; |
| 200 | + } |
| 201 | + utxo = input.non_witness_utxo->vout[prevout.n]; |
| 202 | + } else if (!input.witness_utxo.IsNull()) { |
| 203 | + utxo = input.witness_utxo; |
| 204 | + // When we're taking our information from a witness UTXO, we can't verify it is actually data from |
| 205 | + // the output being spent. This is safe in case a witness signature is produced (which includes this |
| 206 | + // information directly in the hash), but not for non-witness signatures. Remember that we require |
| 207 | + // a witness signature in this situation. |
| 208 | + require_witness_sig = true; |
| 209 | + } else { |
| 210 | + return false; |
| 211 | + } |
| 212 | + |
| 213 | + MutableTransactionSignatureCreator creator(&tx, index, utxo.nValue, sighash); |
| 214 | + sigdata.witness = false; |
| 215 | + bool sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, sigdata); |
| 216 | + // Verify that a witness signature was produced in case one was required. |
| 217 | + if (require_witness_sig && !sigdata.witness) return false; |
| 218 | + input.FromSignatureData(sigdata); |
| 219 | + |
| 220 | + // If we have a witness signature, use the smaller witness UTXO. |
| 221 | + if (sigdata.witness) { |
| 222 | + input.witness_utxo = utxo; |
| 223 | + input.non_witness_utxo = nullptr; |
| 224 | + } |
| 225 | + |
| 226 | + return sig_complete; |
| 227 | +} |
0 commit comments