Changeset View
Changeset View
Standalone View
Standalone View
src/script/sign.cpp
Show All 31 Lines | bool TransactionSignatureCreator::CreateSig(const SigningProvider &provider, | ||||
if (!key.SignECDSA(hash, vchSig)) { | if (!key.SignECDSA(hash, vchSig)) { | ||||
return false; | return false; | ||||
} | } | ||||
vchSig.push_back(uint8_t(sigHashType.getRawSigHashType())); | vchSig.push_back(uint8_t(sigHashType.getRawSigHashType())); | ||||
return true; | return true; | ||||
} | } | ||||
static bool Sign1(const SigningProvider &provider, const CKeyID &address, | |||||
const BaseSignatureCreator &creator, | |||||
const CScript &scriptCode, std::vector<valtype> &ret) { | |||||
std::vector<uint8_t> vchSig; | |||||
if (!creator.CreateSig(provider, vchSig, address, scriptCode)) { | |||||
return false; | |||||
} | |||||
ret.push_back(vchSig); | |||||
return true; | |||||
} | |||||
static bool SignN(const SigningProvider &provider, | |||||
const std::vector<valtype> &multisigdata, | |||||
const BaseSignatureCreator &creator, | |||||
const CScript &scriptCode, std::vector<valtype> &ret) { | |||||
int nSigned = 0; | |||||
int nRequired = multisigdata.front()[0]; | |||||
for (size_t i = 1; i < multisigdata.size() - 1 && nSigned < nRequired; | |||||
i++) { | |||||
const valtype &pubkey = multisigdata[i]; | |||||
CKeyID keyID = CPubKey(pubkey).GetID(); | |||||
if (Sign1(provider, keyID, creator, scriptCode, ret)) { | |||||
++nSigned; | |||||
} | |||||
} | |||||
return nSigned == nRequired; | |||||
} | |||||
/** | /** | ||||
* Sign scriptPubKey using signature made with creator. | * Sign scriptPubKey using signature made with creator. | ||||
* Signatures are returned in scriptSigRet (or returns false if scriptPubKey | * Signatures are returned in scriptSigRet (or returns false if scriptPubKey | ||||
* can't be signed), unless whichTypeRet is TX_SCRIPTHASH, in which case | * can't be signed), unless whichTypeRet is TX_SCRIPTHASH, in which case | ||||
* scriptSigRet is the redemption script. | * scriptSigRet is the redemption script. | ||||
* Returns false if scriptPubKey could not be completely satisfied. | * Returns false if scriptPubKey could not be completely satisfied. | ||||
*/ | */ | ||||
static bool SignStep(const SigningProvider &provider, | static bool SignStep(const SigningProvider &provider, | ||||
const BaseSignatureCreator &creator, | const BaseSignatureCreator &creator, | ||||
const CScript &scriptPubKey, std::vector<valtype> &ret, | const CScript &scriptPubKey, std::vector<valtype> &ret, | ||||
txnouttype &whichTypeRet) { | txnouttype &whichTypeRet) { | ||||
CScript scriptRet; | CScript scriptRet; | ||||
uint160 h160; | uint160 h160; | ||||
ret.clear(); | ret.clear(); | ||||
std::vector<uint8_t> sig; | |||||
std::vector<valtype> vSolutions; | std::vector<valtype> vSolutions; | ||||
if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) { | if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) { | ||||
return false; | return false; | ||||
} | } | ||||
CKeyID keyID; | |||||
switch (whichTypeRet) { | switch (whichTypeRet) { | ||||
case TX_NONSTANDARD: | case TX_NONSTANDARD: | ||||
case TX_NULL_DATA: | case TX_NULL_DATA: | ||||
return false; | return false; | ||||
case TX_PUBKEY: | case TX_PUBKEY: | ||||
keyID = CPubKey(vSolutions[0]).GetID(); | if (!creator.CreateSig(provider, sig, | ||||
return Sign1(provider, keyID, creator, scriptPubKey, ret); | CPubKey(vSolutions[0]).GetID(), | ||||
scriptPubKey)) { | |||||
return false; | |||||
} | |||||
ret.push_back(std::move(sig)); | |||||
return true; | |||||
case TX_PUBKEYHASH: { | case TX_PUBKEYHASH: { | ||||
keyID = CKeyID(uint160(vSolutions[0])); | CKeyID keyID = CKeyID(uint160(vSolutions[0])); | ||||
if (!Sign1(provider, keyID, creator, scriptPubKey, ret)) { | if (!creator.CreateSig(provider, sig, keyID, scriptPubKey)) { | ||||
return false; | return false; | ||||
} | } | ||||
ret.push_back(std::move(sig)); | |||||
CPubKey vch; | CPubKey pubkey; | ||||
provider.GetPubKey(keyID, vch); | provider.GetPubKey(keyID, pubkey); | ||||
ret.push_back(ToByteVector(vch)); | ret.push_back(ToByteVector(pubkey)); | ||||
return true; | return true; | ||||
} | } | ||||
case TX_SCRIPTHASH: | case TX_SCRIPTHASH: | ||||
if (provider.GetCScript(uint160(vSolutions[0]), scriptRet)) { | if (provider.GetCScript(uint160(vSolutions[0]), scriptRet)) { | ||||
ret.push_back( | ret.push_back( | ||||
std::vector<uint8_t>(scriptRet.begin(), scriptRet.end())); | std::vector<uint8_t>(scriptRet.begin(), scriptRet.end())); | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
case TX_MULTISIG: | case TX_MULTISIG: { | ||||
size_t required = vSolutions.front()[0]; | |||||
// workaround CHECKMULTISIG bug | // workaround CHECKMULTISIG bug | ||||
ret.push_back(valtype()); | ret.push_back(valtype()); | ||||
return (SignN(provider, vSolutions, creator, scriptPubKey, ret)); | for (size_t i = 1; i < vSolutions.size() - 1; ++i) { | ||||
CPubKey pubkey = CPubKey(vSolutions[i]); | |||||
if (ret.size() < required + 1 && | |||||
creator.CreateSig(provider, sig, pubkey.GetID(), | |||||
scriptPubKey)) { | |||||
ret.push_back(std::move(sig)); | |||||
} | |||||
} | |||||
bool ok = ret.size() == required + 1; | |||||
for (size_t i = 0; i + ret.size() < required + 1; ++i) { | |||||
ret.push_back(valtype()); | |||||
} | |||||
return ok; | |||||
} | |||||
default: | default: | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
static CScript PushAll(const std::vector<valtype> &values) { | static CScript PushAll(const std::vector<valtype> &values) { | ||||
CScript result; | CScript result; | ||||
for (const valtype &v : values) { | for (const valtype &v : values) { | ||||
▲ Show 20 Lines • Show All 267 Lines • Show Last 20 Lines |