* Sign scriptPubKey using signature made with creator. * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), * unless whichTypeRet is TxoutType::SCRIPTHASH, in which case scriptSigRet is the redemption script. * Returns false if scriptPubKey could not be completely satisfied. */
| 642 | * Returns false if scriptPubKey could not be completely satisfied. |
| 643 | */ |
| 644 | static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, |
| 645 | std::vector<valtype>& ret, TxoutType& whichTypeRet, SigVersion sigversion, SignatureData& sigdata) |
| 646 | { |
| 647 | CScript scriptRet; |
| 648 | ret.clear(); |
| 649 | std::vector<unsigned char> sig; |
| 650 | |
| 651 | std::vector<valtype> vSolutions; |
| 652 | whichTypeRet = Solver(scriptPubKey, vSolutions); |
| 653 | |
| 654 | switch (whichTypeRet) { |
| 655 | case TxoutType::NONSTANDARD: |
| 656 | case TxoutType::NULL_DATA: |
| 657 | case TxoutType::WITNESS_UNKNOWN: |
| 658 | return false; |
| 659 | case TxoutType::PUBKEY: |
| 660 | if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false; |
| 661 | ret.push_back(std::move(sig)); |
| 662 | return true; |
| 663 | case TxoutType::PUBKEYHASH: { |
| 664 | CKeyID keyID = CKeyID(uint160(vSolutions[0])); |
| 665 | CPubKey pubkey; |
| 666 | if (!GetPubKey(provider, sigdata, keyID, pubkey)) { |
| 667 | // Pubkey could not be found, add to missing |
| 668 | sigdata.missing_pubkeys.push_back(keyID); |
| 669 | return false; |
| 670 | } |
| 671 | if (!CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) return false; |
| 672 | ret.push_back(std::move(sig)); |
| 673 | ret.push_back(ToByteVector(pubkey)); |
| 674 | return true; |
| 675 | } |
| 676 | case TxoutType::SCRIPTHASH: { |
| 677 | uint160 h160{vSolutions[0]}; |
| 678 | if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) { |
| 679 | ret.emplace_back(scriptRet.begin(), scriptRet.end()); |
| 680 | return true; |
| 681 | } |
| 682 | // Could not find redeemScript, add to missing |
| 683 | sigdata.missing_redeem_script = h160; |
| 684 | return false; |
| 685 | } |
| 686 | case TxoutType::MULTISIG: { |
| 687 | size_t required = vSolutions.front()[0]; |
| 688 | ret.emplace_back(); // workaround CHECKMULTISIG bug |
| 689 | for (size_t i = 1; i < vSolutions.size() - 1; ++i) { |
| 690 | CPubKey pubkey = CPubKey(vSolutions[i]); |
| 691 | // We need to always call CreateSig in order to fill sigdata with all |
| 692 | // possible signatures that we can create. This will allow further PSBT |
| 693 | // processing to work as it needs all possible signature and pubkey pairs |
| 694 | if (CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) { |
| 695 | if (ret.size() < required + 1) { |
| 696 | ret.push_back(std::move(sig)); |
| 697 | } |
| 698 | } |
| 699 | } |
| 700 | bool ok = ret.size() == required + 1; |
| 701 | for (size_t i = 0; i + ret.size() < required + 1; ++i) { |
no test coverage detected