|
4 | 4 |
|
5 | 5 | #include <psbt.h> |
6 | 6 | #include <util/strencodings.h> |
| 7 | +#include <confidential_validation.h> |
7 | 8 |
|
8 | 9 | #include <numeric> |
9 | 10 |
|
@@ -154,6 +155,11 @@ void PSBTInput::Merge(const PSBTInput& input) |
154 | 155 | if (witness_script.empty() && !input.witness_script.empty()) witness_script = input.witness_script; |
155 | 156 | if (final_script_sig.empty() && !input.final_script_sig.empty()) final_script_sig = input.final_script_sig; |
156 | 157 | if (final_script_witness.IsNull() && !input.final_script_witness.IsNull()) final_script_witness = input.final_script_witness; |
| 158 | + |
| 159 | + if (!value && input.value) value = input.value; |
| 160 | + if (value_blinding_factor.IsNull() && !input.value_blinding_factor.IsNull()) value_blinding_factor = input.value_blinding_factor; |
| 161 | + if (asset.IsNull() && !input.asset.IsNull()) asset = input.asset; |
| 162 | + if (asset_blinding_factor.IsNull() && !input.asset_blinding_factor.IsNull()) asset_blinding_factor = input.asset_blinding_factor; |
157 | 163 | } |
158 | 164 |
|
159 | 165 | bool PSBTInput::IsSane() const |
@@ -206,6 +212,15 @@ void PSBTOutput::Merge(const PSBTOutput& output) |
206 | 212 |
|
207 | 213 | if (redeem_script.empty() && !output.redeem_script.empty()) redeem_script = output.redeem_script; |
208 | 214 | if (witness_script.empty() && !output.witness_script.empty()) witness_script = output.witness_script; |
| 215 | + |
| 216 | + if (!blinding_pubkey.IsValid() && output.blinding_pubkey.IsValid()) blinding_pubkey = output.blinding_pubkey; |
| 217 | + if (value_commitment.IsNull() && !output.value_commitment.IsNull()) value_commitment = output.value_commitment; |
| 218 | + if (value_blinding_factor.IsNull() && !output.value_blinding_factor.IsNull()) value_blinding_factor = output.value_blinding_factor; |
| 219 | + if (asset_commitment.IsNull() && !output.asset_commitment.IsNull()) asset_commitment = output.asset_commitment; |
| 220 | + if (asset_blinding_factor.IsNull() && !output.asset_blinding_factor.IsNull()) asset_blinding_factor = output.asset_blinding_factor; |
| 221 | + if (nonce_commitment.IsNull() && !output.nonce_commitment.IsNull()) nonce_commitment = output.nonce_commitment; |
| 222 | + if (range_proof.empty() && !output.range_proof.empty()) range_proof = output.range_proof; |
| 223 | + if (surjection_proof.empty() && !output.surjection_proof.empty()) surjection_proof = output.surjection_proof; |
209 | 224 | } |
210 | 225 | bool PSBTInputSigned(const PSBTInput& input) |
211 | 226 | { |
@@ -244,7 +259,7 @@ bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& |
244 | 259 | SignatureData sigdata; |
245 | 260 | input.FillSignatureData(sigdata); |
246 | 261 |
|
247 | | - // Get UTXO |
| 262 | + // Get UTXO for this input |
248 | 263 | bool require_witness_sig = false; |
249 | 264 | CTxOut utxo; |
250 | 265 |
|
@@ -323,10 +338,35 @@ bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransacti |
323 | 338 | } |
324 | 339 |
|
325 | 340 | result = *psbtx.tx; |
| 341 | + result.witness.vtxinwit.resize(result.vin.size()); |
326 | 342 | for (unsigned int i = 0; i < result.vin.size(); ++i) { |
327 | 343 | result.vin[i].scriptSig = psbtx.inputs[i].final_script_sig; |
328 | 344 | result.witness.vtxinwit[i].scriptWitness = psbtx.inputs[i].final_script_witness; |
329 | 345 | } |
| 346 | + |
| 347 | + result.witness.vtxoutwit.resize(result.vout.size()); |
| 348 | + for (unsigned int i = 0; i < result.vout.size(); ++i) { |
| 349 | + PSBTOutput& output = psbtx.outputs.at(i); |
| 350 | + CTxOut& out = result.vout[i]; |
| 351 | + CTxOutWitness& outwit = result.witness.vtxoutwit[i]; |
| 352 | + |
| 353 | + if (!output.value_commitment.IsNull()) { |
| 354 | + out.nValue = output.value_commitment; |
| 355 | + } |
| 356 | + if (!output.asset_commitment.IsNull()) { |
| 357 | + out.nAsset = output.asset_commitment; |
| 358 | + } |
| 359 | + if (!output.nonce_commitment.IsNull()) { |
| 360 | + out.nNonce = output.nonce_commitment; |
| 361 | + } |
| 362 | + if (!output.range_proof.empty()) { |
| 363 | + outwit.vchRangeproof = output.range_proof; |
| 364 | + } |
| 365 | + if (!output.surjection_proof.empty()) { |
| 366 | + outwit.vchSurjectionproof = output.surjection_proof; |
| 367 | + } |
| 368 | + } |
| 369 | + |
330 | 370 | return true; |
331 | 371 | } |
332 | 372 |
|
@@ -358,6 +398,14 @@ std::string PSBTRoleName(PSBTRole role) { |
358 | 398 | assert(false); |
359 | 399 | } |
360 | 400 |
|
| 401 | +std::string EncodePSBT(const PartiallySignedTransaction& psbt) |
| 402 | +{ |
| 403 | + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); |
| 404 | + ssTx << psbt; |
| 405 | + return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size()); |
| 406 | +} |
| 407 | + |
| 408 | + |
361 | 409 | bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error) |
362 | 410 | { |
363 | 411 | bool invalid; |
|
0 commit comments