Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead
| 332 | |
| 333 | // Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead |
| 334 | SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout, bool no_forkid) |
| 335 | { |
| 336 | SignatureData data; |
| 337 | assert(tx.vin.size() > nIn); |
| 338 | data.scriptSig = tx.vin[nIn].scriptSig; |
| 339 | data.scriptWitness = tx.vin[nIn].scriptWitness; |
| 340 | Stacks stack(data); |
| 341 | |
| 342 | // Get signatures |
| 343 | MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue); |
| 344 | SignatureExtractorChecker extractor_checker(data, tx_checker); |
| 345 | int flag = no_forkid ? STANDARD_SCRIPT_VERIFY_FLAGS | SCRIPT_FORKID_DISABLED : STANDARD_SCRIPT_VERIFY_FLAGS; |
| 346 | if (VerifyScript(data.scriptSig, txout.scriptPubKey, &data.scriptWitness, flag, extractor_checker)) { |
| 347 | data.complete = true; |
| 348 | return data; |
| 349 | } |
| 350 | |
| 351 | // Get scripts |
| 352 | txnouttype script_type; |
| 353 | std::vector<std::vector<unsigned char>> solutions; |
| 354 | Solver(txout.scriptPubKey, script_type, solutions); |
| 355 | SigVersion sigversion = SigVersion::BASE; |
| 356 | CScript next_script = txout.scriptPubKey; |
| 357 | |
| 358 | if (script_type == TX_SCRIPTHASH && !stack.script.empty() && !stack.script.back().empty()) { |
| 359 | // Get the redeemScript |
| 360 | CScript redeem_script(stack.script.back().begin(), stack.script.back().end()); |
| 361 | data.redeem_script = redeem_script; |
| 362 | next_script = std::move(redeem_script); |
| 363 | |
| 364 | // Get redeemScript type |
| 365 | Solver(next_script, script_type, solutions); |
| 366 | stack.script.pop_back(); |
| 367 | } |
| 368 | if (script_type == TX_WITNESS_V0_SCRIPTHASH && !stack.witness.empty() && !stack.witness.back().empty()) { |
| 369 | // Get the witnessScript |
| 370 | CScript witness_script(stack.witness.back().begin(), stack.witness.back().end()); |
| 371 | data.witness_script = witness_script; |
| 372 | next_script = std::move(witness_script); |
| 373 | |
| 374 | // Get witnessScript type |
| 375 | Solver(next_script, script_type, solutions); |
| 376 | stack.witness.pop_back(); |
| 377 | stack.script = std::move(stack.witness); |
| 378 | stack.witness.clear(); |
| 379 | sigversion = SigVersion::WITNESS_V0; |
| 380 | } |
| 381 | if (script_type == TX_MULTISIG && !stack.script.empty()) { |
| 382 | // Build a map of pubkey -> signature by matching sigs to pubkeys: |
| 383 | assert(solutions.size() > 1); |
| 384 | unsigned int num_pubkeys = solutions.size()-2; |
| 385 | unsigned int last_success_key = 0; |
| 386 | for (const valtype& sig : stack.script) { |
| 387 | for (unsigned int i = last_success_key; i < num_pubkeys; ++i) { |
| 388 | const valtype& pubkey = solutions[i+1]; |
| 389 | // We either have a signature for this pubkey, or we have found a signature and it is valid |
| 390 | if (data.signatures.count(CPubKey(pubkey).GetID()) || extractor_checker.CheckSig(sig, pubkey, next_script, sigversion, no_forkid)) { |
| 391 | last_success_key = i + 1; |