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

Function SignTransaction

src/script/sign.cpp:645–721  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

643}
644
645bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, const std::map<COutPoint, Coin>& coins, int nHashType, const uint256& hash_genesis_block, std::map<int, bilingual_str>& input_errors)
646{
647 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
648
649 // Use CTransaction for the constant parts of the
650 // transaction to avoid rehashing.
651 const CTransaction txConst(mtx);
652
653 PrecomputedTransactionData txdata{hash_genesis_block};
654 std::vector<CTxOut> spent_outputs;
655 for (unsigned int i = 0; i < mtx.vin.size(); ++i) {
656 CTxIn& txin = mtx.vin[i];
657 auto coin = coins.find(txin.prevout);
658 if (coin == coins.end() || coin->second.IsSpent()) {
659 txdata.Init(txConst, /* spent_outputs */ {}, /* force */ true);
660 break;
661 } else {
662 spent_outputs.emplace_back(coin->second.out.nAsset, coin->second.out.nValue, coin->second.out.scriptPubKey);
663 }
664 }
665 if (spent_outputs.size() == mtx.vin.size()) {
666 txdata.Init(txConst, std::move(spent_outputs), true);
667 }
668
669 // Sign what we can, including pegin inputs:
670 mtx.witness.vtxinwit.resize(mtx.vin.size());
671 for (unsigned int i = 0; i < mtx.vin.size(); ++i) {
672 CTxIn& txin = mtx.vin[i];
673 const CTxInWitness& inWitness = mtx.witness.vtxinwit[i];
674
675 CTxOut prevTxOut;
676 if (txin.m_is_pegin) {
677 prevTxOut = GetPeginOutputFromWitness(mtx.witness.vtxinwit[i].m_pegin_witness);
678 } else {
679 auto coin = coins.find(txin.prevout);
680 if (coin == coins.end() || coin->second.IsSpent()) {
681 input_errors[i] = _("Input not found or already spent");
682 continue;
683 }
684 prevTxOut = coin->second.out;
685 }
686
687 const CScript& prevPubKey = prevTxOut.scriptPubKey;
688 const CConfidentialValue& amount = prevTxOut.nValue;
689
690 SignatureData sigdata = DataFromTransaction(mtx, i, prevTxOut);
691 // Only sign SIGHASH_SINGLE if there's a corresponding output:
692 if (!fHashSingle || (i < mtx.vout.size())) {
693 ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, &txdata, nHashType), prevPubKey, sigdata);
694 }
695
696 UpdateTransaction(mtx, i, sigdata); // ELEMENTS: is UpdateInput in Core
697
698 // amount must be specified for valid segwit signature
699 if (amount.IsExplicit() && amount.GetAmount() == MAX_MONEY && !mtx.witness.vtxinwit[i].scriptWitness.IsNull()) {
700 input_errors[i] = _("Missing amount");
701 continue;
702 }

Callers 2

FUZZ_TARGET_INITFunction · 0.50

Calls 15

_Function · 0.85
DataFromTransactionFunction · 0.85
ProduceSignatureFunction · 0.85
UpdateTransactionFunction · 0.85
VerifyScriptFunction · 0.85
UntranslatedFunction · 0.85
ScriptErrorStringFunction · 0.85
findMethod · 0.80
emplace_backMethod · 0.80
IsExplicitMethod · 0.80

Tested by 2

FUZZ_TARGET_INITFunction · 0.40