MCPcopy Create free account
hub / github.com/ElementsProject/elements / DataFromTransaction

Function DataFromTransaction

src/script/sign.cpp:447–512  ·  view source on GitHub ↗

Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead

Source from the content-addressed store, hash-verified

445
446// Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead
447SignatureData 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;

Callers 6

MutateTxSignFunction · 0.85
SignTransactionFunction · 0.85
CombineSignaturesFunction · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85
FUZZ_TARGET_INITFunction · 0.85
combinerawtransactionFunction · 0.85

Calls 13

VerifyScriptFunction · 0.85
SolverFunction · 0.85
countMethod · 0.80
CScriptWitnessClass · 0.70
CPubKeyClass · 0.70
sizeMethod · 0.45
emptyMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
pop_backMethod · 0.45
clearMethod · 0.45
GetIDMethod · 0.45

Tested by 3

CombineSignaturesFunction · 0.68
BOOST_AUTO_TEST_CASEFunction · 0.68
FUZZ_TARGET_INITFunction · 0.68