Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead
| 851 | |
| 852 | // Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead |
| 853 | SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout) |
| 854 | { |
| 855 | SignatureData data; |
| 856 | assert(tx.vin.size() > nIn); |
| 857 | data.scriptSig = tx.vin[nIn].scriptSig; |
| 858 | data.scriptWitness = tx.vin[nIn].scriptWitness; |
| 859 | Stacks stack(data); |
| 860 | |
| 861 | // Get signatures |
| 862 | MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue, MissingDataBehavior::FAIL); |
| 863 | SignatureExtractorChecker extractor_checker(data, tx_checker); |
| 864 | if (VerifyScript(data.scriptSig, txout.scriptPubKey, &data.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, extractor_checker)) { |
| 865 | data.complete = true; |
| 866 | return data; |
| 867 | } |
| 868 | |
| 869 | // Get scripts |
| 870 | std::vector<std::vector<unsigned char>> solutions; |
| 871 | TxoutType script_type = Solver(txout.scriptPubKey, solutions); |
| 872 | SigVersion sigversion = SigVersion::BASE; |
| 873 | CScript next_script = txout.scriptPubKey; |
| 874 | |
| 875 | if (script_type == TxoutType::SCRIPTHASH && !stack.script.empty() && !stack.script.back().empty()) { |
| 876 | // Get the redeemScript |
| 877 | CScript redeem_script(stack.script.back().begin(), stack.script.back().end()); |
| 878 | data.redeem_script = redeem_script; |
| 879 | next_script = std::move(redeem_script); |
| 880 | |
| 881 | // Get redeemScript type |
| 882 | script_type = Solver(next_script, solutions); |
| 883 | stack.script.pop_back(); |
| 884 | } |
| 885 | if (script_type == TxoutType::WITNESS_V0_SCRIPTHASH && !stack.witness.empty() && !stack.witness.back().empty()) { |
| 886 | // Get the witnessScript |
| 887 | CScript witness_script(stack.witness.back().begin(), stack.witness.back().end()); |
| 888 | data.witness_script = witness_script; |
| 889 | next_script = std::move(witness_script); |
| 890 | |
| 891 | // Get witnessScript type |
| 892 | script_type = Solver(next_script, solutions); |
| 893 | stack.witness.pop_back(); |
| 894 | stack.script = std::move(stack.witness); |
| 895 | stack.witness.clear(); |
| 896 | sigversion = SigVersion::WITNESS_V0; |
| 897 | } |
| 898 | if (script_type == TxoutType::MULTISIG && !stack.script.empty()) { |
| 899 | // Build a map of pubkey -> signature by matching sigs to pubkeys: |
| 900 | assert(solutions.size() > 1); |
| 901 | unsigned int num_pubkeys = solutions.size()-2; |
| 902 | unsigned int last_success_key = 0; |
| 903 | for (const valtype& sig : stack.script) { |
| 904 | for (unsigned int i = last_success_key; i < num_pubkeys; ++i) { |
| 905 | const valtype& pubkey = solutions[i+1]; |
| 906 | // We either have a signature for this pubkey, or we have found a signature and it is valid |
| 907 | if (data.signatures.contains(CPubKey(pubkey).GetID()) || extractor_checker.CheckECDSASignature(sig, pubkey, next_script, sigversion)) { |
| 908 | last_success_key = i + 1; |
| 909 | break; |
| 910 | } |