Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead
| 445 | |
| 446 | // Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead |
| 447 | SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout) |
| 448 | { |
| 449 | SignatureData data; |
| 450 | assert(tx.vin.size() > nIn); |
| 451 | data.scriptSig = tx.vin[nIn].scriptSig; |
| 452 | data.scriptWitness = tx.witness.vtxinwit.size() > nIn ? tx.witness.vtxinwit[nIn].scriptWitness : CScriptWitness(); |
| 453 | Stacks stack(data); |
| 454 | |
| 455 | // Get signatures |
| 456 | MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue, MissingDataBehavior::FAIL); |
| 457 | SignatureExtractorChecker extractor_checker(data, tx_checker); |
| 458 | if (VerifyScript(data.scriptSig, txout.scriptPubKey, &data.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS | SCRIPT_SIGHASH_RANGEPROOF, extractor_checker)) { |
| 459 | data.complete = true; |
| 460 | return data; |
| 461 | } |
| 462 | |
| 463 | // Get scripts |
| 464 | std::vector<std::vector<unsigned char>> solutions; |
| 465 | TxoutType script_type = Solver(txout.scriptPubKey, solutions); |
| 466 | SigVersion sigversion = SigVersion::BASE; |
| 467 | CScript next_script = txout.scriptPubKey; |
| 468 | |
| 469 | if (script_type == TxoutType::SCRIPTHASH && !stack.script.empty() && !stack.script.back().empty()) { |
| 470 | // Get the redeemScript |
| 471 | CScript redeem_script(stack.script.back().begin(), stack.script.back().end()); |
| 472 | data.redeem_script = redeem_script; |
| 473 | next_script = std::move(redeem_script); |
| 474 | |
| 475 | // Get redeemScript type |
| 476 | script_type = Solver(next_script, solutions); |
| 477 | stack.script.pop_back(); |
| 478 | } |
| 479 | if (script_type == TxoutType::WITNESS_V0_SCRIPTHASH && !stack.witness.empty() && !stack.witness.back().empty()) { |
| 480 | // Get the witnessScript |
| 481 | CScript witness_script(stack.witness.back().begin(), stack.witness.back().end()); |
| 482 | data.witness_script = witness_script; |
| 483 | next_script = std::move(witness_script); |
| 484 | |
| 485 | // Get witnessScript type |
| 486 | script_type = Solver(next_script, solutions); |
| 487 | stack.witness.pop_back(); |
| 488 | stack.script = std::move(stack.witness); |
| 489 | stack.witness.clear(); |
| 490 | sigversion = SigVersion::WITNESS_V0; |
| 491 | } |
| 492 | // We enable SIGHASH_RANGEPROOF for signing. |
| 493 | unsigned int flags = SCRIPT_SIGHASH_RANGEPROOF; |
| 494 | if (script_type == TxoutType::MULTISIG && !stack.script.empty()) { |
| 495 | // Build a map of pubkey -> signature by matching sigs to pubkeys: |
| 496 | assert(solutions.size() > 1); |
| 497 | unsigned int num_pubkeys = solutions.size()-2; |
| 498 | unsigned int last_success_key = 0; |
| 499 | for (const valtype& sig : stack.script) { |
| 500 | for (unsigned int i = last_success_key; i < num_pubkeys; ++i) { |
| 501 | const valtype& pubkey = solutions[i+1]; |
| 502 | // We either have a signature for this pubkey, or we have found a signature and it is valid |
| 503 | if (data.signatures.count(CPubKey(pubkey).GetID()) || extractor_checker.CheckECDSASignature(sig, pubkey, next_script, sigversion, flags)) { |
| 504 | last_success_key = i + 1; |