* 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. */
| 235 | * Returns false if scriptPubKey could not be completely satisfied. |
| 236 | */ |
| 237 | static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, |
| 238 | std::vector<valtype>& ret, TxoutType& whichTypeRet, SigVersion sigversion, SignatureData& sigdata, |
| 239 | unsigned int flags) |
| 240 | { |
| 241 | CScript scriptRet; |
| 242 | uint160 h160; |
| 243 | ret.clear(); |
| 244 | std::vector<unsigned char> sig; |
| 245 | |
| 246 | std::vector<valtype> vSolutions; |
| 247 | whichTypeRet = Solver(scriptPubKey, vSolutions); |
| 248 | |
| 249 | switch (whichTypeRet) { |
| 250 | case TxoutType::NONSTANDARD: |
| 251 | case TxoutType::NULL_DATA: |
| 252 | case TxoutType::WITNESS_UNKNOWN: |
| 253 | return false; |
| 254 | case TxoutType::PUBKEY: |
| 255 | if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion, flags)) return false; |
| 256 | ret.push_back(std::move(sig)); |
| 257 | return true; |
| 258 | case TxoutType::PUBKEYHASH: { |
| 259 | CKeyID keyID = CKeyID(uint160(vSolutions[0])); |
| 260 | CPubKey pubkey; |
| 261 | if (!GetPubKey(provider, sigdata, keyID, pubkey)) { |
| 262 | // Pubkey could not be found, add to missing |
| 263 | sigdata.missing_pubkeys.push_back(keyID); |
| 264 | return false; |
| 265 | } |
| 266 | if (!CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion, flags)) return false; |
| 267 | ret.push_back(std::move(sig)); |
| 268 | ret.push_back(ToByteVector(pubkey)); |
| 269 | return true; |
| 270 | } |
| 271 | case TxoutType::SCRIPTHASH: |
| 272 | h160 = uint160(vSolutions[0]); |
| 273 | if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) { |
| 274 | ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end())); |
| 275 | return true; |
| 276 | } |
| 277 | // Could not find redeemScript, add to missing |
| 278 | sigdata.missing_redeem_script = h160; |
| 279 | return false; |
| 280 | |
| 281 | case TxoutType::MULTISIG: { |
| 282 | size_t required = vSolutions.front()[0]; |
| 283 | ret.push_back(valtype()); // workaround CHECKMULTISIG bug |
| 284 | for (size_t i = 1; i < vSolutions.size() - 1; ++i) { |
| 285 | CPubKey pubkey = CPubKey(vSolutions[i]); |
| 286 | // We need to always call CreateSig in order to fill sigdata with all |
| 287 | // possible signatures that we can create. This will allow further PSBT |
| 288 | // processing to work as it needs all possible signature and pubkey pairs |
| 289 | if (CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion, flags)) { |
| 290 | if (ret.size() < required + 1) { |
| 291 | ret.push_back(std::move(sig)); |
| 292 | } |
| 293 | } |
| 294 | } |
no test coverage detected