diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -497,7 +497,7 @@ CPubKey pubkey; PKHash *pkhash = boost::get(&address); if (pkhash && model->wallet().getPubKey(out.txout.scriptPubKey, - CKeyID(*pkhash), pubkey)) { + ToKeyID(*pkhash), pubkey)) { nBytesInputs += (pubkey.IsCompressed() ? 148 : 180); } else { // in all error cases, simply assume 148 here diff --git a/src/script/sign.cpp b/src/script/sign.cpp --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -143,7 +143,7 @@ } case TxoutType::SCRIPTHASH: h160 = uint160(vSolutions[0]); - if (GetCScript(provider, sigdata, h160, scriptRet)) { + if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) { ret.push_back( std::vector(scriptRet.begin(), scriptRet.end())); return true; diff --git a/src/script/signingprovider.cpp b/src/script/signingprovider.cpp --- a/src/script/signingprovider.cpp +++ b/src/script/signingprovider.cpp @@ -164,7 +164,7 @@ const CTxDestination &dest) { // Only supports destinations which map to single public keys, i.e. P2PKH. if (auto id = boost::get(&dest)) { - return CKeyID(*id); + return ToKeyID(*id); } return CKeyID(); } diff --git a/src/script/standard.h b/src/script/standard.h --- a/src/script/standard.h +++ b/src/script/standard.h @@ -19,13 +19,52 @@ class CKeyID; class CScript; +struct ScriptHash; + +template class BaseHash { +protected: + HashType m_hash; + +public: + BaseHash() : m_hash() {} + BaseHash(const HashType &in) : m_hash(in) {} + + uint8_t *begin() { return m_hash.begin(); } + + const uint8_t *begin() const { return m_hash.begin(); } + + uint8_t *end() { return m_hash.end(); } + + const uint8_t *end() const { return m_hash.end(); } + + operator std::vector() const { + return std::vector{m_hash.begin(), m_hash.end()}; + } + + std::string ToString() const { return m_hash.ToString(); } + + bool operator==(const BaseHash &other) const noexcept { + return m_hash == other.m_hash; + } + + bool operator!=(const BaseHash &other) const noexcept { + return !(m_hash == other.m_hash); + } + + bool operator<(const BaseHash &other) const noexcept { + return m_hash < other.m_hash; + } + + size_t size() const { return m_hash.size(); } +}; /** A reference to a CScript: the Hash160 of its serialization (see script.h) */ -class CScriptID : public uint160 { +class CScriptID : public BaseHash { public: - CScriptID() : uint160() {} + CScriptID() : BaseHash() {} explicit CScriptID(const CScript &in); - CScriptID(const uint160 &in) : uint160(in) {} + explicit CScriptID(const uint160 &in) : BaseHash(in) {} + explicit CScriptID(const ScriptHash &in); }; /** @@ -61,22 +100,23 @@ } }; -struct PKHash : public uint160 { - PKHash() : uint160() {} - explicit PKHash(const uint160 &hash) : uint160(hash) {} +struct PKHash : public BaseHash { + PKHash() : BaseHash() {} + explicit PKHash(const uint160 &hash) : BaseHash(hash) {} explicit PKHash(const CPubKey &pubkey); - using uint160::uint160; + explicit PKHash(const CKeyID &pubkey_id); }; +CKeyID ToKeyID(const PKHash &key_hash); -struct ScriptHash : public uint160 { - ScriptHash() : uint160() {} +struct ScriptHash : public BaseHash { + ScriptHash() : BaseHash() {} // This doesn't do what you'd expect. // Use ScriptHash(GetScriptForDestination(...)) instead. explicit ScriptHash(const PKHash &hash) = delete; - explicit ScriptHash(const uint160 &hash) : uint160(hash) {} + explicit ScriptHash(const uint160 &hash) : BaseHash(hash) {} explicit ScriptHash(const CScript &script); - using uint160::uint160; + explicit ScriptHash(const CScriptID &script); }; /** diff --git a/src/script/standard.cpp b/src/script/standard.cpp --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -15,12 +15,21 @@ bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER; CScriptID::CScriptID(const CScript &in) - : uint160(Hash160(in.begin(), in.end())) {} + : BaseHash(Hash160(in.begin(), in.end())) {} +CScriptID::CScriptID(const ScriptHash &in) + : BaseHash(static_cast(in)) {} ScriptHash::ScriptHash(const CScript &in) - : uint160(Hash160(in.begin(), in.end())) {} + : BaseHash(Hash160(in.begin(), in.end())) {} +ScriptHash::ScriptHash(const CScriptID &in) + : BaseHash(static_cast(in)) {} -PKHash::PKHash(const CPubKey &pubkey) : uint160(pubkey.GetID()) {} +PKHash::PKHash(const CPubKey &pubkey) : BaseHash(pubkey.GetID()) {} +PKHash::PKHash(const CKeyID &pubkey_id) : BaseHash(pubkey_id) {} + +CKeyID ToKeyID(const PKHash &key_hash) { + return CKeyID{static_cast(key_hash)}; +} std::string GetTxnOutputType(TxoutType t) { switch (t) { diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -352,8 +352,8 @@ pwallet->ImportScripts(scripts, 0 /* timestamp */); if (fP2SH) { - scripts.insert(GetScriptForDestination( - ScriptHash(CScriptID(redeem_script)))); + scripts.insert( + GetScriptForDestination(ScriptHash(redeem_script))); } pwallet->ImportScriptPubKeys( diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4245,7 +4245,7 @@ } UniValue operator()(const PKHash &pkhash) const { - CKeyID keyID(pkhash); + CKeyID keyID(ToKeyID(pkhash)); UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; if (provider && provider->GetPubKey(keyID, vchPubKey)) { diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -483,9 +483,8 @@ SigningResult LegacyScriptPubKeyMan::SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const { - CKeyID key_id(pkhash); CKey key; - if (!GetKey(key_id, key)) { + if (!GetKey(ToKeyID(pkhash), key)) { return SigningResult::PRIVATE_KEY_NOT_AVAILABLE; } @@ -2055,9 +2054,8 @@ return SigningResult::PRIVATE_KEY_NOT_AVAILABLE; } - CKeyID key_id(pkhash); CKey key; - if (!keys->GetKey(key_id, key)) { + if (!keys->GetKey(ToKeyID(pkhash), key)) { return SigningResult::PRIVATE_KEY_NOT_AVAILABLE; }