* Sign scriptPubKey using signature made with creator. * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. * Returns false if scriptPubKey could not be completely satisfied. */
| 93 | * Returns false if scriptPubKey could not be completely satisfied. |
| 94 | */ |
| 95 | static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, |
| 96 | std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion, SignatureData& sigdata) |
| 97 | { |
| 98 | CScript scriptRet; |
| 99 | uint160 h160; |
| 100 | ret.clear(); |
| 101 | std::vector<unsigned char> sig; |
| 102 | |
| 103 | std::vector<valtype> vSolutions; |
| 104 | if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) |
| 105 | return false; |
| 106 | |
| 107 | switch (whichTypeRet) |
| 108 | { |
| 109 | case TX_NONSTANDARD: |
| 110 | case TX_NULL_DATA: |
| 111 | case TX_WITNESS_UNKNOWN: |
| 112 | return false; |
| 113 | case TX_PUBKEY: |
| 114 | if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false; |
| 115 | ret.push_back(std::move(sig)); |
| 116 | return true; |
| 117 | case TX_PUBKEYHASH: { |
| 118 | CKeyID keyID = CKeyID(uint160(vSolutions[0])); |
| 119 | CPubKey pubkey; |
| 120 | GetPubKey(provider, sigdata, keyID, pubkey); |
| 121 | if (!CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) return false; |
| 122 | ret.push_back(std::move(sig)); |
| 123 | ret.push_back(ToByteVector(pubkey)); |
| 124 | return true; |
| 125 | } |
| 126 | case TX_SCRIPTHASH: |
| 127 | if (GetCScript(provider, sigdata, uint160(vSolutions[0]), scriptRet)) { |
| 128 | ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end())); |
| 129 | return true; |
| 130 | } |
| 131 | return false; |
| 132 | |
| 133 | case TX_MULTISIG: { |
| 134 | size_t required = vSolutions.front()[0]; |
| 135 | ret.push_back(valtype()); // workaround CHECKMULTISIG bug |
| 136 | for (size_t i = 1; i < vSolutions.size() - 1; ++i) { |
| 137 | CPubKey pubkey = CPubKey(vSolutions[i]); |
| 138 | if (ret.size() < required + 1 && CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) { |
| 139 | ret.push_back(std::move(sig)); |
| 140 | } |
| 141 | } |
| 142 | bool ok = ret.size() == required + 1; |
| 143 | for (size_t i = 0; i + ret.size() < required + 1; ++i) { |
| 144 | ret.push_back(valtype()); |
| 145 | } |
| 146 | return ok; |
| 147 | } |
| 148 | case TX_WITNESS_V0_KEYHASH: |
| 149 | ret.push_back(vSolutions[0]); |
| 150 | return true; |
| 151 | |
| 152 | case TX_WITNESS_V0_SCRIPTHASH: |
no test coverage detected