diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 53d41ea1a5..b6a8524f23 100755 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -8,9 +8,9 @@ TEST_SRCDIR = test TEST_BINARY=test/test_gridcoin$(EXEEXT) JSON_TEST_FILES = \ - test/data/base58_keys_valid.json \ test/data/base58_encode_decode.json \ - test/data/base58_keys_invalid.json \ + test/data/key_io_invalid.json \ + test/data/key_io_valid.json \ test/data/script_valid.json \ test/data/script_invalid.json \ test/data/tx_invalid.json \ @@ -59,6 +59,7 @@ GRIDCOIN_TESTS =\ test/gridcoin/sidestake_tests.cpp \ test/gridcoin/superblock_tests.cpp \ test/key_tests.cpp \ + test/key_io_tests.cpp \ test/merkle_tests.cpp \ test/mruset_tests.cpp \ test/multisig_tests.cpp \ diff --git a/src/base58.h b/src/base58.h index 214f021a0c..d085f5e778 100644 --- a/src/base58.h +++ b/src/base58.h @@ -60,292 +60,4 @@ std::string EncodeBase58Check(const std::vector& vchIn); [[nodiscard]] bool DecodeBase58Check(const std::string& str, std::vector& vchRet, int max_ret_len = std::numeric_limits::max() - 4); - -/** Base class for all base58-encoded data */ -class CBase58Data -{ -protected: - // the version byte - unsigned char nVersion; - - // the actually encoded data - std::vector vchData; - - CBase58Data() - { - nVersion = 0; - vchData.clear(); - } - - ~CBase58Data() - { - // zero the memory, as it may contain sensitive data - if (!vchData.empty()) - memory_cleanse(&vchData[0], vchData.size()); - } - - void SetData(int nVersionIn, const void* pdata, size_t nSize) - { - nVersion = nVersionIn; - vchData.resize(nSize); - if (!vchData.empty()) - memcpy(&vchData[0], pdata, nSize); - } - - void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend) - { - SetData(nVersionIn, (void*)pbegin, pend - pbegin); - } - -public: - bool SetString(const char* psz) - { - std::vector vchTemp; - if (!DecodeBase58Check(psz, vchTemp)) - { - vchData.clear(); - nVersion = 0; - return false; - } - nVersion = vchTemp[0]; - vchData.resize(vchTemp.size() - 1); - if (!vchData.empty()) - memcpy(&vchData[0], &vchTemp[1], vchData.size()); - memory_cleanse(&vchTemp[0], vchTemp.size()); - return true; - } - - bool SetString(const std::string& str) - { - return SetString(str.c_str()); - } - - std::string ToString() const - { - std::vector vch(1, nVersion); - vch.insert(vch.end(), vchData.begin(), vchData.end()); - return EncodeBase58Check(vch); - } - - int CompareTo(const CBase58Data& b58) const - { - if (nVersion < b58.nVersion) return -1; - if (nVersion > b58.nVersion) return 1; - if (vchData < b58.vchData) return -1; - if (vchData > b58.vchData) return 1; - return 0; - } - - bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; } - bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; } - bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; } - bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; } - bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; } -}; - -/** base58-encoded addresses. - * Public-key-hash-addresses have version 25 (or 111 testnet). - * The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key. - * Script-hash-addresses have version 85 (or 196 testnet). - * The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script. - */ -class CBitcoinAddress; -class CBitcoinAddressVisitor -{ -private: - CBitcoinAddress *addr; -public: - CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { } - bool operator()(const CKeyID &id) const; - bool operator()(const CScriptID &id) const; - bool operator()(const CNoDestination &no) const; -}; - -class CBitcoinAddress : public CBase58Data -{ -public: - enum - { - //Base58Gridcoin: - PUBKEY_ADDRESS = 62, // Gridcoin Research addresses start with R - 62, (Classic Starts with G: 37) - SCRIPT_ADDRESS = 85, - PUBKEY_ADDRESS_TEST = 111, - SCRIPT_ADDRESS_TEST = 196, - }; - - bool Set(const CKeyID &id) { - SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &id, 20); - return true; - } - - bool Set(const CScriptID &id) { - SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &id, 20); - return true; - } - - bool Set(const CTxDestination &dest) - { - return std::visit(CBitcoinAddressVisitor(this), dest); - } - - bool IsValid() const - { - unsigned int nExpectedSize = 20; - bool fExpectTestNet = false; - switch(nVersion) - { - case PUBKEY_ADDRESS: - nExpectedSize = 20; // Hash of public key - fExpectTestNet = false; - break; - case SCRIPT_ADDRESS: - nExpectedSize = 20; // Hash of CScript - fExpectTestNet = false; - break; - - case PUBKEY_ADDRESS_TEST: - nExpectedSize = 20; - fExpectTestNet = true; - break; - case SCRIPT_ADDRESS_TEST: - nExpectedSize = 20; - fExpectTestNet = true; - break; - - default: - return false; - } - return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize; - } - - CBitcoinAddress() - { - } - - CBitcoinAddress(const CTxDestination &dest) - { - Set(dest); - } - - CBitcoinAddress(const std::string& strAddress) - { - SetString(strAddress); - } - - CBitcoinAddress(const char* pszAddress) - { - SetString(pszAddress); - } - - CTxDestination Get() const { - if (!IsValid()) - return CNoDestination(); - switch (nVersion) { - case PUBKEY_ADDRESS: - case PUBKEY_ADDRESS_TEST: { - uint160 id; - memcpy(&id, &vchData[0], 20); - return CKeyID(id); - } - case SCRIPT_ADDRESS: - case SCRIPT_ADDRESS_TEST: { - uint160 id; - memcpy(&id, &vchData[0], 20); - return CScriptID(id); - } - } - return CNoDestination(); - } - - bool GetKeyID(CKeyID &keyID) const { - if (!IsValid()) - return false; - switch (nVersion) { - case PUBKEY_ADDRESS: - case PUBKEY_ADDRESS_TEST: { - uint160 id; - memcpy(&id, &vchData[0], 20); - keyID = CKeyID(id); - return true; - } - default: return false; - } - } - - bool IsScript() const { - if (!IsValid()) - return false; - switch (nVersion) { - case SCRIPT_ADDRESS: - case SCRIPT_ADDRESS_TEST: { - return true; - } - default: return false; - } - } -}; - -bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { return addr->Set(id); } -bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); } -bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; } - -/** A base58-encoded secret key */ -class CBitcoinSecret : public CBase58Data -{ -public: - void SetSecret(const CSecret& vchSecret, bool fCompressed) - { - assert(vchSecret.size() == 32); - SetData(128 + (fTestNet ? CBitcoinAddress::PUBKEY_ADDRESS_TEST : CBitcoinAddress::PUBKEY_ADDRESS), &vchSecret[0], vchSecret.size()); - if (fCompressed) - vchData.push_back(1); - } - - CSecret GetSecret(bool &fCompressedOut) - { - CSecret vchSecret; - vchSecret.resize(32); - memcpy(&vchSecret[0], &vchData[0], 32); - fCompressedOut = vchData.size() == 33; - return vchSecret; - } - - bool IsValid() const - { - bool fExpectTestNet = false; - switch(nVersion) - { - case (128 + CBitcoinAddress::PUBKEY_ADDRESS): - break; - - case (128 + CBitcoinAddress::PUBKEY_ADDRESS_TEST): - fExpectTestNet = true; - break; - - default: - return false; - } - return fExpectTestNet == fTestNet && (vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1)); - } - - bool SetString(const char* pszSecret) - { - return CBase58Data::SetString(pszSecret) && IsValid(); - } - - bool SetString(const std::string& strSecret) - { - return SetString(strSecret.c_str()); - } - - CBitcoinSecret(const CSecret& vchSecret, bool fCompressed) - { - SetSecret(vchSecret, fCompressed); - } - - CBitcoinSecret() - { - } -}; - #endif diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 53d8ca56d8..a2d2d8d790 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -102,7 +102,7 @@ class CMainParams : public CChainParams { base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,62); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,85); - base58Prefixes[SECRET_KEY] = std::vector(1,0); // TODO: What should be the exact value here? 128 + PUBKEY_ADDRESS as 4 bytes? + base58Prefixes[SECRET_KEY] = std::vector(1,190); base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4}; @@ -213,7 +213,7 @@ class CTestNetParams : public CChainParams { base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); - base58Prefixes[SECRET_KEY] = std::vector(1,0); // TODO: What should be the exact value here? 128 + PUBKEY_ADDRESS as 4 bytes? + base58Prefixes[SECRET_KEY] = std::vector(1,239); base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; diff --git a/src/crypter.cpp b/src/crypter.cpp index fab1defe50..29e6a88573 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -114,7 +114,7 @@ bool CCrypter::Decrypt(const std::vector& vchCiphertext, CKeyingM } -bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext) +bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext) { CCrypter cKeyCrypter; std::vector chIV(WALLET_CRYPTO_KEY_SIZE); @@ -124,7 +124,7 @@ bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, con return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext); } -bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext) +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext) { CCrypter cKeyCrypter; std::vector chIV(WALLET_CRYPTO_KEY_SIZE); diff --git a/src/crypter.h b/src/crypter.h index d3f1be407c..9bdb51def4 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -120,8 +120,8 @@ class CCrypter }; -bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext); -bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector &vchCiphertext, const uint256& nIV, CSecret &vchPlaintext); +bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext); +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector &vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext); bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key); #endif // BITCOIN_CRYPTER_H diff --git a/src/gridcoin/backup.cpp b/src/gridcoin/backup.cpp index de5456fb26..1e63af065a 100644 --- a/src/gridcoin/backup.cpp +++ b/src/gridcoin/backup.cpp @@ -336,29 +336,3 @@ bool GRC::MaintainBackups(fs::path wallet_backup_path, std::vector return true; } -bool GRC::BackupPrivateKeys(const CWallet& wallet, std::string& sTarget, std::string& sErrors) -{ - if (wallet.IsLocked() || fWalletUnlockStakingOnly) - { - sErrors = "Wallet needs to be fully unlocked to backup private keys."; - return false; - } - fs::path PrivateKeysTarget = GetBackupFilename("keys.dat"); - fs::create_directories(PrivateKeysTarget.parent_path()); - sTarget = PrivateKeysTarget.string(); - fsbridge::ofstream myBackup; - myBackup.open(PrivateKeysTarget); - std::string sError; - for(const auto& keyPair : wallet.GetAllPrivateKeys(sError)) - { - if (!sError.empty()) - { - sErrors = sError; - return false; - } - myBackup << "Address: " << keyPair.first.ToString() << ", Secret: " << keyPair.second.ToString() << std::endl; - } - LogPrintf("BackupPrivateKeys: Backup made to %s", PrivateKeysTarget.string()); - myBackup.close(); - return true; -} diff --git a/src/gridcoin/backup.h b/src/gridcoin/backup.h index 082f5c4657..f7aba4ee32 100644 --- a/src/gridcoin/backup.h +++ b/src/gridcoin/backup.h @@ -23,7 +23,6 @@ bool BackupConfigFile(const std::string& strDest); bool MaintainBackups(fs::path wallet_backup_path, std::vector backup_file_type, unsigned int retention_by_num, unsigned int retention_by_days, std::vector& files_removed); bool BackupWallet(const CWallet& wallet, const std::string& strDest); -bool BackupPrivateKeys(const CWallet& wallet, std::string& sTarget, std::string& sErrors); } #endif // GRIDCOIN_BACKUP_H diff --git a/src/gridcoin/beacon.cpp b/src/gridcoin/beacon.cpp index 3fdcfc9e61..e629e18b32 100644 --- a/src/gridcoin/beacon.cpp +++ b/src/gridcoin/beacon.cpp @@ -2,7 +2,8 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or https://opensource.org/licenses/mit-license.php. -#include "base58.h" +#include +#include #include "logging.h" #include "main.h" #include "gridcoin/beacon.h" @@ -105,7 +106,7 @@ bool Beacon::WellFormed() const std::pair Beacon::KeyValueToString() const { - return std::make_pair(m_cpid.ToString(), GetAddress().ToString()); + return std::make_pair(m_cpid.ToString(), EncodeDestination(GetAddress())); } std::string Beacon::StatusToString() const @@ -184,9 +185,9 @@ CKeyID Beacon::GetId() const return m_public_key.GetID(); } -CBitcoinAddress Beacon::GetAddress() const +CTxDestination Beacon::GetAddress() const { - return CBitcoinAddress(CTxDestination(m_public_key.GetID())); + return CTxDestination(m_public_key.GetID()); } std::string Beacon::GetVerificationCode() const @@ -209,7 +210,7 @@ std::string Beacon::ToString() const { return EncodeBase64( "0;0;" // Unused: [CPIDv2];[nonce]; - + GetAddress().ToString() + + EncodeDestination(GetAddress()) + ";" + HexStr(m_public_key)); } @@ -429,7 +430,7 @@ bool BeaconRegistry::TryRenewal(Beacon_ptr& current_beacon_ptr, int& height, con "contracts in the same block get stored/replayed.", __func__, renewal.m_cpid.ToString(), - renewal.GetAddress().ToString(), + EncodeDestination(renewal.GetAddress()), renewal.m_hash.GetHex()); } @@ -498,7 +499,7 @@ void BeaconRegistry::Add(const ContractContext& ctx) "contracts in the same block get stored/replayed.", __func__, historical.m_cpid.ToString(), - historical.GetAddress().ToString(), + EncodeDestination(historical.GetAddress()), historical.m_hash.GetHex()); } m_beacons[payload.m_cpid] = m_beacon_db.find(ctx.m_tx.GetHash())->second; @@ -530,7 +531,7 @@ void BeaconRegistry::Add(const ContractContext& ctx) "contracts in the same block get stored/replayed.", __func__, pending.m_cpid.ToString(), - pending.GetAddress().ToString(), + EncodeDestination(pending.GetAddress()), pending.m_hash.GetHex()); } @@ -1072,7 +1073,7 @@ void BeaconRegistry::ActivatePending( LogPrint(LogFlags::BEACON, "INFO: %s: Activating beacon for cpid %s, address %s, hash %s.", __func__, activated_beacon.m_cpid.ToString(), - activated_beacon.GetAddress().ToString(), + EncodeDestination(activated_beacon.GetAddress()), activated_beacon.m_hash.GetHex()); m_beacon_db.insert(activated_beacon.m_hash, height, activated_beacon); @@ -1108,7 +1109,7 @@ void BeaconRegistry::ActivatePending( LogPrint(LogFlags::BEACON, "INFO: %s: Marking pending beacon expired for cpid %s, address %s, hash %s.", __func__, pending_beacon.m_cpid.ToString(), - pending_beacon.GetAddress().ToString(), + EncodeDestination(pending_beacon.GetAddress()), pending_beacon.m_hash.GetHex()); // Insert the expired pending beacon into the db. @@ -1194,7 +1195,7 @@ void BeaconRegistry::Deactivate(const uint256 superblock_hash) pending_beacon_entry->second->m_hash.GetHex(), pending_beacon_entry->second->m_cpid.ToString(), superblock_hash.GetHex(), - pending_beacon_entry->second->GetAddress().ToString() + EncodeDestination(pending_beacon_entry->second->GetAddress()) ); } } diff --git a/src/gridcoin/beacon.h b/src/gridcoin/beacon.h index e97d1fd0f3..cc2d0333f0 100644 --- a/src/gridcoin/beacon.h +++ b/src/gridcoin/beacon.h @@ -17,7 +17,6 @@ #include #include -class CBitcoinAddress; class CTransaction; class CWallet; @@ -218,7 +217,7 @@ class Beacon //! //! \return Address produced from the beacon's public key. //! - CBitcoinAddress GetAddress() const; + CTxDestination GetAddress() const; //! //! \brief Get the code that the scrapers use to verify the beacon. diff --git a/src/gridcoin/contract/message.cpp b/src/gridcoin/contract/message.cpp index a08ff23e4f..b6bf70496f 100644 --- a/src/gridcoin/contract/message.cpp +++ b/src/gridcoin/contract/message.cpp @@ -27,7 +27,7 @@ namespace { //! bool SelectMasterInputOutput(CCoinControl& coin_control) { - const CTxDestination master_address = CWallet::MasterAddress(pindexBest->nHeight).Get(); + const CTxDestination master_address = CWallet::MasterAddress(pindexBest->nHeight); // Send change back to the master address: coin_control.destChange = master_address; @@ -86,7 +86,7 @@ bool CreateContractTx(CWalletTx& wtx_out, CReserveKey& reserve_key, CAmount burn coin_control_out.destChange = out_address; LogPrintf("INFO: %s: Change sent to %s for contract transaction per contractchangetoinputaddress setting.", - __func__, CBitcoinAddress(coin_control_out.destChange).ToString()); + __func__, EncodeDestination(coin_control_out.destChange)); } for (const auto& contract : wtx_out.vContracts) { diff --git a/src/gridcoin/quorum.cpp b/src/gridcoin/quorum.cpp index c0d04a4753..893677cd0a 100644 --- a/src/gridcoin/quorum.cpp +++ b/src/gridcoin/quorum.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or https://opensource.org/licenses/mit-license.php. -#include "base58.h" +#include #include "chainparams.h" #include "main.h" #include "gridcoin/claim.h" @@ -253,7 +253,7 @@ class QuorumVote { public: const QuorumHash m_hash; //!< Hash of the superblock to vote for. - const CBitcoinAddress m_address; //!< Address of the voting wallet. + const CTxDestination m_address; //!< Address of the voting wallet. const CBlockIndex* const m_pindex; //!< Block that contains the vote. //! @@ -263,7 +263,7 @@ class QuorumVote //! \param address Default address of the voting wallet. //! \param pindex Block that contains the vote. //! - QuorumVote(QuorumHash hash, CBitcoinAddress address, const CBlockIndex* pindex) + QuorumVote(QuorumHash hash, CTxDestination address, const CBlockIndex* pindex) : m_hash(hash) , m_address(std::move(address)) , m_pindex(pindex) @@ -374,9 +374,9 @@ class LegacyConsensus return; } - CBitcoinAddress address(grc_address); + CTxDestination address = DecodeDestination(grc_address); - if (!address.IsValid()) { + if (!IsValidDestination(address)) { LogPrint(BCLog::LogFlags::VERBOSE, "Quorum::RecordVote: invalid address: %s HASH: %s", grc_address, @@ -509,7 +509,7 @@ class LegacyConsensus const int64_t min_height = last_height - STANDARD_LOOKBACK; PopularityMap popularity_map; - std::map addresses_seen; + std::map addresses_seen; for (const auto& vote_pair : reverse_iterate(m_votes)) { const int64_t vote_height = vote_pair.first; @@ -1557,9 +1557,9 @@ bool Quorum::ValidateSuperblockClaim( return ValidateSuperblock(superblock); } - const CBitcoinAddress address(claim.m_quorum_address); + const CTxDestination address = DecodeDestination(claim.m_quorum_address); - if (!address.IsValid()) { + if (!IsValidDestination(address)) { return error("ValidateSuperblockClaim(): " "invalid quorum address: %s", claim.m_quorum_address); } diff --git a/src/gridcoin/scraper/scraper.cpp b/src/gridcoin/scraper/scraper.cpp index d654f88d4a..0dfcb83578 100755 --- a/src/gridcoin/scraper/scraper.cpp +++ b/src/gridcoin/scraper/scraper.cpp @@ -442,7 +442,7 @@ bool ScraperSaveCScraperManifestToFiles(uint256 nManifestHash); * @param Key * @return bool true if successful */ -bool ScraperSendFileManifestContents(CBitcoinAddress& Address, CKey& Key); +bool ScraperSendFileManifestContents(CTxDestination& Address, CKey& Key); /** * @brief Sorts the inventory of CScraperManifests by scraper and orders by manifest time, which is important for * convergence determination @@ -1493,7 +1493,7 @@ void Scraper(bool bSingleShot) int64_t sbage = SuperblockAge(); int64_t nScraperThreadStartTime = GetAdjustedTime(); - CBitcoinAddress AddressOut; + CTxDestination AddressOut; CKey KeyOut; // These are to ensure thread-safety of these globals and keep the locking scope to a minimum. These will go away @@ -4116,7 +4116,7 @@ bool IsScraperAuthorized() return ALLOW_NONSCRAPER_NODE_STATS_DOWNLOAD; } -bool IsScraperAuthorizedToBroadcastManifests(CBitcoinAddress& AddressOut, CKey& KeyOut) +bool IsScraperAuthorizedToBroadcastManifests(CTxDestination& AddressOut, CKey& KeyOut) { AppCacheSection mScrapers = GetScrapersCache(); @@ -4138,23 +4138,22 @@ bool IsScraperAuthorizedToBroadcastManifests(CBitcoinAddress& AddressOut, CKey& { _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "Entry in appcache is enabled."); - CBitcoinAddress address(sScraperAddressFromConfig); + CTxDestination address = DecodeDestination(sScraperAddressFromConfig); //CPubKey ScraperPubKey(ParseHex(sScraperAddressFromConfig)); - CKeyID KeyID; - address.GetKeyID(KeyID); + CKeyID* KeyID = std::get_if(&address); // ... and the address is valid... - if (address.IsValid()) + if (KeyID) { _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "The address is valid."); _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", - "(Doublecheck) The address is " + address.ToString()); + "(Doublecheck) The address is " + EncodeDestination(address)); // ... and it exists in the wallet... LOCK(pwalletMain->cs_wallet); - if (pwalletMain->GetKey(KeyID, KeyOut)) + if (pwalletMain->GetKey(*KeyID, KeyOut)) { // ... and the key returned from the wallet is valid and matches the provided public key... assert(KeyOut.IsValid()); @@ -4189,9 +4188,9 @@ bool IsScraperAuthorizedToBroadcastManifests(CBitcoinAddress& AddressOut, CKey& for (auto const& item : pwalletMain->mapAddressBook) { - const CBitcoinAddress& address = item.first; + const CTxDestination& address = item.first; - std::string sScraperAddress = address.ToString(); + std::string sScraperAddress = EncodeDestination(address); _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "Checking address " + sScraperAddress); entry = mScrapers.find(sScraperAddress); @@ -4206,18 +4205,17 @@ bool IsScraperAuthorizedToBroadcastManifests(CBitcoinAddress& AddressOut, CKey& { _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "AppCache entry enabled"); - CKeyID KeyID; - address.GetKeyID(KeyID); + const CKeyID* KeyID = std::get_if(&address); // ... and the address is valid... - if (address.IsValid()) + if (KeyID) { _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "The address is valid."); _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", - "(Doublecheck) The address is " + address.ToString()); + "(Doublecheck) The address is " + EncodeDestination(address)); // ... and it exists in the wallet... (It SHOULD here... it came from the map...) - if (pwalletMain->GetKey(KeyID, KeyOut)) + if (pwalletMain->GetKey(*KeyID, KeyOut)) { // ... and the key returned from the wallet is valid ... assert(KeyOut.IsValid()); @@ -4264,11 +4262,10 @@ EXCLUSIVE_LOCKS_REQUIRED(CScraperManifest::cs_mapManifest) CKeyID ManifestKeyID = PubKey.GetID(); - CBitcoinAddress ManifestAddress; - ManifestAddress.Set(ManifestKeyID); + CTxDestination ManifestAddress(ManifestKeyID); // This is the address corresponding to the manifest public key, and is the scraper ID key in the outer map. - std::string sManifestAddress = ManifestAddress.ToString(); + std::string sManifestAddress = EncodeDestination(ManifestAddress); const auto& iScraper = mMapCSManifestBinnedByScraper.find(sManifestAddress); @@ -4411,7 +4408,7 @@ unsigned int ScraperDeleteUnauthorizedCScraperManifests() return nDeleted; } -bool ScraperSendFileManifestContents(CBitcoinAddress& Address, CKey& Key) +bool ScraperSendFileManifestContents(CTxDestination& Address, CKey& Key) EXCLUSIVE_LOCKS_REQUIRED(cs_StructScraperFileManifest, CScraperManifest::cs_mapManifest) { // This "broadcasts" the current ScraperFileManifest contents to the network. @@ -4429,10 +4426,10 @@ EXCLUSIVE_LOCKS_REQUIRED(cs_StructScraperFileManifest, CScraperManifest::cs_mapM LOCK2(CSplitBlob::cs_mapParts, manifest->cs_manifest); // The manifest name is the authorized address of the scraper. - manifest->sCManifestName = Address.ToString(); + manifest->sCManifestName = EncodeDestination(Address); // Also store local sCManifestName, because the manifest will be std::moved by addManifest. - sCManifestName = Address.ToString(); + sCManifestName = EncodeDestination(Address); manifest->nTime = StructScraperFileManifest.timestamp; @@ -5802,7 +5799,7 @@ UniValue sendscraperfilemanifest(const UniValue& params, bool fHelp) "Send a CScraperManifest object from the current ScraperFileManifest.\n" ); - CBitcoinAddress AddressOut; + CTxDestination AddressOut; CKey KeyOut; bool ret; if (IsScraperAuthorizedToBroadcastManifests(AddressOut, KeyOut)) diff --git a/src/gridcoin/scraper/scraper.h b/src/gridcoin/scraper/scraper.h index f07c56f020..a32e543ba8 100644 --- a/src/gridcoin/scraper/scraper.h +++ b/src/gridcoin/scraper/scraper.h @@ -159,7 +159,7 @@ bool IsScraperAuthorized(); * modified to bypass this check, so messages sent will also be validated on receipt by the complement * to this function, IsManifestAuthorized(CKey& Key) in the CScraperManifest class. */ -bool IsScraperAuthorizedToBroadcastManifests(CBitcoinAddress& AddressOut, CKey& KeyOut); +bool IsScraperAuthorizedToBroadcastManifests(CTxDestination& AddressOut, CKey& KeyOut); /** * @brief Returns whether the scraper with the input public key at the input time has exceeded the maximum allowable * manifest publishing rate. This is a DoS function and is used to issue misbehavior points, which could result in banning diff --git a/src/gridcoin/scraper/scraper_net.cpp b/src/gridcoin/scraper/scraper_net.cpp index ccb46dc9f2..1b7f89687e 100644 --- a/src/gridcoin/scraper/scraper_net.cpp +++ b/src/gridcoin/scraper/scraper_net.cpp @@ -13,7 +13,7 @@ #include "rpc/server.h" #include "rpc/protocol.h" #ifdef SCRAPER_NET_PK_AS_ADDRESS -#include "base58.h" +#include #endif #include "gridcoin/appcache.h" #include "gridcoin/project.h" @@ -352,11 +352,10 @@ EXCLUSIVE_LOCKS_REQUIRED(CScraperManifest::cs_mapManifest) CKeyID ManifestKeyID = PubKey.GetID(); - CBitcoinAddress ManifestAddress; - ManifestAddress.Set(ManifestKeyID); + CTxDestination ManifestAddress(ManifestKeyID); // This is the address corresponding to the manifest public key. - std::string sManifestAddress = ManifestAddress.ToString(); + std::string sManifestAddress = EncodeDestination(ManifestAddress); AppCacheSectionExt mScrapersExtended = GetExtendedScrapersCache(); @@ -857,7 +856,7 @@ UniValue CScraperManifest::ToJson() const EXCLUSIVE_LOCKS_REQUIRED(CSplitBlob::c UniValue r(UniValue::VOBJ); #ifdef SCRAPER_NET_PK_AS_ADDRESS - r.pushKV("pubkey", CBitcoinAddress(pubkey.GetID()).ToString()); + r.pushKV("pubkey", EncodeDestination(pubkey.GetID())); #else r.pushKV("pubkey", pubkey.GetID().ToString()); #endif @@ -950,7 +949,7 @@ UniValue listmanifests(const UniValue& params, bool fHelp) else { #ifdef SCRAPER_NET_PK_AS_ADDRESS - subset.pushKV("scraper (manifest) address", CBitcoinAddress(manifest.pubkey.GetID()).ToString()); + subset.pushKV("scraper (manifest) address", EncodeDestination(manifest.pubkey.GetID())); #else subset.pushKV("scraper (manifest) pubkey", manifest.pubkey.GetID().ToString()); #endif @@ -973,7 +972,7 @@ UniValue listmanifests(const UniValue& params, bool fHelp) else { #ifdef SCRAPER_NET_PK_AS_ADDRESS - subset.pushKV("scraper (manifest) address", CBitcoinAddress(manifest.pubkey.GetID()).ToString()); + subset.pushKV("scraper (manifest) address", EncodeDestination(manifest.pubkey.GetID())); #else subset.pushKV("scraper (manifest) pubkey", manifest.pubkey.GetID().ToString()); #endif diff --git a/src/gridcoin/scraper/scraper_registry.cpp b/src/gridcoin/scraper/scraper_registry.cpp index 5a22fb11ad..aedf3e89b3 100644 --- a/src/gridcoin/scraper/scraper_registry.cpp +++ b/src/gridcoin/scraper/scraper_registry.cpp @@ -52,7 +52,7 @@ ScraperEntry::ScraperEntry(CKeyID key_id, Status status, int64_t tx_timestamp, u bool ScraperEntry::WellFormed() const { - return (CBitcoinAddress(m_key).IsValid() + return (IsValidDestination(m_key) && m_status != ScraperEntryStatus::UNKNOWN && m_status != ScraperEntryStatus::OUT_OF_BOUND); } @@ -64,7 +64,7 @@ CKeyID ScraperEntry::Key() const std::pair ScraperEntry::KeyValueToString() const { - return std::make_pair(CBitcoinAddress(m_key).ToString(), StatusToString()); + return std::make_pair(EncodeDestination(m_key), StatusToString()); } CKeyID ScraperEntry::GetId() const @@ -72,9 +72,9 @@ CKeyID ScraperEntry::GetId() const return m_key; } -CBitcoinAddress ScraperEntry::GetAddress() const +CTxDestination ScraperEntry::GetAddress() const { - return CBitcoinAddress(m_key); + return CTxDestination(m_key); } std::string ScraperEntry::StatusToString() const @@ -125,7 +125,7 @@ AppCacheEntryExt ScraperEntry::GetLegacyScraperEntry() { AppCacheEntryExt entry; - entry.value = CBitcoinAddress(m_key).ToString(); + entry.value = EncodeDestination(m_key); entry.timestamp = m_timestamp; entry.deleted = (m_status == ScraperEntryStatus::DELETED); @@ -186,11 +186,9 @@ ScraperEntryPayload::ScraperEntryPayload(const std::string& key, const std::stri { m_version = 1; - CBitcoinAddress address; + CTxDestination address = DecodeDestination(m_key); - address.SetString(m_key); - - if (!address.IsValid()) { + if (!IsValidDestination(address)) { error("%s: Error during initialization of ScraperEntryPayload from legacy format: key = %s, value = %s", __func__, key, @@ -198,7 +196,7 @@ ScraperEntryPayload::ScraperEntryPayload(const std::string& key, const std::stri return; } - address.GetKeyID(m_scraper_entry.m_key); + m_scraper_entry.m_key = std::get(address); if (ToLower(m_value) == "true") { m_scraper_entry.m_status = ScraperEntryStatus::AUTHORIZED; @@ -210,16 +208,13 @@ ScraperEntryPayload::ScraperEntryPayload(const std::string& key, const std::stri ScraperEntryPayload ScraperEntryPayload::Parse(const std::string& key, const std::string& value) { - CBitcoinAddress address; - - address.SetString(key); + CTxDestination address = DecodeDestination(key); + CKeyID* key_id = std::get_if(&address); - if (!address.IsValid()) { + if (!IsValidDestination(address) || !key_id) { return ScraperEntryPayload(); } - CKeyID key_id; - address.GetKeyID(key_id); ScraperEntryStatus scraper_entry_status = ScraperEntryStatus::UNKNOWN; if (ToLower(value) == "true") { @@ -229,7 +224,7 @@ ScraperEntryPayload ScraperEntryPayload::Parse(const std::string& key, const std scraper_entry_status = ScraperEntryStatus::NOT_AUTHORIZED; } - ScraperEntryPayload payload(1, ScraperEntry(key_id, scraper_entry_status)); + ScraperEntryPayload payload(1, ScraperEntry(*key_id, scraper_entry_status)); // The above constructor doesn't carry over the legacy K-V which we need. payload.m_key = key; payload.m_value = value; @@ -270,7 +265,7 @@ const AppCacheSectionExt ScraperRegistry::GetScrapersLegacyExt(const bool& autho for (const auto& entry : m_scrapers) { - std::string key = CBitcoinAddress(entry.first).ToString(); + std::string key = EncodeDestination(entry.first); switch (entry.second->m_status.Value()) { case ScraperEntryStatus::DELETED: @@ -383,8 +378,7 @@ void ScraperRegistry::AddDelete(const ContractContext& ctx) payload.m_scraper_entry.m_previous_hash = uint256 {}; } - CBitcoinAddress address; - address.Set(payload.m_scraper_entry.m_key); + CTxDestination address(payload.m_scraper_entry.m_key); LogPrint(LogFlags::SCRAPER, "INFO: %s: scraper entry add/delete: contract m_version = %u, payload " "m_version = %u, address for m_key = %s, m_timestamp = %" PRId64 ", " @@ -392,7 +386,7 @@ void ScraperRegistry::AddDelete(const ContractContext& ctx) __func__, ctx->m_version, payload.m_version, - address.ToString(), + EncodeDestination(address), payload.m_scraper_entry.m_timestamp, payload.m_scraper_entry.m_hash.ToString(), payload.m_scraper_entry.m_previous_hash.ToString(), @@ -407,7 +401,7 @@ void ScraperRegistry::AddDelete(const ContractContext& ctx) "db record already exists. This can be expected on a restart of the wallet to ensure " "multiple contracts in the same block get stored/replayed.", __func__, - historical.GetAddress().ToString(), + EncodeDestination(historical.GetAddress()), historical.m_hash.GetHex()); } @@ -441,14 +435,14 @@ void ScraperRegistry::Revert(const ContractContext& ctx) if (entry_to_revert == m_scrapers.end()) { error("%s: The scraper entry for address %s to revert was not found in the scraper entry map.", __func__, - entry_to_revert->second->GetAddress().ToString()); + EncodeDestination(entry_to_revert->second->GetAddress())); // If there is no record in the current m_scrapers map, then there is nothing to do here. This // should not occur. return; } - CBitcoinAddress address = entry_to_revert->second->GetAddress(); + CTxDestination address = entry_to_revert->second->GetAddress(); // If this is not a null hash, then there will be a prior entry to resurrect. uint256 resurrect_hash = entry_to_revert->second->m_previous_hash; @@ -459,7 +453,7 @@ void ScraperRegistry::Revert(const ContractContext& ctx) if (m_scrapers.erase(payload->m_scraper_entry.m_key) == 0) { error("%s: The scraper entry to erase during a scraper entry revert for address %s was not found.", __func__, - address.ToString()); + EncodeDestination(address)); // If the record to revert is not found in the m_scrapers map, no point in continuing. return; } @@ -468,7 +462,7 @@ void ScraperRegistry::Revert(const ContractContext& ctx) if (!m_scraper_db.erase(ctx.m_tx.GetHash())) { error("%s: The db entry to erase during a scraper entry revert for address %s was not found.", __func__, - address.ToString()); + EncodeDestination(address)); // Unlike the above we will keep going even if this record is not found, because it is identical to the // m_scrapers record above. This should not happen, because during contract adds and removes, entries are @@ -484,7 +478,7 @@ void ScraperRegistry::Revert(const ContractContext& ctx) if (resurrect_entry == m_scraper_db.end()) { error("%s: The prior entry to resurrect during a scraper entry ADD revert for address %s was not found.", __func__, - address.ToString()); + EncodeDestination(address)); return; } diff --git a/src/gridcoin/scraper/scraper_registry.h b/src/gridcoin/scraper/scraper_registry.h index 8256b7e11b..736b49513f 100644 --- a/src/gridcoin/scraper/scraper_registry.h +++ b/src/gridcoin/scraper/scraper_registry.h @@ -6,7 +6,7 @@ #define GRIDCOIN_SCRAPER_SCRAPER_REGISTRY_H #include "amount.h" -#include "base58.h" +#include #include "dbwrapper.h" #include "serialize.h" #include "gridcoin/scraper/fwd.h" @@ -136,9 +136,9 @@ class ScraperEntry //! //! \brief Return the address from the m_key. //! - //! \return \c CBitcoinAddress derived from the m_key. + //! \return \c CTxDestination derived from the m_key. //! - CBitcoinAddress GetAddress() const; + CTxDestination GetAddress() const; //! //! \brief Returns the string representation of the current scraper entry status @@ -346,11 +346,7 @@ class ScraperEntryPayload : public LegacyPayload //! std::string LegacyKeyString() const override { - CBitcoinAddress address; - - address.Set(m_scraper_entry.m_key); - - return address.ToString(); + return EncodeDestination(m_scraper_entry.m_key); } //! diff --git a/src/gridcoin/sidestake.cpp b/src/gridcoin/sidestake.cpp index 0c553d6eef..4b7509f8b8 100644 --- a/src/gridcoin/sidestake.cpp +++ b/src/gridcoin/sidestake.cpp @@ -235,7 +235,7 @@ LocalSideStake::LocalSideStake(CTxDestination destination, bool LocalSideStake::WellFormed() const { - return CBitcoinAddress(m_destination).IsValid() && m_allocation >= 0 && m_allocation <= 1; + return IsValidDestination(m_destination) && m_allocation >= 0 && m_allocation <= 1; } std::string LocalSideStake::StatusToString() const @@ -328,7 +328,7 @@ MandatorySideStake::MandatorySideStake(CTxDestination destination, bool MandatorySideStake::WellFormed() const { - return CBitcoinAddress(m_destination).IsValid() && m_allocation >= 0 && m_allocation <= 1; + return IsValidDestination(m_destination) && m_allocation >= 0 && m_allocation <= 1; } CTxDestination MandatorySideStake::Key() const @@ -338,7 +338,7 @@ CTxDestination MandatorySideStake::Key() const std::pair MandatorySideStake::KeyValueToString() const { - return std::make_pair(CBitcoinAddress(m_destination).ToString(), StatusToString()); + return std::make_pair(EncodeDestination(m_destination), StatusToString()); } std::string MandatorySideStake::StatusToString() const @@ -718,7 +718,7 @@ void SideStakeRegistry::AddDelete(const ContractContext& ctx) __func__, ctx->m_version, payload.m_version, - CBitcoinAddress(payload.m_entry.m_destination).ToString(), + EncodeDestination(payload.m_entry.m_destination), payload.m_entry.m_allocation.ToPercent(), payload.m_entry.m_timestamp, payload.m_entry.m_hash.ToString(), @@ -734,7 +734,7 @@ void SideStakeRegistry::AddDelete(const ContractContext& ctx) "the SideStake entry db record already exists. This can be expected on a restart " "of the wallet to ensure multiple contracts in the same block get stored/replayed.", __func__, - CBitcoinAddress(historical.m_destination).ToString(), + EncodeDestination(historical.m_destination), historical.m_allocation.ToPercent(), historical.m_hash.GetHex()); } @@ -796,7 +796,7 @@ void SideStakeRegistry::Revert(const ContractContext& ctx) if (entry_to_revert == m_mandatory_sidestake_entries.end()) { error("%s: The SideStake entry for key %s to revert was not found in the SideStake entry map.", __func__, - CBitcoinAddress(entry_to_revert->second->m_destination).ToString()); + EncodeDestination(entry_to_revert->second->m_destination)); // If there is no record in the current m_sidestake_entries map, then there is nothing to do here. This // should not occur. @@ -813,7 +813,7 @@ void SideStakeRegistry::Revert(const ContractContext& ctx) if (m_mandatory_sidestake_entries.erase(payload->m_entry.m_destination) == 0) { error("%s: The SideStake entry to erase during a SideStake entry revert for key %s was not found.", __func__, - CBitcoinAddress(key).ToString()); + EncodeDestination(key)); // If the record to revert is not found in the m_sidestake_entries map, no point in continuing. return; } @@ -822,7 +822,7 @@ void SideStakeRegistry::Revert(const ContractContext& ctx) if (!m_sidestake_db.erase(ctx.m_tx.GetHash())) { error("%s: The db entry to erase during a SideStake entry revert for key %s was not found.", __func__, - CBitcoinAddress(key).ToString()); + EncodeDestination(key)); // Unlike the above we will keep going even if this record is not found, because it is identical to the // m_sidestake_entries record above. This should not happen, because during contract adds and removes, @@ -838,7 +838,7 @@ void SideStakeRegistry::Revert(const ContractContext& ctx) if (resurrect_entry == m_sidestake_db.end()) { error("%s: The prior entry to resurrect during a SideStake entry ADD revert for key %s was not found.", __func__, - CBitcoinAddress(key).ToString()); + EncodeDestination(key)); return; } @@ -1021,8 +1021,8 @@ void SideStakeRegistry::LoadLocalSideStakesFromConfig() std::string sAllocation = std::get<1>(entry); std::string sDescription = std::get<2>(entry); - CBitcoinAddress address(sAddress); - if (!address.IsValid()) + CTxDestination address = DecodeDestination(sAddress); + if (!IsValidDestination(address)) { LogPrintf("WARN: %s: ignoring sidestake invalid address %s.", __func__, sAddress); continue; @@ -1060,7 +1060,7 @@ void SideStakeRegistry::LoadLocalSideStakesFromConfig() break; } - LocalSideStake sidestake(address.Get(), + LocalSideStake sidestake(address, allocation, sDescription, LocalSideStake::LocalSideStakeStatus::ACTIVE); @@ -1117,7 +1117,7 @@ bool SideStakeRegistry::SaveLocalSideStakesToConfig() separator = ","; } - addresses += separator + CBitcoinAddress(iter.second->m_destination).ToString(); + addresses += separator + EncodeDestination(iter.second->m_destination); allocations += separator + ToString(iter.second->m_allocation.ToPercent()); descriptions += separator + iter.second->m_description; diff --git a/src/gridcoin/sidestake.h b/src/gridcoin/sidestake.h index d909e7f27a..54a324f400 100644 --- a/src/gridcoin/sidestake.h +++ b/src/gridcoin/sidestake.h @@ -5,7 +5,7 @@ #ifndef GRIDCOIN_SIDESTAKE_H #define GRIDCOIN_SIDESTAKE_H -#include "base58.h" +#include #include "gridcoin/contract/handler.h" #include "gridcoin/contract/payload.h" #include "gridcoin/contract/registry_db.h" @@ -572,7 +572,7 @@ class SideStakePayload : public IContractPayload "m_entry.StatusToString() = %s", __func__, valid, - CBitcoinAddress(m_entry.m_destination).ToString(), + EncodeDestination(m_entry.m_destination), m_entry.m_allocation.ToPercent(), m_entry.StatusToString() ); @@ -588,7 +588,7 @@ class SideStakePayload : public IContractPayload //! std::string LegacyKeyString() const override { - return CBitcoinAddress(m_entry.m_destination).ToString(); + return EncodeDestination(m_entry.m_destination); } //! diff --git a/src/gridcoin/voting/builders.cpp b/src/gridcoin/voting/builders.cpp index 529a883028..9611e1b40f 100644 --- a/src/gridcoin/voting/builders.cpp +++ b/src/gridcoin/voting/builders.cpp @@ -23,21 +23,6 @@ using namespace GRC; using LogFlags = BCLog::LogFlags; namespace { -//! -//! \brief Get the string representation of an output destination for logging. -//! -//! \param dest Destination to convert to an address string. -//! -//! \return Base58-encoded string of the address. -//! -std::string DestinationToAddressString(const CTxDestination dest) -{ - CBitcoinAddress address; - address.Set(dest); - - return address.ToString(); -} - //! //! \brief A set of outputs associated with an address for a voting claim. //! @@ -166,7 +151,7 @@ class CoinPicker void operator()(const CKeyID& keyId, const COutput& output) const { LogPrint(LogFlags::VOTE, " added output for address: %s", - DestinationToAddressString(keyId)); + EncodeDestination(keyId)); auto result_pair = m_by_address.emplace(keyId, keyId); AddressOutputs& address_outputs = result_pair.first->second; @@ -184,7 +169,7 @@ class CoinPicker { // Voting does not support redemption script outputs yet. LogPrint(LogFlags::VOTE, " skipped script address: %s", - DestinationToAddressString(scriptId)); + EncodeDestination(scriptId)); } private: @@ -219,14 +204,14 @@ class CoinPicker // if (txo.tx->vout[txo.i].nValue < COIN) { LogPrint(LogFlags::VOTE, " skipped < 1 GRC outputs for: %s", - DestinationToAddressString(dest)); + EncodeDestination(dest)); break; // The input set is sorted so the rest are too small. } if (!txo.tx->IsTrusted() || !txo.tx->IsConfirmed()) { LogPrint(LogFlags::VOTE, " skipped unconfirmed output for %s", - DestinationToAddressString(dest)); + EncodeDestination(dest)); continue; } @@ -302,7 +287,7 @@ class AddressClaimBuilder if (!m_wallet.GetPubKey(address_outputs.m_key_id, claim.m_public_key)) { error("%s: failed to fetch public key for address %s", __func__, - DestinationToAddressString(address_outputs.m_key_id)); + EncodeDestination(address_outputs.m_key_id)); return std::nullopt; } @@ -310,8 +295,8 @@ class AddressClaimBuilder LogPrint(BCLog::LogFlags::VOTE, "INFO: %s: building address claim for address_outputs.m_key_id %s, " "claim.m_public_key address %s.", __func__, - DestinationToAddressString(address_outputs.m_key_id), - DestinationToAddressString(claim.m_public_key.GetID())); + EncodeDestination(address_outputs.m_key_id), + EncodeDestination(claim.m_public_key.GetID())); // An address claim must submit outputs in ascending order. This // improves the performance of duplicate output validation: @@ -337,25 +322,25 @@ class AddressClaimBuilder if (!m_wallet.GetKey(key_id, private_key)) { return error("%s: failed to fetch private key for address %s", __func__, - DestinationToAddressString(key_id)); + EncodeDestination(key_id)); } if (!private_key.IsValid()) { return error("%s: invalid private key for address %s", __func__, - DestinationToAddressString(key_id)); + EncodeDestination(key_id)); } if (!claim.Sign(private_key, message)) { return error("%s: failed to sign address claim for address %s", __func__, - DestinationToAddressString(key_id)); + EncodeDestination(key_id)); } LogPrint(LogFlags::VOTE, "%s: signed address claim for address: %s", __func__, - DestinationToAddressString(key_id)); + EncodeDestination(key_id)); return true; } @@ -420,7 +405,7 @@ class BalanceClaimBuilder for (auto& address_claim : claim.m_address_claims) { LogPrint(BCLog::LogFlags::VOTE, "INFO: %s: signing claim address %s", __func__, - DestinationToAddressString(address_claim.m_public_key.GetID()) + EncodeDestination(address_claim.m_public_key.GetID()) ); if (!builder.SignClaim(address_claim, message)) { @@ -459,7 +444,7 @@ class BalanceClaimBuilder LogPrint(LogFlags::VOTE, "%s: trimmed output claim from %s", __func__, - DestinationToAddressString(address.m_key_id)); + EncodeDestination(address.m_key_id)); address.m_outpoints.pop_back(); bytes_estimate -= txo_bytes; @@ -467,7 +452,7 @@ class BalanceClaimBuilder if (address.m_outpoints.empty()) { LogPrint(LogFlags::VOTE, "%s: trimmed address claim %s", __func__, - DestinationToAddressString(address.m_key_id)); + EncodeDestination(address.m_key_id)); by_address.pop_back(); bytes_estimate -= address_claim_bytes; @@ -716,7 +701,7 @@ class PollClaimBuilder if (address.m_total_amount < POLL_REQUIRED_BALANCE) { LogPrint(LogFlags::VOTE, "%s: exceeded max outputs for %s", __func__, - DestinationToAddressString(address.m_key_id)); + EncodeDestination(address.m_key_id)); return false; } @@ -1225,7 +1210,7 @@ CWalletTx PollBuilder::BuildContractTx(CWallet* const pwallet, const uint32_t& c LogPrint(BCLog::LogFlags::VOTE, "INFO: %s: tx contract payload claim address %s, poll title %s.", __func__, - DestinationToAddressString(poll_payload.m_claim.m_address_claim.m_public_key.GetID()), + EncodeDestination(poll_payload.m_claim.m_address_claim.m_public_key.GetID()), poll_payload.m_poll.m_title ); diff --git a/src/key.h b/src/key.h index d87ddeb2f5..069f85b45b 100644 --- a/src/key.h +++ b/src/key.h @@ -25,9 +25,6 @@ class key_error : public std::runtime_error // secure_allocator is defined in allocators.h // CPrivKey is a serialized private key, with all parameters included (279 bytes) typedef std::vector > CPrivKey; -// CSecret is a serialization of just the secret parameter (32 bytes) -typedef std::vector > CSecret; - /** An encapsulated private key. */ class CKey diff --git a/src/key_io.cpp b/src/key_io.cpp index 414996e37e..40cae5daf9 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -12,6 +12,114 @@ #include #include +namespace { +class DestinationEncoder +{ +private: + const CChainParams& m_params; + +public: + explicit DestinationEncoder(const CChainParams& params) : m_params(params) {} + + std::string operator()(const CKeyID& id) const + { + std::vector data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); + data.insert(data.end(), id.begin(), id.end()); + return EncodeBase58Check(data); + } + + std::string operator()(const CScriptID& id) const + { + std::vector data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); + data.insert(data.end(), id.begin(), id.end()); + return EncodeBase58Check(data); + } + + std::string operator()(const CNoDestination& no) const { return {}; } +}; + +CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, std::string& error_str, std::vector* error_locations) +{ + std::vector data; + uint160 hash; + error_str = ""; + + if (DecodeBase58Check(str, data, 21)) { + // base58-encoded Gridcoin addresses. + // Public-key-hash-addresses have version 62 (or 111 testnet). + // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key. + const std::vector& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); + if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) { + std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin()); + return CKeyID(hash); + } + // Script-hash-addresses have version 85 (or 196 testnet). + // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script. + const std::vector& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); + if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) { + std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin()); + return CScriptID(hash); + } + + // If the prefix of data matches either the script or pubkey prefix, the length must have been wrong + if ((data.size() >= script_prefix.size() && + std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) || + (data.size() >= pubkey_prefix.size() && + std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin()))) { + error_str = "Invalid length for Base58 address (P2PKH or P2SH)"; + } else { + error_str = "Invalid or unsupported Base58-encoded address."; + } + return CNoDestination(); + } else { + // Try Base58 decoding without the checksum, using a much larger max length + if (!DecodeBase58(str, data, 100)) { + error_str = "Invalid Base58 encoding."; + } else { + error_str = "Invalid checksum or length of Base58 address (P2PKH or P2SH)"; + } + return CNoDestination(); + } + + + // Set error message if address can't be interpreted as Base58. + if (error_str.empty()) error_str = "Invalid address format"; + + return CNoDestination(); +} +} // namespace + +CKey DecodeSecret(const std::string& str) +{ + CKey key; + std::vector data; + if (DecodeBase58Check(str, data, 34)) { + const std::vector& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY); + if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) && + std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) { + bool compressed = data.size() == 33 + privkey_prefix.size(); + key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed); + } + } + if (!data.empty()) { + memory_cleanse(data.data(), data.size()); + } + return key; +} + +std::string EncodeSecret(const CKey& key) +{ + assert(key.IsValid()); + std::vector data = Params().Base58Prefix(CChainParams::SECRET_KEY); + data.insert(data.end(), key.begin(), key.end()); + if (key.IsCompressed()) { + data.push_back(1); + } + std::string ret = EncodeBase58Check(data); + memory_cleanse(data.data(), data.size()); + return ret; +} + CExtPubKey DecodeExtPubKey(const std::string& str) { CExtPubKey key; @@ -58,3 +166,30 @@ std::string EncodeExtKey(const CExtKey& key) memory_cleanse(data.data(), data.size()); return ret; } + +std::string EncodeDestination(const CTxDestination& dest) +{ + return std::visit(DestinationEncoder(Params()), dest); +} + +CTxDestination DecodeDestination(const std::string& str, std::string& error_msg, std::vector* error_locations) +{ + return DecodeDestination(str, Params(), error_msg, error_locations); +} + +CTxDestination DecodeDestination(const std::string& str) +{ + std::string error_msg; + return DecodeDestination(str, error_msg); +} + +bool IsValidDestinationString(const std::string& str, const CChainParams& params) +{ + std::string error_msg; + return IsValidDestination(DecodeDestination(str, params, error_msg, nullptr)); +} + +bool IsValidDestinationString(const std::string& str) +{ + return IsValidDestinationString(str, Params()); +} diff --git a/src/key_io.h b/src/key_io.h index 248366894e..39e7d2d7b2 100644 --- a/src/key_io.h +++ b/src/key_io.h @@ -9,12 +9,22 @@ #include #include #include +#include #include +CKey DecodeSecret(const std::string& str); +std::string EncodeSecret(const CKey& key); + CExtKey DecodeExtKey(const std::string& str); std::string EncodeExtKey(const CExtKey& extkey); CExtPubKey DecodeExtPubKey(const std::string& str); std::string EncodeExtPubKey(const CExtPubKey& extpubkey); +std::string EncodeDestination(const CTxDestination& dest); +CTxDestination DecodeDestination(const std::string& str); +CTxDestination DecodeDestination(const std::string& str, std::string& error_msg, std::vector* error_locations = nullptr); +bool IsValidDestinationString(const std::string& str); +bool IsValidDestinationString(const std::string& str, const CChainParams& params); + #endif // BITCOIN_KEY_IO_H diff --git a/src/keystore.cpp b/src/keystore.cpp index 5fb35a8202..f1bc00d90d 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -15,13 +15,14 @@ bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const return true; } -bool CBasicKeyStore::AddKey(const CKey& key) +bool CKeyStore::AddKey(const CKey &key) { + return AddKeyPubKey(key, key.GetPubKey()); +} + +bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey) { - CSecret secret(key.begin(), key.end()); - { - LOCK(cs_KeyStore); - mapKeys[key.GetPubKey().GetID()] = make_pair(secret, key.IsCompressed()); - } + LOCK(cs_KeyStore); + mapKeys[pubkey.GetID()] = key; return true; } @@ -133,23 +134,22 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) return true; } -bool CCryptoKeyStore::AddKey(const CKey& key) +bool CCryptoKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey) { { LOCK(cs_KeyStore); if (!IsCrypted()) - return CBasicKeyStore::AddKey(key); + return CBasicKeyStore::AddKeyPubKey(key, pubkey); if (IsLocked()) return false; std::vector vchCryptedSecret; - CPubKey vchPubKey = key.GetPubKey(); - CSecret secret(key.begin(), key.end()); - if (!EncryptSecret(vMasterKey, secret, vchPubKey.GetHash(), vchCryptedSecret)) + CKeyingMaterial vchSecret(key.begin(), key.end()); + if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), vchCryptedSecret)) return false; - if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) + if (!AddCryptedKey(pubkey, vchCryptedSecret)) return false; } return true; @@ -180,7 +180,7 @@ bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const { const CPubKey& vchPubKey = mi->second.first; const std::vector& vchCryptedSecret = mi->second.second; - CSecret vchSecret; + CKeyingMaterial vchSecret; if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) return false; if (vchSecret.size() != 32) @@ -219,13 +219,11 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) fUseCrypto = true; for(KeyMap::value_type& mKey : mapKeys) { - CKey key; - key.Set(mKey.second.first.begin(), mKey.second.first.end(), mKey.second.second); - if (!key.IsValid()) - return false; - const CPubKey vchPubKey = key.GetPubKey(); + const CKey &key = mKey.second; + CPubKey vchPubKey = key.GetPubKey(); + CKeyingMaterial vchSecret(key.begin(), key.end()); std::vector vchCryptedSecret; - if (!EncryptSecret(vMasterKeyIn, mKey.second.first, vchPubKey.GetHash(), vchCryptedSecret)) + if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret)) return false; if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) return false; diff --git a/src/keystore.h b/src/keystore.h index cb6ab524a3..c6eea7343d 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -22,7 +22,8 @@ class CKeyStore virtual ~CKeyStore() {} // Add a key to the store. - virtual bool AddKey(const CKey& key) =0; + virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) =0; + virtual bool AddKey(const CKey &key); // Check whether a key corresponding to a given address is present in the store. virtual bool HaveKey(const CKeyID &address) const =0; @@ -34,19 +35,9 @@ class CKeyStore virtual bool AddCScript(const CScript& redeemScript) =0; virtual bool HaveCScript(const CScriptID &hash) const =0; virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0; - - virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const - { - CKey key; - if (!GetKey(address, key)) - return false; - fCompressed = key.IsCompressed(); - vchSecret.assign(key.begin(), key.end()); - return true; - } }; -typedef std::map > KeyMap; +typedef std::map KeyMap; typedef std::map ScriptMap; /** Basic key store, that keeps keys in an address->secret map */ @@ -57,7 +48,7 @@ class CBasicKeyStore : public CKeyStore ScriptMap mapScripts; public: - bool AddKey(const CKey& key); + bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); bool HaveKey(const CKeyID &address) const { bool result; @@ -87,7 +78,7 @@ class CBasicKeyStore : public CKeyStore KeyMap::const_iterator mi = mapKeys.find(address); if (mi != mapKeys.end()) { - keyOut.Set(mi->second.first.begin(), mi->second.first.end(), mi->second.second); + keyOut = mi->second; return true; } } @@ -151,7 +142,7 @@ class CCryptoKeyStore : public CBasicKeyStore bool Lock(); virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret); - bool AddKey(const CKey& key); + bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); bool HaveKey(const CKeyID &address) const { { diff --git a/src/main.h b/src/main.h index 3afe3e45a5..e297464d9f 100644 --- a/src/main.h +++ b/src/main.h @@ -33,7 +33,6 @@ class CKeyItem; class CReserveKey; class COutPoint; class CAddress; -class CBitcoinAddress; class CInv; class CNode; class CTxMemPool; diff --git a/src/miner.cpp b/src/miner.cpp index 1d1e8a3f7f..58ce9e7ac9 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -192,9 +192,9 @@ bool CreateMRCRewards(CBlock &blocknew, std::mapnTime); if (beacon && mrc_outputs.size() <= output_limit) { - CBitcoinAddress beacon_address = beacon->GetAddress(); + CTxDestination beacon_address = beacon->GetAddress(); CScript script_beacon_key; - script_beacon_key.SetDestination(beacon_address.Get()); + script_beacon_key.SetDestination(beacon_address); // The net reward paid to the MRC beacon address is the requested research subsidy (reward) // minus the fees for the MRC. @@ -254,7 +254,7 @@ bool CreateMRCRewards(CBlock &blocknew, std::mapget()->GetDestination()); + CTxDestination address = iterSideStake->get()->GetDestination(); GRC::Allocation allocation = iterSideStake->get()->GetAllocation(); - if (!address.IsValid()) + if (!IsValidDestination(address)) { LogPrintf("WARN: SplitCoinStakeOutput: ignoring sidestake invalid address %s.", - address.ToString()); + EncodeDestination(address)); continue; } @@ -972,7 +972,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake { LogPrintf("WARN: SplitCoinStakeOutput: distribution %f too small to address %s.", CoinToDouble((allocation * nReward).ToCAmount()), - address.ToString() + EncodeDestination(address) ); continue; } @@ -987,7 +987,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake // Push to an output the (reward times the allocation) to the address, increment the accumulator for allocation, // decrement the remaining stake output value, and increment outputs used. - SideStakeScriptPubKey.SetDestination(address.Get()); + SideStakeScriptPubKey.SetDestination(address); // It is entirely possible that the coinstake could be from an address that is specified in one of the sidestake // entries if the sidestake address(es) are local to the staking wallet. There is no reason to sidestake in that @@ -1014,7 +1014,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake LogPrintf("SplitCoinStakeOutput: create sidestake UTXO %i value %f to address %s", nOutputsUsed, CoinToDouble((allocation * nReward).ToCAmount()), - address.ToString() + EncodeDestination(address) ); SumAllocation += allocation; nRemainingStakeOutputValue -= nSideStake; @@ -1489,7 +1489,7 @@ void StakeMiner(CWallet *pwallet) __func__, i, FormatMoney(StakeBlock.vtx[1].vout[i].nValue), - CBitcoinAddress(destination).ToString()); + EncodeDestination(destination)); } } diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 7bb0d5d1b1..07026c9a73 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -3,7 +3,7 @@ #include "walletmodel.h" #include "wallet/wallet.h" -#include "base58.h" +#include #include "util.h" #include @@ -62,12 +62,12 @@ class AddressTablePriv LOCK(wallet->cs_wallet); for (auto const &item : wallet->mapAddressBook) { - const CBitcoinAddress& address = item.first; + const CTxDestination& address = item.first; const std::string& strName = item.second; - isminetype fMine = IsMine(*wallet, address.Get()); + isminetype fMine = IsMine(*wallet, address); cachedAddressTable.append(AddressTableEntry((fMine != ISMINE_NO) ? AddressTableEntry::Receiving : AddressTableEntry::Sending, QString::fromStdString(strName), - QString::fromStdString(address.ToString()))); + QString::fromStdString(EncodeDestination(address)))); } } // std::lower_bound() and std::upper_bound() require our cachedAddressTable list to be sorted in asc order @@ -222,7 +222,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, auto address_count = [this](const QVariant &value) { LOCK(wallet->cs_wallet); - return wallet->mapAddressBook.count(CBitcoinAddress(value.toString().toStdString()).Get()); + return wallet->mapAddressBook.count(DecodeDestination(value.toString().toStdString())); }; if (role == Qt::EditRole) @@ -236,11 +236,11 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, editStatus = NO_CHANGES; return false; } - wallet->SetAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get(), value.toString().toStdString()); + wallet->SetAddressBookName(DecodeDestination(rec->address.toStdString()), value.toString().toStdString()); break; case Address: // Do nothing, if old address == new address - if(CBitcoinAddress(rec->address.toStdString()) == CBitcoinAddress(value.toString().toStdString())) + if(DecodeDestination(rec->address.toStdString()) == DecodeDestination(value.toString().toStdString())) { editStatus = NO_CHANGES; return false; @@ -264,9 +264,9 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, { LOCK(wallet->cs_wallet); // Remove old entry - wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get()); + wallet->DelAddressBookName(DecodeDestination(rec->address.toStdString())); // Add new entry with new address - wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()).Get(), rec->label.toStdString()); + wallet->SetAddressBookName(DecodeDestination(value.toString().toStdString()), rec->label.toStdString()); } } break; @@ -342,7 +342,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con // Check for duplicate addresses { LOCK(wallet->cs_wallet); - if(wallet->mapAddressBook.count(CBitcoinAddress(strAddress).Get())) + if(wallet->mapAddressBook.count(DecodeDestination(strAddress))) { editStatus = DUPLICATE_ADDRESS; return QString(); @@ -365,7 +365,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con editStatus = KEY_GENERATION_FAILURE; return QString(); } - strAddress = CBitcoinAddress(newKey.GetID()).ToString(); + strAddress = EncodeDestination(newKey.GetID()); } else { @@ -375,7 +375,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con // Add entry { LOCK(wallet->cs_wallet); - wallet->SetAddressBookName(CBitcoinAddress(strAddress).Get(), strLabel); + wallet->SetAddressBookName(DecodeDestination(strAddress), strLabel); } return QString::fromStdString(strAddress); } @@ -392,7 +392,7 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex &parent } { LOCK(wallet->cs_wallet); - wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get()); + wallet->DelAddressBookName(DecodeDestination(rec->address.toStdString())); } return true; } @@ -403,8 +403,8 @@ QString AddressTableModel::labelForAddress(const QString &address) const { { LOCK(wallet->cs_wallet); - CBitcoinAddress address_parsed(address.toStdString()); - std::map::iterator mi = wallet->mapAddressBook.find(address_parsed.Get()); + CTxDestination address_parsed = DecodeDestination(address.toStdString()); + std::map::iterator mi = wallet->mapAddressBook.find(address_parsed); if (mi != wallet->mapAddressBook.end()) { return QString::fromStdString(mi->second); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 17eaf4541a..38b14cce23 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -821,7 +821,7 @@ void CoinControlDialog::updateView() QString sAddress = ""; if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, outputAddress)) { - sAddress = CBitcoinAddress(outputAddress).ToString().c_str(); + sAddress = EncodeDestination(outputAddress).c_str(); // if listMode or change => show bitcoin address. In tree mode, address is not shown again for direct wallet address outputs if (!treeMode || (!(sAddress == sWalletAddress))) diff --git a/src/qt/consolidateunspentwizardselectinputspage.cpp b/src/qt/consolidateunspentwizardselectinputspage.cpp index bef140db0e..8e1702e074 100644 --- a/src/qt/consolidateunspentwizardselectinputspage.cpp +++ b/src/qt/consolidateunspentwizardselectinputspage.cpp @@ -582,7 +582,7 @@ void ConsolidateUnspentWizardSelectInputsPage::updateView() QString sAddress = ""; if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, outputAddress)) { - sAddress = CBitcoinAddress(outputAddress).ToString().c_str(); + sAddress = EncodeDestination(outputAddress).c_str(); // if listMode or change => show bitcoin address. In tree mode, address is not shown again for direct wallet address outputs if (!treeMode || (!(sAddress == sWalletAddress))) diff --git a/src/qt/researcher/researchermodel.cpp b/src/qt/researcher/researchermodel.cpp index 18a4f7bef4..1fe8ae8bc4 100644 --- a/src/qt/researcher/researchermodel.cpp +++ b/src/qt/researcher/researchermodel.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or https://opensource.org/licenses/mit-license.php. -#include "base58.h" +#include #include "main.h" #include "gridcoin/beacon.h" #include "gridcoin/boinc.h" @@ -462,7 +462,7 @@ QString ResearcherModel::formatBeaconAddress() const return QString(); } - return QString::fromStdString(m_beacon->GetAddress().ToString()); + return QString::fromStdString(EncodeDestination(m_beacon->GetAddress())); } QString ResearcherModel::formatBeaconVerificationCode() const diff --git a/src/qt/researcher/researcherwizardpoolpage.cpp b/src/qt/researcher/researcherwizardpoolpage.cpp index 2185be6df2..07be71486e 100644 --- a/src/qt/researcher/researcherwizardpoolpage.cpp +++ b/src/qt/researcher/researcherwizardpoolpage.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or https://opensource.org/licenses/mit-license.php. -#include "base58.h" +#include #include "key.h" #include "qt/decoration.h" #include "qt/forms/ui_researcherwizardpoolpage.h" @@ -105,7 +105,7 @@ void ResearcherWizardPoolPage::getNewAddress() } ui->addressLabel->setText( - QString::fromStdString(CBitcoinAddress(public_key.GetID()).ToString())); + QString::fromStdString(EncodeDestination(public_key.GetID()))); ui->copyToClipboardButton->setVisible(true); } diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index d813d868d4..126fbf7d11 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -349,8 +349,8 @@ bool SendCoinsDialog::handleURI(const QString &uri) // URI has to be valid if (GUIUtil::parseBitcoinURI(uri, &rv)) { - CBitcoinAddress address(rv.address.toStdString()); - if (!address.IsValid()) + CTxDestination address = DecodeDestination(rv.address.toStdString()); + if (!IsValidDestination(address)) return false; pasteEntry(rv); return true; @@ -509,7 +509,7 @@ void SendCoinsDialog::coinControlChangeChecked(int state) if (model) { if (state == Qt::Checked) - coinControl->destChange = CBitcoinAddress(ui->coinControlChangeEdit->text().toStdString()).Get(); + coinControl->destChange = DecodeDestination(ui->coinControlChangeEdit->text().toStdString()); else coinControl->destChange = CNoDestination(); } @@ -525,13 +525,13 @@ void SendCoinsDialog::coinControlChangeEdited(const QString & text) { if (model) { - coinControl->destChange = CBitcoinAddress(text.toStdString()).Get(); + coinControl->destChange = DecodeDestination(text.toStdString()); // label for the change address ui->coinControlChangeAddressLabel->setStyleSheet(QString()); if (text.isEmpty()) ui->coinControlChangeAddressLabel->setText(QString()); - else if (!CBitcoinAddress(text.toStdString()).IsValid()) + else if (!IsValidDestination(DecodeDestination(text.toStdString()))) { ui->coinControlChangeAddressLabel->setStyleSheet("QLabel{color:red;}"); ui->coinControlChangeAddressLabel->setText(tr("WARNING: Invalid Gridcoin address")); @@ -544,9 +544,9 @@ void SendCoinsDialog::coinControlChangeEdited(const QString & text) else { CPubKey pubkey; - CKeyID keyid; - CBitcoinAddress(text.toStdString()).GetKeyID(keyid); - if (model->getPubKey(keyid, pubkey)) + CTxDestination dest = DecodeDestination(text.toStdString()); + CKeyID* keyid = std::get_if(&dest); + if (keyid && model->getPubKey(*keyid, pubkey)) ui->coinControlChangeAddressLabel->setText(tr("(no label)")); else { diff --git a/src/qt/sidestaketablemodel.cpp b/src/qt/sidestaketablemodel.cpp index 018cb0977e..9b6411b2ed 100644 --- a/src/qt/sidestaketablemodel.cpp +++ b/src/qt/sidestaketablemodel.cpp @@ -154,7 +154,7 @@ QVariant SideStakeTableModel::data(const QModelIndex &index, int role) const if (role == Qt::DisplayRole) { switch (column) { case Address: - return QString::fromStdString(CBitcoinAddress(rec->GetDestination()).ToString()); + return QString::fromStdString(EncodeDestination(rec->GetDestination())); case Allocation: return QString().setNum(rec->GetAllocation().ToPercent(), 'f', 2) + QString("\%"); case Description: @@ -166,7 +166,7 @@ QVariant SideStakeTableModel::data(const QModelIndex &index, int role) const } else if (role == Qt::EditRole) { switch (column) { case Address: - return QString::fromStdString(CBitcoinAddress(rec->GetDestination()).ToString()); + return QString::fromStdString(EncodeDestination(rec->GetDestination())); case Allocation: return QString().setNum(rec->GetAllocation().ToPercent(), 'f', 2); case Description: @@ -342,19 +342,18 @@ QString SideStakeTableModel::addRow(const QString &address, const QString &alloc { GRC::SideStakeRegistry& registry = GRC::GetSideStakeRegistry(); - CBitcoinAddress sidestake_address; - sidestake_address.SetString(address.toStdString()); + CTxDestination sidestake_address = DecodeDestination(address.toStdString()); m_edit_status = OK; - if (!sidestake_address.IsValid()) { + if (!IsValidDestination(sidestake_address)) { m_edit_status = INVALID_ADDRESS; return QString(); } // Check for duplicate local sidestakes. Here we use the actual core sidestake registry rather than the // UI model. - std::vector core_local_sidestake = registry.Try(sidestake_address.Get(), GRC::SideStake::FilterFlag::LOCAL); + std::vector core_local_sidestake = registry.Try(sidestake_address, GRC::SideStake::FilterFlag::LOCAL); if (!core_local_sidestake.empty()) { m_edit_status = DUPLICATE_ADDRESS; @@ -393,14 +392,14 @@ QString SideStakeTableModel::addRow(const QString &address, const QString &alloc return QString(); } - registry.NonContractAdd(GRC::LocalSideStake(sidestake_address.Get(), + registry.NonContractAdd(GRC::LocalSideStake(sidestake_address, sidestake_allocation, sanitized_description, GRC::LocalSideStake::LocalSideStakeStatus::ACTIVE)); updateSideStakeTableModel(); - return QString::fromStdString(sidestake_address.ToString()); + return QString::fromStdString(EncodeDestination(sidestake_address)); } bool SideStakeTableModel::removeRows(int row, int count, const QModelIndex &parent) diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 1589c8dc38..fa09672981 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -2,7 +2,7 @@ #include "ui_signverifymessagedialog.h" #include "addressbookpage.h" -#include "base58.h" +#include #include "guiutil.h" #include "init.h" #include "main.h" @@ -102,16 +102,16 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() /* Clear old signature to ensure users don't get confused on error with an old signature displayed */ ui->signatureOutEdit_SM->clear(); - CBitcoinAddress addr(ui->addressInEdit_SM->text().toStdString()); - if (!addr.IsValid()) + CTxDestination addr = DecodeDestination(ui->addressInEdit_SM->text().toStdString()); + if (!IsValidDestination(addr)) { ui->addressInEdit_SM->setValid(false); ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); return; } - CKeyID keyID; - if (!addr.GetKeyID(keyID)) + CKeyID* keyID = std::get_if(&addr); + if (!keyID) { ui->addressInEdit_SM->setValid(false); ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); @@ -128,7 +128,7 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() } CKey key; - if (!pwalletMain->GetKey(keyID, key)) + if (!pwalletMain->GetKey(*keyID, key)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("Private key for the entered address is not available.")); @@ -185,16 +185,16 @@ void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() { - CBitcoinAddress addr(ui->addressInEdit_VM->text().toStdString()); - if (!addr.IsValid()) + CTxDestination addr = DecodeDestination(ui->addressInEdit_VM->text().toStdString()); + if (!IsValidDestination(addr)) { ui->addressInEdit_VM->setValid(false); ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); return; } - CKeyID keyID; - if (!addr.GetKeyID(keyID)) + CKeyID* keyID = std::get_if(&addr); + if (!keyID) { ui->addressInEdit_VM->setValid(false); ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); @@ -226,7 +226,7 @@ void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() return; } - if (!(CBitcoinAddress(pubkey.GetID()) == addr)) + if (!(CTxDestination(pubkey.GetID()) == addr)) { ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_VM->setText(QString("") + tr("Message verification failed.") + QString("")); diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index cca2f3ba28..e04bb67af0 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -7,7 +7,7 @@ #include "wallet/wallet.h" #include "txdb.h" #include "node/ui_interface.h" -#include "base58.h" +#include #include "bitcoingui.h" #include "util.h" @@ -71,7 +71,7 @@ std::string PubKeyToGRCAddress(const CScript& scriptPubKey) std::string grcaddress = ""; for (auto const& addr : addresses) - grcaddress = CBitcoinAddress(addr).ToString(); + grcaddress = EncodeDestination(addr); return grcaddress; } @@ -177,7 +177,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, unsigned int vo { strHTML += "" + tr("From") + ": " + tr("unknown") + "
"; strHTML += "" + tr("To") + ": "; - strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); + strHTML += GUIUtil::HtmlEscape(EncodeDestination(address)); if (!wallet->mapAddressBook[address].empty()) strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")"; @@ -203,7 +203,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, unsigned int vo strHTML += "" + tr("To") + ": "; - CTxDestination dest = CBitcoinAddress(strAddress).Get(); + CTxDestination dest = DecodeDestination(strAddress); if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].empty()) strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest]) + " "; @@ -269,7 +269,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, unsigned int vo if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty()) strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " "; - strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); + strHTML += GUIUtil::HtmlEscape(EncodeDestination(address)); strHTML += "
"; } } @@ -395,7 +395,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, unsigned int vo CTxDestination address; if (ExtractDestination(vout.scriptPubKey, address)) - strHTML += QString::fromStdString(CBitcoinAddress(address).ToString()); + strHTML += QString::fromStdString(EncodeDestination(address)); strHTML += " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, vout.nValue); strHTML += " IsMine=" + ((wallet->IsMine(vout) != ISMINE_NO) ? tr("true") : tr("false")) + ""; diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 1fc5af5a19..b841940cb5 100755 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -1,6 +1,6 @@ #include "transactionrecord.h" #include "wallet/wallet.h" -#include "base58.h" +#include #include /* Return positive answer if transaction should be shown in list. */ @@ -88,7 +88,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * if (ExtractDestination(txout.scriptPubKey, address)) { - sub.address = CBitcoinAddress(address).ToString(); + sub.address = EncodeDestination(address); } // Generated (proof-of-work) @@ -121,7 +121,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * // The coinstake HAS to be from an address. if(ExtractDestination(wtx.vout[1].scriptPubKey, address)) { - sub.address = CBitcoinAddress(address).ToString(); + sub.address = EncodeDestination(address); } // Here we add up all of the outputs, whether they are ours (the stake return with @@ -173,7 +173,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * if (ExtractDestination(wtx.vout[t].scriptPubKey, address)) { - sub.address = CBitcoinAddress(address).ToString(); + sub.address = EncodeDestination(address); } int64_t nValue = wtx.vout[t].nValue; @@ -205,7 +205,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * { // Received by Bitcoin Address sub.type = TransactionRecord::RecvWithAddress; - sub.address = CBitcoinAddress(address).ToString(); + sub.address = EncodeDestination(address); } else { @@ -281,7 +281,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * { // Sent to Bitcoin Address sub.type = TransactionRecord::SendToAddress; - sub.address = CBitcoinAddress(address).ToString(); + sub.address = EncodeDestination(address); } else { diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index f8c8e167a9..8c0c688b66 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -6,7 +6,7 @@ #include "node/ui_interface.h" #include "wallet/wallet.h" -#include "base58.h" +#include #include "util.h" #include "gridcoin/tx_message.h" @@ -174,8 +174,8 @@ void WalletModel::updateAddressBook(const QString &address, const QString &label bool WalletModel::validateAddress(const QString &address) { - CBitcoinAddress addressParsed(address.toStdString()); - return addressParsed.IsValid(); + CTxDestination addressParsed = DecodeDestination(address.toStdString()); + return IsValidDestination(addressParsed); } WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList &recipients, const CCoinControl *coinControl) @@ -242,7 +242,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList > vecSend; for (const SendCoinsRecipient& rcp : recipients) { CScript scriptPubKey; - scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); + scriptPubKey.SetDestination(DecodeDestination(rcp.address.toStdString())); vecSend.push_back(std::make_pair(scriptPubKey, rcp.amount)); } @@ -273,7 +273,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QListcs_wallet); @@ -361,9 +361,9 @@ static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStor static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status) { - LogPrintf("NotifyAddressBookChanged %s %s isMine=%i status=%i", CBitcoinAddress(address).ToString(), label, isMine, status); + LogPrintf("NotifyAddressBookChanged %s %s isMine=%i status=%i", EncodeDestination(address), label, isMine, status); QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection, - Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())), + Q_ARG(QString, QString::fromStdString(EncodeDestination(address))), Q_ARG(QString, QString::fromStdString(label)), Q_ARG(bool, isMine), Q_ARG(int, status)); @@ -501,7 +501,7 @@ void WalletModel::listCoins(std::map >& mapCoins) CTxDestination address; if(!ExtractDestination(cout.tx->vout[cout.i].scriptPubKey, address)) continue; - mapCoins[CBitcoinAddress(address).ToString().c_str()].push_back(out); + mapCoins[EncodeDestination(address).c_str()].push_back(out); } } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 32ee83380c..69d73a2a39 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1081,31 +1081,6 @@ UniValue getblocksbatch(const UniValue& params, bool fHelp) return result; } -UniValue backupprivatekeys(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "backupprivatekeys\n" - "\n" - "Backup wallet private keys to file (Wallet must be fully unlocked!)\n"); - - string sErrors; - string sTarget; - UniValue res(UniValue::VOBJ); - - bool bBackupPrivateKeys = GRC::BackupPrivateKeys(*pwalletMain, sTarget, sErrors); - - if (!bBackupPrivateKeys) - res.pushKV("error", sErrors); - - else - res.pushKV("location", sTarget); - - res.pushKV("result", bBackupPrivateKeys); - - return res; -} - UniValue rainbymagnitude(const UniValue& params, bool fHelp) { if (fHelp || (params.size() < 2 || params.size() > 4)) @@ -1181,7 +1156,7 @@ UniValue rainbymagnitude(const UniValue& params, bool fHelp) const int64_t now = GetAdjustedTime(); // Time to calculate beacon expiration from //------- CPID -------------- beacon address -- Mag --- payment - suppressed - std::map> mCPIDRain; + std::map> mCPIDRain; for (const auto& entry : mScraperConvergedStats) { @@ -1209,7 +1184,7 @@ UniValue rainbymagnitude(const UniValue& params, bool fHelp) // Zero mag CPIDs do not get paid. if (!dCPIDMag) continue; - CBitcoinAddress address; + CTxDestination address; // If the beacon is active get the address and insert an entry into the map for payment, // otherwise skip. @@ -1266,7 +1241,7 @@ UniValue rainbymagnitude(const UniValue& params, bool fHelp) { // Make it easier to read. const GRC::Cpid& cpid = iter.first; - const CBitcoinAddress& address = std::get<0>(iter.second); + const CTxDestination& address = std::get<0>(iter.second); const double& magnitude = std::get<1>(iter.second); // This is not a const reference on purpose because it has to be renormalized. @@ -1279,18 +1254,18 @@ UniValue rainbymagnitude(const UniValue& params, bool fHelp) payment = roundint64((double) payment * (double) amount / (double) total_amount_1st_pass); CScript scriptPubKey; - scriptPubKey.SetDestination(address.Get()); + scriptPubKey.SetDestination(address); LogPrint(BCLog::LogFlags::VERBOSE, "INFO: %s: cpid = %s. address = %s, magnitude = %.2f, " "payment = %s, dust_suppressed = %u", - __func__, cpid.ToString(), address.ToString(), magnitude, ValueFromAmount(payment).getValStr(), suppressed); + __func__, cpid.ToString(), EncodeDestination(address), magnitude, ValueFromAmount(payment).getValStr(), suppressed); if (output_details) { UniValue detail_entry(UniValue::VOBJ); detail_entry.pushKV("cpid", cpid.ToString()); - detail_entry.pushKV("address", address.ToString()); + detail_entry.pushKV("address", EncodeDestination(address)); detail_entry.pushKV("magnitude", magnitude); detail_entry.pushKV("amount", ValueFromAmount(payment)); detail_entry.pushKV("suppressed", suppressed); @@ -1562,7 +1537,7 @@ UniValue beaconreport(const UniValue& params, bool fHelp) if (active_only && beacon_pair.second->Expired(now)) continue; entry.pushKV("cpid", beacon_pair.first.ToString()); - entry.pushKV("address", beacon_pair.second->GetAddress().ToString()); + entry.pushKV("address", EncodeDestination(beacon_pair.second->GetAddress())); entry.pushKV("timestamp", beacon_pair.second->m_timestamp); entry.pushKV("hash", beacon_pair.second->m_hash.GetHex()); entry.pushKV("prev_beacon_hash", beacon_pair.second->m_previous_hash.GetHex()); @@ -1681,14 +1656,12 @@ UniValue pendingbeaconreport(const UniValue& params, bool fHelp) { UniValue entry(UniValue::VOBJ); - CBitcoinAddress address; const CKeyID& key_id = pending_beacon_pair.first; - - address.Set(key_id); + CTxDestination address(key_id); entry.pushKV("cpid", pending_beacon_pair.second->m_cpid.ToString()); entry.pushKV("key_id", pending_beacon_pair.first.ToString()); - entry.pushKV("address", address.ToString()); + entry.pushKV("address", EncodeDestination(address)); entry.pushKV("timestamp", pending_beacon_pair.second->m_timestamp); results.push_back(entry); @@ -1740,7 +1713,7 @@ UniValue beaconstatus(const UniValue& params, bool fHelp) entry.pushKV("expired", beacon->Expired(now)); entry.pushKV("renewable", beacon->Renewable(now)); entry.pushKV("timestamp", TimestampToHRDate(beacon->m_timestamp)); - entry.pushKV("address", beacon->GetAddress().ToString()); + entry.pushKV("address", EncodeDestination(beacon->GetAddress())); entry.pushKV("public_key", HexStr(beacon->m_public_key)); entry.pushKV("private_key_available", beacon->WalletHasPrivateKey(pwalletMain)); entry.pushKV("magnitude", GRC::Quorum::GetMagnitude(*cpid).Floating()); @@ -1758,7 +1731,7 @@ UniValue beaconstatus(const UniValue& params, bool fHelp) entry.pushKV("expired", beacon_ptr->Expired(now)); entry.pushKV("renewable", false); entry.pushKV("timestamp", TimestampToHRDate(beacon_ptr->m_timestamp)); - entry.pushKV("address", beacon_ptr->GetAddress().ToString()); + entry.pushKV("address", EncodeDestination(beacon_ptr->GetAddress())); entry.pushKV("public_key", HexStr(beacon_ptr->m_public_key)); entry.pushKV("private_key_available", beacon_ptr->WalletHasPrivateKey(pwalletMain)); entry.pushKV("magnitude", 0); @@ -2412,15 +2385,13 @@ UniValue addkey(const UniValue& params, bool fHelp) std::string status_string = ToLower(params[3].get_str()); GRC::ScraperEntryStatus status = GRC::ScraperEntryStatus::UNKNOWN; - CBitcoinAddress scraper_address; - if (!scraper_address.SetString(params[2].get_str())) { + CTxDestination scraper_address = DecodeDestination(params[2].get_str()); + if (!IsValidDestination(scraper_address)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Address specified for the scraper is invalid."); } if (block_v13_enabled) { // Contract version will be 3. - CKeyID key_id; - - scraper_address.GetKeyID(key_id); + CKeyID key_id = std::get(scraper_address); if (action == GRC::ContractAction::ADD) { if (status_string == "false") { @@ -2455,7 +2426,7 @@ UniValue addkey(const UniValue& params, bool fHelp) contract = GRC::MakeContract( contract_version, action, - scraper_address.ToString(), + EncodeDestination(scraper_address), status_string); } break; @@ -2472,8 +2443,8 @@ UniValue addkey(const UniValue& params, bool fHelp) case GRC::ContractType::SIDESTAKE: { if (block_v13_enabled) { - CBitcoinAddress sidestake_address; - if (!sidestake_address.SetString(params[2].get_str())) { + CTxDestination sidestake_address = DecodeDestination(params[2].get_str()); + if (!IsValidDestination(sidestake_address)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Address specified for the sidestake is invalid."); } @@ -2499,7 +2470,7 @@ UniValue addkey(const UniValue& params, bool fHelp) contract_version, // Contract version number (3+) action, // Contract action uint32_t {1}, // Contract payload version number - sidestake_address.Get(), // Sidestake destination + sidestake_address, // Sidestake destination allocation, // Sidestake allocation description, // Sidestake description GRC::MandatorySideStake::MandatorySideStakeStatus::MANDATORY // sidestake status @@ -2643,9 +2614,9 @@ UniValue listscrapers(const UniValue& params, bool fHelp) for (const auto& scraper : GRC::GetScraperRegistry().Scrapers()) { UniValue entry(UniValue::VOBJ); - CBitcoinAddress address(scraper.first); + CTxDestination address(scraper.first); - entry.pushKV("scraper_address", address.ToString()); + entry.pushKV("scraper_address", EncodeDestination(address)); entry.pushKV("current_scraper_entry_tx_hash", scraper.second->m_hash.ToString()); if (scraper.second->m_previous_hash.IsNull()) { entry.pushKV("previous_scraper_entry_tx_hash", "null"); @@ -2714,7 +2685,7 @@ UniValue listmandatorysidestakes(const UniValue& params, bool fHelp) for (const auto& sidestake : GRC::GetSideStakeRegistry().ActiveSideStakeEntries(GRC::SideStake::FilterFlag::MANDATORY, false)) { UniValue entry(UniValue::VOBJ); - entry.pushKV("mandatory_sidestake_entry_address", CBitcoinAddress(sidestake->GetDestination()).ToString()); + entry.pushKV("mandatory_sidestake_entry_address", EncodeDestination(sidestake->GetDestination())); entry.pushKV("mandatory_sidestake_entry_allocation", sidestake->GetAllocation().ToPercent()); entry.pushKV("mandatory_sidestake_entry_tx_hash", sidestake->GetHash().ToString()); if (sidestake->GetPreviousHash().IsNull()) { diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 9724c04aa9..f99bc02991 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -6,7 +6,7 @@ #include "init.h" #include "sync.h" #include "node/ui_interface.h" -#include "base58.h" +#include #include "protocol.h" #include "client.h" #include "server.h" diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index be24b0b100..23c318c659 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -117,7 +117,7 @@ UniValue getstakinginfo(const UniValue& params, bool fHelp) // sidestakes are always included. for (const auto& alloc : vSideStakeAlloc) { - sidestakingalloc.pushKV("address", CBitcoinAddress(alloc->GetDestination()).ToString()); + sidestakingalloc.pushKV("address", EncodeDestination(alloc->GetDestination())); sidestakingalloc.pushKV("allocation_pct", alloc->GetAllocation().ToPercent()); sidestakingalloc.pushKV("status", alloc->StatusToString()); @@ -213,7 +213,7 @@ UniValue getlaststake(const UniValue& params, bool fHelp) CTxDestination dest; if (ExtractDestination(stake_tx->vout[1].scriptPubKey, dest)) { - json.pushKV("address", CBitcoinAddress(dest).ToString()); + json.pushKV("address", EncodeDestination(dest)); } else { json.pushKV("address", ""); } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 13127761d3..77a4f96e64 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -518,15 +518,7 @@ UniValue sendalert(const UniValue& params, bool fHelp) sMsg << (CUnsignedAlert)alert; alert.vchMsg = vector((unsigned char*)&sMsg.begin()[0], (unsigned char*)&sMsg.end()[0]); - CBitcoinSecret vchSecret; - - if (!vchSecret.SetString(params[0].get_str())) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); - } - - bool fCompressed; - CSecret secret = vchSecret.GetSecret(fCompressed); - key.Set(secret.begin(), secret.end(), fCompressed); + key = DecodeSecret(params[0].get_str()); if (!key.IsValid()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); @@ -604,15 +596,7 @@ UniValue sendalert2(const UniValue& params, bool fHelp) sMsg << (CUnsignedAlert)alert; alert.vchMsg = vector((unsigned char*)&sMsg.begin()[0], (unsigned char*)&sMsg.end()[0]); - CBitcoinSecret vchSecret; - - if (!vchSecret.SetString(params[0].get_str())) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); - } - - bool fCompressed; - CSecret secret = vchSecret.GetSecret(fCompressed); - key.Set(secret.begin(), secret.end(), fCompressed); + key = DecodeSecret(params[0].get_str()); if (!key.IsValid()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index 804eba917b..c4f44923af 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -7,7 +7,7 @@ #include "sync.h" #include "node/ui_interface.h" #include "protocol.h" -#include "base58.h" +#include #include "wallet/db.h" #include "util.h" diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index ef570f9da7..509ea3a6f8 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -17,6 +17,7 @@ #include "gridcoin/support/block_finder.h" #include "gridcoin/tx_message.h" #include "gridcoin/voting/payloads.h" +#include #include "node/blockstorage.h" #include "policy/policy.h" #include "policy/fees.h" @@ -120,7 +121,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud UniValue a(UniValue::VARR); for (auto const& addr : addresses) - a.push_back(CBitcoinAddress(addr).ToString()); + a.push_back(EncodeDestination(addr)); out.pushKV("addresses", a); } @@ -252,7 +253,7 @@ UniValue SideStakePayloadToJson (const GRC::ContractPayload& payload) UniValue out(UniValue::VOBJ); - out.pushKV("address", CBitcoinAddress(sidestake.m_entry.m_destination).ToString()); + out.pushKV("address", EncodeDestination(sidestake.m_entry.m_destination)); out.pushKV("allocation", sidestake.m_entry.m_allocation.ToPercent()); out.pushKV("description", sidestake.m_entry.m_description); out.pushKV("status", sidestake.m_entry.StatusToString()); @@ -455,14 +456,14 @@ UniValue listunspent(const UniValue& params, bool fHelp) if (params.size() > 1) nMaxDepth = params[1].get_int(); - set setAddress; + set setAddress; if (params.size() > 2) { UniValue inputs = params[2].get_array(); for (unsigned int ix = 0; ix < inputs.size(); ix++) { - CBitcoinAddress address(inputs[ix].get_str()); - if (!address.IsValid()) + CTxDestination address = DecodeDestination(inputs[ix].get_str()); + if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Gridcoin address: ")+inputs[ix].get_str()); if (setAddress.count(address)) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+inputs[ix].get_str()); @@ -501,7 +502,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) CTxDestination address; if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { - entry.pushKV("address", CBitcoinAddress(address).ToString()); + entry.pushKV("address", EncodeDestination(address)); auto item = pwalletMain->mapAddressBook.find(address); @@ -566,7 +567,7 @@ UniValue consolidateunspent(const UniValue& params, bool fHelp) UniValue result(UniValue::VOBJ); std::string sAddress = params[0].get_str(); - CBitcoinAddress OptimizeAddress(sAddress); + CTxDestination OptimizeAddress = DecodeDestination(sAddress); int64_t nConsolidateLimit = 0; unsigned int nInputNumberLimit = GetMaxInputsForConsolidationTxn(); @@ -588,14 +589,14 @@ UniValue consolidateunspent(const UniValue& params, bool fHelp) // due to the size. nInputNumberLimit = std::min(nInputNumberLimit, GetMaxInputsForConsolidationTxn()); - if (!OptimizeAddress.IsValid()) + if (!IsValidDestination(OptimizeAddress)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Gridcoin address: ") + sAddress); } // Set the consolidation transaction address to the specified output address. CScript scriptDestPubKey; - scriptDestPubKey.SetDestination(OptimizeAddress.Get()); + scriptDestPubKey.SetDestination(OptimizeAddress); std::vector vecInputs; @@ -622,7 +623,7 @@ UniValue consolidateunspent(const UniValue& params, bool fHelp) // If the UTXO matches the consolidation address or all sweep_all_addresses is true then add to the inputs // map for consolidation. Note that the value of sweep_change is ignored and all change will be swept. - if (CBitcoinAddress(out_address) == OptimizeAddress || sweep_all_addresses) + if (out_address == OptimizeAddress || sweep_all_addresses) { mInputs.insert(std::make_pair(nOutValue, out)); } @@ -683,7 +684,7 @@ UniValue consolidateunspent(const UniValue& params, bool fHelp) // to the inputs map for consolidation. if (ExtractDestination(prev_ctxout.scriptPubKey, change_input_address)) { - if (CBitcoinAddress(change_input_address) == OptimizeAddress) + if (change_input_address == OptimizeAddress) { // Insert the ORIGINAL change UTXO into the input map for the consolidation. mInputs.insert(std::make_pair(nOutValue, out)); @@ -817,7 +818,7 @@ UniValue consolidateunspent(const UniValue& params, bool fHelp) CCoinControl coinControl; // Send the change back to the same address. - coinControl.destChange = OptimizeAddress.Get(); + coinControl.destChange = OptimizeAddress; if (!pwalletMain->CreateTransaction(vecSend, setCoins, wtxNew, reservekey, nFeeRequired, &coinControl)) { @@ -998,10 +999,10 @@ UniValue consolidatemsunspent(const UniValue& params, bool fHelp) if (nMaxValue < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Value must not be less than 0"); - CBitcoinAddress Address(sAddress); + CTxDestination Address = DecodeDestination(sAddress); // Check if the address is valid - if (!Address.IsValid()) + if (!IsValidDestination(Address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin Address"); { @@ -1019,7 +1020,7 @@ UniValue consolidatemsunspent(const UniValue& params, bool fHelp) txnouttype WhichType; vector vSolutions; - CSDest.SetDestination(Address.Get()); + CSDest.SetDestination(Address); // Solve the solutions for Destination script if (!Solver(CSDest, WhichType, vSolutions)) @@ -1148,7 +1149,7 @@ UniValue consolidatemsunspent(const UniValue& params, bool fHelp) continue; // If we found a match to multisig address do our work - if (CBitcoinAddress(txaddress) == Address) + if (txaddress == Address) { // Check if this output is already spent COutPoint dummy = COutPoint(tx.GetHash(), j); @@ -1206,7 +1207,7 @@ UniValue consolidatemsunspent(const UniValue& params, bool fHelp) // Make the output CScript scriptPubKey; - scriptPubKey.SetDestination(Address.Get()); + scriptPubKey.SetDestination(Address); CTxOut out(nOutput, scriptPubKey); @@ -1289,9 +1290,9 @@ UniValue scanforunspent(const UniValue& params, bool fHelp) if (nBlockEnd < 1 || nBlockEnd > nBestHeight || nBlockEnd <= nBlockStart) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block-end"); - CBitcoinAddress Address(sAddress); + CTxDestination Address = DecodeDestination(sAddress); - if (!Address.IsValid()) + if (!IsValidDestination(Address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin Address"); // Store as: TXID, VOUT, nValue, nHeight @@ -1339,7 +1340,7 @@ UniValue scanforunspent(const UniValue& params, bool fHelp) continue; // If we found a match to multisig address do our work - if (CBitcoinAddress(txaddress) == Address) + if (txaddress == Address) { // Check if this output is already spent COutPoint dummy = COutPoint(tx.GetHash(), j); @@ -1546,11 +1547,11 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) rawTx.vin.push_back(in); } - set setAddress; + set setAddress; vector addrList = sendTo.getKeys(); for (auto const& name_: addrList) { - CBitcoinAddress address(name_); + CTxDestination address = DecodeDestination(name_); if (name_ == "data") { std::vector data = ParseHexV(sendTo[name_],"Data"); @@ -1559,8 +1560,8 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) } else { - CBitcoinAddress address(name_); - if (!address.IsValid()) + CTxDestination address = DecodeDestination(name_); + if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Gridcoin address: ")+name_); if (setAddress.count(address)) @@ -1568,7 +1569,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) setAddress.insert(address); CScript scriptPubKey; - scriptPubKey.SetDestination(address.Get()); + scriptPubKey.SetDestination(address); int64_t nAmount = AmountFromValue(sendTo[name_]); CTxOut out(nAmount, scriptPubKey); @@ -1630,7 +1631,7 @@ UniValue decodescript(const UniValue& params, bool fHelp) } ScriptPubKeyToJSON(script, r, false); - r.pushKV("p2sh", CBitcoinAddress(script.GetID()).ToString()); + r.pushKV("p2sh", EncodeDestination(script.GetID())); return r; } @@ -1762,14 +1763,10 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) for (unsigned int idx = 0; idx < keys.size(); idx++) { UniValue k = keys[idx]; - CBitcoinSecret vchSecret; - bool fGood = vchSecret.SetString(k.get_str()); - if (!fGood) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,"Invalid private key"); - CKey key; - bool fCompressed; - CSecret secret = vchSecret.GetSecret(fCompressed); - key.Set(secret.begin(), secret.end(), fCompressed); + CKey key = DecodeSecret(k.get_str()); + if (!key.IsValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); + } tempKeystore.AddKey(key); } } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index a483355d62..497c8bbd30 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -4,10 +4,11 @@ // file COPYING or https://opensource.org/licenses/mit-license.php. #include "amount.h" +#include #include "init.h" #include "sync.h" +#include #include "node/ui_interface.h" -#include "base58.h" #include "server.h" #include "client.h" #include "protocol.h" @@ -288,7 +289,6 @@ static const CRPCCommand vRPCCommands[] = // Wallet commands { "addmultisigaddress", &addmultisigaddress, cat_wallet }, { "addredeemscript", &addredeemscript, cat_wallet }, - { "backupprivatekeys", &backupprivatekeys, cat_wallet }, { "backupwallet", &backupwallet, cat_wallet }, { "burn", &burn, cat_wallet }, { "checkwallet", &checkwallet, cat_wallet }, diff --git a/src/rpc/server.h b/src/rpc/server.h index a4b6f2d571..e1ae8b6874 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -103,7 +103,6 @@ extern std::vector ParseHexV(const UniValue& v, std::string strNa // Wallet extern UniValue addmultisigaddress(const UniValue& params, bool fHelp); extern UniValue addredeemscript(const UniValue& params, bool fHelp); -extern UniValue backupprivatekeys(const UniValue& params, bool fHelp); extern UniValue backupwallet(const UniValue& params, bool fHelp); extern UniValue burn(const UniValue& params, bool fHelp); extern UniValue checkwallet(const UniValue& params, bool fHelp); diff --git a/src/script.cpp b/src/script.cpp index e81af2bfcf..2595d20daa 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1910,3 +1910,7 @@ void CScript::SetMultisig(int nRequired, const std::vector& keys) *this << key; *this << EncodeOP_N(keys.size()) << OP_CHECKMULTISIG; } + +bool IsValidDestination(const CTxDestination& dest) { + return dest.index() != 0; +} diff --git a/src/script.h b/src/script.h index c65169c25c..4d675b5c62 100644 --- a/src/script.h +++ b/src/script.h @@ -106,10 +106,12 @@ class CNoDestination { * * CNoDestination: no destination set * * CKeyID: TX_PUBKEYHASH destination * * CScriptID: TX_SCRIPTHASH destination - * A CTxDestination is the internal data type encoded in a CBitcoinAddress */ typedef std::variant CTxDestination; +/** Check whether a CTxDestination is a CNoDestination. */ +bool IsValidDestination(const CTxDestination& dest); + const char* GetTxnOutputType(txnouttype t); /** Script opcodes */ diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 895c30e81c..dee72293c1 100755 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -8,8 +8,6 @@ #include #include #include -#include -#include #include @@ -80,196 +78,4 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58) BOOST_CHECK(!DecodeBase58Check(std::string("3vQB7B6MrGQZaxCuFg4oh\00IOl", 26), result)); } -// Visitor to check address type -class TestAddrTypeVisitor -{ -private: - std::string exp_addrType; -public: - TestAddrTypeVisitor(const std::string &exp_addrType) : exp_addrType(exp_addrType) { } - bool operator()(const CKeyID &id) const - { - return (exp_addrType == "pubkey"); - } - bool operator()(const CScriptID &id) const - { - return (exp_addrType == "script"); - } - bool operator()(const CNoDestination &no) const - { - return (exp_addrType == "none"); - } -}; - -// Visitor to check address payload -class TestPayloadVisitor -{ -private: - std::vector exp_payload; -public: - TestPayloadVisitor(std::vector &exp_payload) : exp_payload(exp_payload) { } - bool operator()(const CKeyID &id) const - { - uint160 exp_key(exp_payload); - return exp_key == id; - } - bool operator()(const CScriptID &id) const - { - uint160 exp_key(exp_payload); - return CScriptID(exp_key) == id; - } - bool operator()(const CNoDestination &no) const - { - return exp_payload.size() == 0; - } -}; - -// Goal: check that parsed keys match test payload -BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) -{ - UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); - std::vector result; - CBitcoinSecret secret; - CBitcoinAddress addr; - // Save global state - bool fTestNet_stored = fTestNet; - for (unsigned int idx = 0; idx < tests.size(); idx++) { - UniValue test = tests[idx]; - std::string strTest = test.write(); - if (test.size() < 3) // Allow for extra stuff (useful for comments) - { - BOOST_ERROR("Bad test: " << strTest); - continue; - } - std::string exp_base58string = test[0].get_str(); - std::vector exp_payload = ParseHex(test[1].get_str()); - const UniValue &metadata = test[2].get_obj(); - bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); - bool isTestnet = find_value(metadata, "isTestnet").get_bool(); - fTestNet = isTestnet; // Override testnet flag - if(isPrivkey) - { - bool isCompressed = find_value(metadata, "isCompressed").get_bool(); - // Must be valid private key - // Note: CBitcoinSecret::SetString tests isValid, whereas CBitcoinAddress does not! - BOOST_CHECK_MESSAGE(secret.SetString(exp_base58string), "!SetString:"+ strTest); - BOOST_CHECK_MESSAGE(secret.IsValid(), "!IsValid:" + strTest); - bool fCompressedOut = false; - CSecret privkey = secret.GetSecret(fCompressedOut); - BOOST_CHECK_MESSAGE(fCompressedOut == isCompressed, "compressed mismatch:" + strTest); - BOOST_CHECK_MESSAGE(privkey.size() == exp_payload.size() && std::equal(privkey.begin(), privkey.end(), exp_payload.begin()), "key mismatch:" + strTest); - - // Private key must be invalid public key - addr.SetString(exp_base58string); - BOOST_CHECK_MESSAGE(!addr.IsValid(), "IsValid privkey as pubkey:" + strTest); - } - else - { - std::string exp_addrType = find_value(metadata, "addrType").get_str(); // "script" or "pubkey" - // Must be valid public key - BOOST_CHECK_MESSAGE(addr.SetString(exp_base58string), "SetString:" + strTest); - BOOST_CHECK_MESSAGE(addr.IsValid(), "!IsValid:" + strTest); - BOOST_CHECK_MESSAGE(addr.IsScript() == (exp_addrType == "script"), "isScript mismatch" + strTest); - CTxDestination dest = addr.Get(); - BOOST_CHECK_MESSAGE(std::visit(TestAddrTypeVisitor(exp_addrType), dest), "addrType mismatch" + strTest); - - // Public key must be invalid private key - secret.SetString(exp_base58string); - BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest); - } - } - // Restore global state - fTestNet = fTestNet_stored; -} - -// Goal: check that generated keys match test vectors -BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) -{ - UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); - std::vector result; - // Save global state - bool fTestNet_stored = fTestNet; - for (unsigned int idx = 0; idx < tests.size(); idx++) { - UniValue test = tests[idx]; - std::string strTest = test.write(); - if (test.size() < 3) // Allow for extra stuff (useful for comments) - { - BOOST_ERROR("Bad test: " << strTest); - continue; - } - std::string exp_base58string = test[0].get_str(); - std::vector exp_payload = ParseHex(test[1].get_str()); - const UniValue &metadata = test[2].get_obj(); - bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); - bool isTestnet = find_value(metadata, "isTestnet").get_bool(); - fTestNet = isTestnet; // Override testnet flag - if(isPrivkey) - { - bool isCompressed = find_value(metadata, "isCompressed").get_bool(); - CBitcoinSecret secret; - secret.SetSecret(CSecret(exp_payload.begin(), exp_payload.end()), isCompressed); - BOOST_CHECK_MESSAGE(secret.ToString() == exp_base58string, "result mismatch: " + strTest); - } - else - { - std::string exp_addrType = find_value(metadata, "addrType").get_str(); - CTxDestination dest; - if(exp_addrType == "pubkey") - { - dest = CKeyID(uint160(exp_payload)); - } - else if(exp_addrType == "script") - { - dest = CScriptID(uint160(exp_payload)); - } - else if(exp_addrType == "none") - { - dest = CNoDestination(); - } - else - { - BOOST_ERROR("Bad addrtype: " << strTest); - continue; - } - CBitcoinAddress addrOut; - BOOST_CHECK_MESSAGE(std::visit(CBitcoinAddressVisitor(&addrOut), dest), "encode dest: " + strTest); - BOOST_CHECK_MESSAGE(addrOut.ToString() == exp_base58string, "mismatch: " + strTest + addrOut.ToString()); - } - } - - // Visiting a CNoDestination must fail - CBitcoinAddress dummyAddr; - CTxDestination nodest = CNoDestination(); - BOOST_CHECK(!std::visit(CBitcoinAddressVisitor(&dummyAddr), nodest)); - - // Restore global state - fTestNet = fTestNet_stored; -} - -// Goal: check that base58 parsing code is robust against a variety of corrupted data -BOOST_AUTO_TEST_CASE(base58_keys_invalid) -{ - UniValue tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); - std::vector result; - CBitcoinSecret secret; - CBitcoinAddress addr; - for (unsigned int idx = 0; idx < tests.size(); idx++) { - UniValue test = tests[idx]; - std::string strTest = test.write(); - if (test.size() < 1) // Allow for extra stuff (useful for comments) - { - BOOST_ERROR("Bad test: " << strTest); - continue; - } - std::string exp_base58string = test[0].get_str(); - - // must be invalid as public and as private key - addr.SetString(exp_base58string); - BOOST_CHECK_MESSAGE(!addr.IsValid(), "IsValid pubkey:" + strTest); - secret.SetString(exp_base58string); - BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid privkey:" + strTest); - } -} - - BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/data/CMakeLists.txt b/src/test/data/CMakeLists.txt index 784efde82a..9034d69b56 100644 --- a/src/test/data/CMakeLists.txt +++ b/src/test/data/CMakeLists.txt @@ -1,7 +1,7 @@ set(JSON_TEST_FILES - base58_keys_valid.json base58_encode_decode.json - base58_keys_invalid.json + key_io_invalid.json + key_io_valid.json script_valid.json script_invalid.json tx_invalid.json diff --git a/src/test/data/base58_keys_invalid.json b/src/test/data/key_io_invalid.json similarity index 100% rename from src/test/data/base58_keys_invalid.json rename to src/test/data/key_io_invalid.json diff --git a/src/test/data/base58_keys_valid.json b/src/test/data/key_io_valid.json similarity index 76% rename from src/test/data/base58_keys_valid.json rename to src/test/data/key_io_valid.json index 9855ceeb0f..733c0fc61b 100644 --- a/src/test/data/base58_keys_valid.json +++ b/src/test/data/key_io_valid.json @@ -1,38 +1,38 @@ [ [ "SE8hQCjzRxWye3p7D4hdYeeYaNuGUMWKaV", - "B174A85C22C917563A4E8425082A9B2302691814", + "76a914b174a85c22c917563a4e8425082a9b230269181488ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "bE9beycFciNiykheLUmSPn5txcsvAMvA8v", - "0F91EFD3FE4DC089C6E2F4E259705F3A37716733", + "a9140f91efd3fe4dc089c6e2f4e259705f3a3771673387", { "addrType": "script", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "mtocGjbyzLqgMjqnjsTXJB29DpF4Xycg8Q", - "91BFFE0E06D0B15F74896B1F3967307EF7C73B73", + "76a91491bffe0e06d0b15f74896b1f3967307ef7c73b7388ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ - "2Mua2yKphS8HcpmT15YTQ7crCey6sXohv9y", - "197EF56DD6D0BDEC3D9D8B09297FF02293400FEF", + "2Mua2yKphS8HcpmT15YTQ7crCey6sXohv9y", + "a914197ef56dd6d0bdec3d9d8b09297ff02293400fef87", { "addrType": "script", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ @@ -41,7 +41,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -50,7 +50,7 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -59,7 +59,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ @@ -68,43 +68,43 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ "RxN1HEdC2HqHEAk469wN39mDXknG4Dp2ZX", - "0476FA5D10A4D4FEB6FE00146AC6E2AB503BB9B3", + "76a9140476fa5d10a4d4feb6fe00146ac6e2ab503bb9b388ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "bJkYuAPAqyxJDAfFoSP8t4Sg5g7vfFEG5G", - "420EB2D228DBE7611D797BABFD720A198DCE488F", + "a914420eb2d228dbe7611d797babfd720a198dce488f87", { "addrType": "script", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "mmwJ4FJUQ5kez7F1hm7S7AY8vHuqg5fChS", - "466B3BF6CC306568A8E754A3455ECF0D216B8782", + "76a914466b3bf6cc306568a8e754a3455ecf0d216b878288ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ "2N5B1qtneGpC9cchdKw9nsGSG74yRv2desu", - "82D5B52C470B024BD9CBC6A03FA401C1302FC5A5", + "a91482d5b52c470b024bd9cbc6a03fa401c1302fc5a587", { "addrType": "script", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ @@ -113,7 +113,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -122,7 +122,7 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -131,7 +131,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ @@ -140,43 +140,43 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ "S5GgFVTsorwKffDSsgZAFRHcV3sWNngz8z", - "503DE4A5E4DCCF882CC81A401653F9864E34B3EF", + "76a914503de4a5e4dccf882cc81a401653f9864e34b3ef88ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "bbpiXYwBzX3JFdVvTmiKGwZb4tbU5mgkLU", - "FD5289882CCF46545266F122243B352A64AE9729", + "a914fd5289882ccf46545266f122243b352a64ae972987", { "addrType": "script", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "mwJ3qHbM193N6r2cJt3uNfCnGbun3dZiac", - "AD113A74A31FB178B87AA9C8338A15D9AE064821", + "76a914ad113a74a31fb178b87aa9c8338a15d9ae06482188ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ "2N7wZC6QBYmp24rQtyR17evyhuA3wj2LNow", - "A1326E08A14B3202D77B53635CB3736355103697", + "a914a1326e08a14b3202d77b53635cb373635510369787", { "addrType": "script", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ @@ -185,7 +185,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -194,7 +194,7 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -203,7 +203,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ @@ -212,43 +212,43 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ "SGeyeAC18vCZdW3wrBr3fgtbzyax9zuoRT", - "CD1EF1EFC1F9E1720693B8AFBCE39A829C04F54E", + "76a914cd1ef1efc1f9e1720693b8afbce39a829c04f54e88ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "bGDhyPqUcykcEXHP2h8umYWvyF6zhUkTH7", - "26492038BEA91C03B677BFCE591C9B84A033AEE3", + "a91426492038bea91c03b677bfce591c9b84a033aee387", { "addrType": "script", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "mfprNrD49kcdxQcmA4o2qLosLmg43ocm8Q", - "03628C3B3C51F1634E260C948E376E6479122489", + "76a91403628c3b3c51f1634e260c948e376e647912248988ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ "2N45K8B7KHgmZ8CufhvFX15jaidmYaTV7WK", - "76C982E8E14D3B61B55DA51DA0ED2E1C3CF634E0", + "a91476c982e8e14d3b61b55da51da0ed2e1c3cf634e087", { "addrType": "script", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ @@ -257,7 +257,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -266,7 +266,7 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -275,7 +275,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ @@ -284,43 +284,43 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ "S4tBgEy9mYTex8g5mDVvBwnMo1uEKm8D8N", - "4BFCE3E6060BCC52B14158543478F898D89270D0", + "76a9144bfce3e6060bcc52b14158543478f898d89270d088ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "bTp4nL6vhz5nvKJTt8gePcqXjkv1adUQKQ", - "A57205DA5628AF7BC2FC0796976D32E83C0A2168", + "a914a57205da5628af7bc2fc0796976d32e83c0a216887", { "addrType": "script", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "mrZd1vneUmE4YkPg4P6wWWDgvuev45qpAh", - "792A89FCFADFDFB5E0571A8A06B9B51F6D447483", + "76a914792a89fcfadfdfb5e0571a8a06b9b51f6d44748388ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ "2N1UMtU75Ua1cvDzAMCuhM1bQSGrU9j9NcG", - "5A3D02150EAF6F3FC5FAEE1964996525526D28D8", + "a9145a3d02150eaf6f3fc5faee1964996525526d28d887", { "addrType": "script", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ @@ -329,7 +329,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -338,7 +338,7 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -347,7 +347,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ @@ -356,43 +356,43 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ "S7vE1RM32kdRyoA2x4nRnba86Z25JVaL6m", - "6D480B886118FB6E6D3FFC35B62F2C5BFD98DD2B", + "76a9146d480b886118fb6e6d3ffc35b62f2c5bfd98dd2b88ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "bDtPuxX6bY4j6hxF4w2gbUz1LPvS36MhQ9", - "0CB1E55B1E593DEEE37D75895576BD3CAB52430B2", + "a9140cb1e55b1e593deee37d75895576bd3cab52430b87", { "addrType": "script", "isPrivkey": false, - "isTestnet": false + "chain": "main" } ], [ "mjFCEneHB5n1pzE5ZinZV6uiqrcxHJRpUG", - "28E57CC2E23A4A20B22D0201A20C2A736E7C296B", + "76a91428e57cc2e23a4a20b22d0201a20c2a736e7c296b88ac", { "addrType": "pubkey", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ "2MybDkUBALd9Ga8X4DqWfzhbFdNzvUaQEYE", - "4598E00770AC4D4521DF3F847D0573C75071E47A", + "a9144598e00770ac4d4521df3f847d0573c75071e47a87", { "addrType": "script", "isPrivkey": false, - "isTestnet": true + "chain": "test" } ], [ @@ -401,7 +401,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -410,7 +410,7 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": false + "chain": "main" } ], [ @@ -419,7 +419,7 @@ { "isCompressed": false, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ], [ @@ -428,7 +428,7 @@ { "isCompressed": true, "isPrivkey": true, - "isTestnet": true + "chain": "test" } ] ] diff --git a/src/test/gridcoin/beacon_tests.cpp b/src/test/gridcoin/beacon_tests.cpp index 770cddb0d7..7c9f91b49a 100644 --- a/src/test/gridcoin/beacon_tests.cpp +++ b/src/test/gridcoin/beacon_tests.cpp @@ -2,9 +2,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or https://opensource.org/licenses/mit-license.php. -#include "base58.h" +#include #include "dbwrapper.h" #include "gridcoin/beacon.h" +#include #include "rpc/blockchain.h" #include "test/data/testnet_beacon.bin.h" #include "test/data/mainnet_beacon.bin.h" @@ -71,9 +72,9 @@ struct TestKey //! //! \brief Create an address from the test public key. //! - static CBitcoinAddress Address() + static CTxDestination Address() { - return CBitcoinAddress(CTxDestination(KeyId())); + return CTxDestination(KeyId()); } //! @@ -210,7 +211,7 @@ class BeaconRegistryTest << "blockheight = " << ctx.m_pindex->nHeight << ", cpid = " << beacon->m_cpid.ToString() << ", public key = " << HexStr(beacon->m_public_key) - << ", address = " << beacon->GetAddress().ToString() + << ", address = " << EncodeDestination(beacon->GetAddress()) << ", timestamp = " << beacon->m_timestamp << ", hash = " << beacon->m_hash.GetHex() << ", prev beacon hash = " << beacon->m_previous_hash.GetHex() @@ -230,7 +231,7 @@ class BeaconRegistryTest << "blockheight = " << ctx.m_pindex->nHeight << ", cpid = " << beacon->m_cpid.ToString() << ", public key = " << HexStr(beacon->m_public_key) - << ", address = " << beacon->GetAddress().ToString() + << ", address = " << EncodeDestination(beacon->GetAddress()) << ", timestamp = " << beacon->m_timestamp << ", hash = " << beacon->m_hash.GetHex() << ", prev beacon hash = " << beacon->m_previous_hash.GetHex() @@ -268,7 +269,7 @@ class BeaconRegistryTest << "blockheight = " << pindex->nHeight << ", cpid = " << activated_beacon->m_cpid.ToString() << ", public key = " << HexStr(activated_beacon->m_public_key) - << ", address = " << activated_beacon->GetAddress().ToString() + << ", address = " << EncodeDestination(activated_beacon->GetAddress()) << ", timestamp = " << activated_beacon->m_timestamp << ", hash = " << activated_beacon->m_hash.GetHex() << ", prev beacon hash = " << activated_beacon->m_previous_hash.GetHex() @@ -283,7 +284,7 @@ class BeaconRegistryTest << "blockheight = " << pindex->nHeight << ", cpid = " << iter->m_cpid.ToString() << ", public key = " << HexStr(iter->m_public_key) - << ", address = " << iter->GetAddress().ToString() + << ", address = " << EncodeDestination(iter->GetAddress()) << ", timestamp = " << iter->m_timestamp << ", hash = " << iter->m_hash.GetHex() << ", prev beacon hash = " << iter->m_previous_hash.GetHex() @@ -328,7 +329,7 @@ class BeaconRegistryTest std::cout << "init beacon db record: " << ", cpid = " << beacon_ptr->m_cpid.ToString() << ", public key = " << HexStr(beacon_ptr->m_public_key) - << ", address = " << beacon_ptr->GetAddress().ToString() + << ", address = " << EncodeDestination(beacon_ptr->GetAddress()) << ", timestamp = " << beacon_ptr->m_timestamp << ", hash = " << beacon_ptr->m_hash.GetHex() << ", prev beacon hash = " << beacon_ptr->m_previous_hash.GetHex() @@ -379,7 +380,7 @@ class BeaconRegistryTest std::cout << "init beacon db record: " << ", cpid = " << beacon_ptr->m_cpid.ToString() << ", public key = " << HexStr(beacon_ptr->m_public_key) - << ", address = " << beacon_ptr->GetAddress().ToString() + << ", address = " << EncodeDestination(beacon_ptr->GetAddress()) << ", timestamp = " << beacon_ptr->m_timestamp << ", hash = " << beacon_ptr->m_hash.GetHex() << ", prev beacon hash = " << beacon_ptr->m_previous_hash.GetHex() @@ -431,7 +432,7 @@ class BeaconRegistryTest << "hash = " << hash.GetHex() << ", cpid = " << left.second->m_cpid.ToString() << ", public key = " << HexStr(left.second->m_public_key) - << ", address = " << left.second->GetAddress().ToString() + << ", address = " << EncodeDestination(left.second->GetAddress()) << ", timestamp = " << left.second->m_timestamp << ", hash = " << left.second->m_hash.GetHex() << ", prev beacon hash = " << left.second->m_previous_hash.GetHex() @@ -457,8 +458,8 @@ class BeaconRegistryTest std::cout << "init_beacon public key = " << HexStr(left_beacon_ptr->m_public_key) << ", reinit_beacon public key = " << HexStr(right_beacon_iter->second->m_public_key) << std::endl; - std::cout << "init_beacon address = " << left_beacon_ptr->GetAddress().ToString() - << ", reinit_beacon address = " << right_beacon_iter->second->GetAddress().ToString() << std::endl; + std::cout << "init_beacon address = " << EncodeDestination(left_beacon_ptr->GetAddress()) + << ", reinit_beacon address = " << EncodeDestination(right_beacon_iter->second->GetAddress()) << std::endl; std::cout << "init_beacon timestamp = " << left_beacon_ptr->m_timestamp << ", reinit_beacon timestamp = " << right_beacon_iter->second->m_timestamp << std::endl; @@ -493,7 +494,7 @@ class BeaconRegistryTest << "hash = " << hash.GetHex() << ", cpid = " << left.second->m_cpid.ToString() << ", public key = " << HexStr(left.second->m_public_key) - << ", address = " << left.second->GetAddress().ToString() + << ", address = " << EncodeDestination(left.second->GetAddress()) << ", timestamp = " << left.second->m_timestamp << ", hash = " << left.second->m_hash.GetHex() << ", prev beacon hash = " << left.second->m_previous_hash.GetHex() @@ -519,8 +520,8 @@ class BeaconRegistryTest std::cout << "reinit_beacon public key = " << HexStr(left_beacon_ptr->m_public_key) << ", init_beacon public key = " << HexStr(right_beacon_iter->second->m_public_key) << std::endl; - std::cout << "reinit_beacon address = " << left_beacon_ptr->GetAddress().ToString() - << ", init_beacon address = " << right_beacon_iter->second->GetAddress().ToString() << std::endl; + std::cout << "reinit_beacon address = " << EncodeDestination(left_beacon_ptr->GetAddress()) + << ", init_beacon address = " << EncodeDestination(right_beacon_iter->second->GetAddress()) << std::endl; std::cout << "reinit_beacon timestamp = " << left_beacon_ptr->m_timestamp << ", init_beacon timestamp = " << right_beacon_iter->second->m_timestamp << std::endl; @@ -557,7 +558,7 @@ class BeaconRegistryTest // You should be in the src directory for that, so the command would be ./test/test_gridcoin. std::cout << "init_beacon cpid = " << cpid.ToString() << ", public key = " << HexStr(beacon.m_public_key) - << ", address = " << beacon.GetAddress().ToString() + << ", address = " << EncodeDestination(beacon.GetAddress()) << ", timestamp = " << beacon.m_timestamp << ", hash = " << beacon.m_hash.GetHex() << ", prev beacon hash = " << beacon.m_previous_hash.GetHex() @@ -574,7 +575,7 @@ class BeaconRegistryTest // You should be in the src directory for that, so the command would be ./test/test_gridcoin. std::cout << "reinit beacon cpid = " << cpid.ToString() << ", public key = " << HexStr(beacon.m_public_key) - << ", address = " << beacon.GetAddress().ToString() + << ", address = " << EncodeDestination(beacon.GetAddress()) << ", timestamp = " << beacon.m_timestamp << ", hash = " << beacon.m_hash.GetHex() << ", prev beacon hash = " << beacon.m_previous_hash.GetHex() @@ -603,7 +604,7 @@ class BeaconRegistryTest << "hash = " << left.second.m_hash.GetHex() << ", cpid = " << left.second.m_cpid.ToString() << ", public key = " << HexStr(left.second.m_public_key) - << ", address = " << left.second.GetAddress().ToString() + << ", address = " << EncodeDestination(left.second.GetAddress()) << ", timestamp = " << left.second.m_timestamp << ", hash = " << left.second.m_hash.GetHex() << ", prev beacon hash = " << left.second.m_previous_hash.GetHex() @@ -656,7 +657,7 @@ class BeaconRegistryTest << "hash = " << left.second.m_hash.GetHex() << ", cpid = " << left.second.m_cpid.ToString() << ", public key = " << HexStr(left.second.m_public_key) - << ", address = " << left.second.GetAddress().ToString() + << ", address = " << EncodeDestination(left.second.GetAddress()) << ", timestamp = " << left.second.m_timestamp << ", hash = " << left.second.m_hash.GetHex() << ", prev beacon hash = " << left.second.m_previous_hash.GetHex() @@ -720,7 +721,7 @@ class BeaconRegistryTest << "hash = " << left_beacon.m_hash.GetHex() << ", cpid = " << left_beacon.m_cpid.ToString() << ", public key = " << HexStr(left_beacon.m_public_key) - << ", address = " << left_beacon.GetAddress().ToString() + << ", address = " << EncodeDestination(left_beacon.GetAddress()) << ", timestamp = " << left_beacon.m_timestamp << ", hash = " << left_beacon.m_hash.GetHex() << ", prev beacon hash = " << left_beacon.m_previous_hash.GetHex() @@ -775,7 +776,7 @@ class BeaconRegistryTest << "hash = " << left.second.m_hash.GetHex() << ", cpid = " << left.second.m_cpid.ToString() << ", public key = " << HexStr(left.second.m_public_key) - << ", address = " << left.second.GetAddress().ToString() + << ", address = " << EncodeDestination(left.second.GetAddress()) << ", timestamp = " << left.second.m_timestamp << ", hash = " << left.second.m_hash.GetHex() << ", prev beacon hash = " << left.second.m_previous_hash.GetHex() @@ -962,7 +963,7 @@ BOOST_AUTO_TEST_CASE(it_represents_itself_as_a_legacy_string) const std::string expected = EncodeBase64( "0;0;" - + TestKey::Address().ToString() + + EncodeDestination(TestKey::Address()) + ";" + HexStr(TestKey::Public())); diff --git a/src/test/gridcoin/scraper_registry_tests.cpp b/src/test/gridcoin/scraper_registry_tests.cpp index 1164ae068e..4465ccafda 100644 --- a/src/test/gridcoin/scraper_registry_tests.cpp +++ b/src/test/gridcoin/scraper_registry_tests.cpp @@ -15,10 +15,10 @@ void AddRemoveScraperEntryV1(const std::string& address, const std::string& valu GRC::ScraperRegistry& registry = GRC::GetScraperRegistry(); std::string status_string = ToLower(value); - CBitcoinAddress scraper_address; + CTxDestination scraper_address = DecodeDestination(address); // Assert if not a valid address. - assert(scraper_address.SetString(address)); + assert(IsValidDestination(scraper_address)); // Make sure the registry is reset. if (reset_registry) registry.Reset(); @@ -54,12 +54,8 @@ void AddRemoveScraperEntryV2(const std::string& address, const GRC::ScraperEntry { GRC::ScraperRegistry& registry = GRC::GetScraperRegistry(); - CBitcoinAddress scraper_address; - CKeyID key_id; - - scraper_address.SetString(address); - - scraper_address.GetKeyID(key_id); + CTxDestination scraper_address = DecodeDestination(address); + CKeyID key_id = std::get(scraper_address); // Make sure the registry is reset. if (reset_registry) registry.Reset(); @@ -119,11 +115,9 @@ BOOST_AUTO_TEST_CASE(scraper_entries_added_to_scraper_work_correctly_legacy) // Native format from legacy adds. for (const auto& entry : scraper_entries) { - CBitcoinAddress address; - address.SetString(entry); + CTxDestination address = DecodeDestination(entry); - CKeyID key_id; - address.GetKeyID(key_id); + CKeyID key_id = std::get(address); auto registry_entry = scraper_map.find(key_id); @@ -185,11 +179,9 @@ BOOST_AUTO_TEST_CASE(scraper_entry_deauthorize_and_delete_works_correctly_legacy // Native format from legacy adds. for (const auto& entry : scraper_entries) { - CBitcoinAddress address; - address.SetString(entry); + CTxDestination address = DecodeDestination(entry); - CKeyID key_id; - address.GetKeyID(key_id); + CKeyID key_id = std::get(address); auto registry_entry = scraper_map.find(key_id); @@ -254,11 +246,9 @@ BOOST_AUTO_TEST_CASE(scraper_entry_deauthorize_and_delete_works_correctly_legacy // Native format from legacy adds, deauthorize, and delete for active scraper map.. for (const auto& entry : scraper_entries) { - CBitcoinAddress address; - address.SetString(entry); + CTxDestination address = DecodeDestination(entry); - CKeyID key_id; - address.GetKeyID(key_id); + CKeyID key_id = std::get(address); auto registry_entry = scraper_map.find(key_id); @@ -385,11 +375,9 @@ BOOST_AUTO_TEST_CASE(scraper_entry_deauthorize_and_delete_works_correctly_native // Native format from native adds. for (const auto& entry : scraper_entries) { - CBitcoinAddress address; - address.SetString(entry); + CTxDestination address = DecodeDestination(entry); - CKeyID key_id; - address.GetKeyID(key_id); + CKeyID key_id = std::get(address); auto registry_entry = scraper_map.find(key_id); @@ -430,11 +418,9 @@ BOOST_AUTO_TEST_CASE(scraper_entry_deauthorize_and_delete_works_correctly_native GRC::Contract contract; - CBitcoinAddress address; - address.SetString("SLbdvKZHmtu49VUWm88rbcCo9DaC8Z2urV"); + CTxDestination address = DecodeDestination("SLbdvKZHmtu49VUWm88rbcCo9DaC8Z2urV"); - CKeyID key_id; - address.GetKeyID(key_id) + CKeyID key_id = std::get(address); ; contract = GRC::MakeContract( uint32_t {3}, // Contract version (pre v13) @@ -460,11 +446,9 @@ BOOST_AUTO_TEST_CASE(scraper_entry_deauthorize_and_delete_works_correctly_native // Native format from legacy adds, deauthorize, and delete for active scraper map.. for (const auto& entry : scraper_entries) { - CBitcoinAddress address; - address.SetString(entry); + CTxDestination address = DecodeDestination(entry); - CKeyID key_id; - address.GetKeyID(key_id); + CKeyID key_id = std::get(address); auto registry_entry = scraper_map.find(key_id); diff --git a/src/test/gridcoin/superblock_tests.cpp b/src/test/gridcoin/superblock_tests.cpp index eea417b628..0e4b92dc55 100644 --- a/src/test/gridcoin/superblock_tests.cpp +++ b/src/test/gridcoin/superblock_tests.cpp @@ -2,12 +2,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or https://opensource.org/licenses/mit-license.php. -#include "base58.h" +#include #include "compat/endian.h" #include #include "gridcoin/scraper/scraper_net.h" #include "gridcoin/superblock.h" #include "gridcoin/support/xml.h" +#include #include "streams.h" #include diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp new file mode 100644 index 0000000000..8300aa04d2 --- /dev/null +++ b/src/test/key_io_tests.cpp @@ -0,0 +1,153 @@ +// Copyright (c) 2011-2023 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://opensource.org/licenses/mit-license.php. + +#include +#include + +#include +#include +#include +#include + +#include + +#include + +UniValue read_json(const std::string& jsondata); + +BOOST_AUTO_TEST_SUITE(key_io_tests) + +// Goal: check that parsed keys match test payload +BOOST_AUTO_TEST_CASE(key_io_valid_parse) +{ + UniValue tests = read_json(std::string(json_tests::key_io_valid, json_tests::key_io_valid + sizeof(json_tests::key_io_valid))); + CKey privkey; + CTxDestination destination; + SelectParams(CBaseChainParams::MAIN); + + for (unsigned int idx = 0; idx < tests.size(); idx++) { + const UniValue& test = tests[idx]; + std::string strTest = test.write(); + if (test.size() < 3) { // Allow for extra stuff (useful for comments) + BOOST_ERROR("Bad test: " << strTest); + continue; + } + std::string exp_base58string = test[0].get_str(); + const std::vector exp_payload{ParseHex(test[1].get_str())}; + const UniValue &metadata = test[2].get_obj(); + bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); + SelectParams(find_value(metadata, "chain").get_str()); + bool try_case_flip = find_value(metadata, "tryCaseFlip").isNull() ? false : find_value(metadata, "tryCaseFlip").get_bool(); + if (isPrivkey) { + bool isCompressed = find_value(metadata, "isCompressed").get_bool(); + // Must be valid private key + privkey = DecodeSecret(exp_base58string); + BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest); + BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest); + BOOST_CHECK_MESSAGE(Span{privkey} == MakeByteSpan(exp_payload), "key mismatch:" + strTest); + + // Private key must be invalid public key + destination = DecodeDestination(exp_base58string); + BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid privkey as pubkey:" + strTest); + } else { + // Must be valid public key + destination = DecodeDestination(exp_base58string); + CScript script; + script.SetDestination(destination); + BOOST_CHECK_MESSAGE(IsValidDestination(destination), "!IsValid:" + strTest); + BOOST_CHECK_EQUAL(HexStr(script), HexStr(exp_payload)); + + // Try flipped case version + for (char& c : exp_base58string) { + if (c >= 'a' && c <= 'z') { + c = (c - 'a') + 'A'; + } else if (c >= 'A' && c <= 'Z') { + c = (c - 'A') + 'a'; + } + } + destination = DecodeDestination(exp_base58string); + BOOST_CHECK_MESSAGE(IsValidDestination(destination) == try_case_flip, "!IsValid case flipped:" + strTest); + if (IsValidDestination(destination)) { + script.SetDestination(destination); + BOOST_CHECK_EQUAL(HexStr(script), HexStr(exp_payload)); + } + + // Public key must be invalid private key + privkey = DecodeSecret(exp_base58string); + BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid pubkey as privkey:" + strTest); + } + } + + SelectParams(CBaseChainParams::MAIN); +} + +// Goal: check that generated keys match test vectors +BOOST_AUTO_TEST_CASE(key_io_valid_gen) +{ + UniValue tests = read_json(std::string(json_tests::key_io_valid, json_tests::key_io_valid + sizeof(json_tests::key_io_valid))); + + for (unsigned int idx = 0; idx < tests.size(); idx++) { + const UniValue& test = tests[idx]; + std::string strTest = test.write(); + if (test.size() < 3) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + std::string exp_base58string = test[0].get_str(); + std::vector exp_payload = ParseHex(test[1].get_str()); + const UniValue &metadata = test[2].get_obj(); + bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); + SelectParams(find_value(metadata, "chain").get_str()); + if (isPrivkey) { + bool isCompressed = find_value(metadata, "isCompressed").get_bool(); + CKey key; + key.Set(exp_payload.begin(), exp_payload.end(), isCompressed); + assert(key.IsValid()); + BOOST_CHECK_MESSAGE(EncodeSecret(key) == exp_base58string, "result mismatch: " + strTest); + } else { + CTxDestination dest; + CScript exp_script(exp_payload.begin(), exp_payload.end()); + BOOST_CHECK(ExtractDestination(exp_script, dest)); + std::string address = EncodeDestination(dest); + + BOOST_CHECK_EQUAL(address, exp_base58string); + } + } + + SelectParams(CBaseChainParams::MAIN); +} + + +// Goal: check that base58 parsing code is robust against a variety of corrupted data +BOOST_AUTO_TEST_CASE(key_io_invalid) +{ + UniValue tests = read_json(std::string(json_tests::key_io_invalid, json_tests::key_io_invalid + sizeof(json_tests::key_io_invalid))); // Negative testcases + CKey privkey; + CTxDestination destination; + + for (unsigned int idx = 0; idx < tests.size(); idx++) { + const UniValue& test = tests[idx]; + std::string strTest = test.write(); + if (test.size() < 1) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + std::string exp_base58string = test[0].get_str(); + + // must be invalid as public and as private key + for (const auto& chain : { CBaseChainParams::MAIN, CBaseChainParams::TESTNET }) { + SelectParams(chain); + destination = DecodeDestination(exp_base58string); + BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid pubkey in mainnet:" + strTest); + privkey = DecodeSecret(exp_base58string); + BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid privkey in mainnet:" + strTest); + } + } + + SelectParams(CBaseChainParams::MAIN); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 0ad8b9679b..30218872a0 100755 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -4,7 +4,7 @@ #include #include "key.h" -#include "base58.h" +#include #include "uint256.h" #include "util.h" @@ -15,10 +15,10 @@ static const std::string strSecret1 ("7NUfsJVtS5TruQrAFpni4yqqvoQg2fNk5JHRh1vsJP static const std::string strSecret2 ("7PiDb7gCaHw7P7Jfayc3d6BioSj8NyzxDzNb94vYe7gGYq2ytYF"); static const std::string strSecret1C("V7o8Z2EW1ghZGLFyrRvkGZtaxTqVGLNy7yHVyd6m1m45gzwsUEci"); static const std::string strSecret2C("VDEvZaU25wjqAapyJxqgaHtKVzYwa2ankLEHgcKLepUKd4F7czq6"); -static const CBitcoinAddress addr1 ("SMDEt5x56GHokFwbpaYLNykBo1JwA3tC4E"); -static const CBitcoinAddress addr2 ("SC3N7xZ7NnoshVxFhAM6eFWq4YCSGMKkzn"); -static const CBitcoinAddress addr1C("SKkhuYMjyZueN4wGpY6pMMW5soPiEDhXe8"); -static const CBitcoinAddress addr2C("S9P852TD2PFqh9otrRYUL7rTheRddigULh"); +static const std::string addr1 ("SMDEt5x56GHokFwbpaYLNykBo1JwA3tC4E"); +static const std::string addr2 ("SC3N7xZ7NnoshVxFhAM6eFWq4YCSGMKkzn"); +static const std::string addr1C("SKkhuYMjyZueN4wGpY6pMMW5soPiEDhXe8"); +static const std::string addr2C("S9P852TD2PFqh9otrRYUL7rTheRddigULh"); static const string strAddressBad("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF"); @@ -27,41 +27,26 @@ BOOST_AUTO_TEST_SUITE(key_tests) BOOST_AUTO_TEST_CASE(key_test1) { - CBitcoinSecret bsecret1, bsecret2, bsecret1C, bsecret2C, baddress1; - BOOST_CHECK( bsecret1.SetString (strSecret1)); - BOOST_CHECK( bsecret2.SetString (strSecret2)); - BOOST_CHECK( bsecret1C.SetString(strSecret1C)); - BOOST_CHECK( bsecret2C.SetString(strSecret2C)); - BOOST_CHECK(!baddress1.SetString(strAddressBad)); - - bool fCompressed; - CSecret secret1 = bsecret1.GetSecret (fCompressed); - BOOST_CHECK(fCompressed == false); - CSecret secret2 = bsecret2.GetSecret (fCompressed); - BOOST_CHECK(fCompressed == false); - CSecret secret1C = bsecret1C.GetSecret(fCompressed); - BOOST_CHECK(fCompressed == true); - CSecret secret2C = bsecret2C.GetSecret(fCompressed); - BOOST_CHECK(fCompressed == true); - - BOOST_CHECK(secret1 == secret1C); - BOOST_CHECK(secret2 == secret2C); - - CKey key1, key2, key1C, key2C; - key1.Set(secret1.begin(), secret1.end(), false); - key2.Set(secret2.begin(), secret2.end(), false); - key1C.Set(secret1.begin(), secret1.end(), true); - key2C.Set(secret2.begin(), secret2.end(), true); + CKey key1 = DecodeSecret(strSecret1); + BOOST_CHECK(key1.IsValid() && !key1.IsCompressed()); + CKey key2 = DecodeSecret(strSecret2); + BOOST_CHECK(key2.IsValid() && !key2.IsCompressed()); + CKey key1C = DecodeSecret(strSecret1C); + BOOST_CHECK(key1C.IsValid() && key1C.IsCompressed()); + CKey key2C = DecodeSecret(strSecret2C); + BOOST_CHECK(key2C.IsValid() && key2C.IsCompressed()); + CKey bad_key = DecodeSecret(strAddressBad); + BOOST_CHECK(!bad_key.IsValid()); CPubKey pubkey1 = key1. GetPubKey(); CPubKey pubkey2 = key2. GetPubKey(); CPubKey pubkey1C = key1C.GetPubKey(); CPubKey pubkey2C = key2C.GetPubKey(); - BOOST_CHECK(addr1.Get() == CTxDestination(key1.GetPubKey().GetID())); - BOOST_CHECK(addr2.Get() == CTxDestination(key2.GetPubKey().GetID())); - BOOST_CHECK(addr1C.Get() == CTxDestination(key1C.GetPubKey().GetID())); - BOOST_CHECK(addr2C.Get() == CTxDestination(key2C.GetPubKey().GetID())); + BOOST_CHECK(DecodeDestination(addr1) == CTxDestination(pubkey1.GetID())); + BOOST_CHECK(DecodeDestination(addr2) == CTxDestination(pubkey2.GetID())); + BOOST_CHECK(DecodeDestination(addr1C) == CTxDestination(pubkey1C.GetID())); + BOOST_CHECK(DecodeDestination(addr2C) == CTxDestination(pubkey2C.GetID())); for (int n=0; n<16; n++) { diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 5be3fd616f..6eb9c8a14c 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include @@ -38,18 +38,17 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig) const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; UniValue v; - CBitcoinAddress address; BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); - address.SetString(v.get_str()); - BOOST_CHECK(address.IsValid() && address.IsScript()); + CTxDestination address = DecodeDestination(v.get_str()); + BOOST_CHECK(std::holds_alternative(address)); BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false)); - address.SetString(v.get_str()); - BOOST_CHECK(address.IsValid() && address.IsScript()); + address = DecodeDestination(v.get_str()); + BOOST_CHECK(std::holds_alternative(address)); BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false)); - address.SetString(v.get_str()); - BOOST_CHECK(address.IsValid() && address.IsScript()); + address = DecodeDestination(v.get_str()); + BOOST_CHECK(std::holds_alternative(address)); BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error); BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error); diff --git a/src/validation.cpp b/src/validation.cpp index 5871f358d8..9fff54f614 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -227,7 +227,7 @@ CAmount GetValueIn(const CTransaction& tx, const MapPrevTx& inputs) bool HasMasterKeyInput(const CTransaction& tx, const MapPrevTx& inputs, int block_height) { - const CTxDestination master_address = CWallet::MasterAddress(block_height).Get(); + const CTxDestination master_address = CWallet::MasterAddress(block_height); for (const auto& input : tx.vin) { const CTxOut& prev_out = GetOutputFor(input, inputs); @@ -625,18 +625,18 @@ Fraction FoundationSideStakeAllocation() return Fraction(4, 5); } -CBitcoinAddress FoundationSideStakeAddress() { - CBitcoinAddress foundation_address; +CTxDestination FoundationSideStakeAddress() { + CTxDestination foundation_address; // If on testnet set foundation destination address to test wallet address if (fTestNet) { - foundation_address.SetString("mfiy9sc2QEZZCK3WMUMZjNfrdRA6gXzRhr"); + foundation_address = DecodeDestination("mfiy9sc2QEZZCK3WMUMZjNfrdRA6gXzRhr"); return foundation_address; } // Will get here if not on testnet. The below address is the current multisignature address for the foundation - foundation_address.SetString("bc3NA8e8E3EoTL1qhRmeprbjWcmuoZ26A2"); + foundation_address = DecodeDestination("bc3NA8e8E3EoTL1qhRmeprbjWcmuoZ26A2"); return foundation_address; } @@ -904,7 +904,7 @@ class ClaimValidator "actual_output = %" PRId64 ", required_output = %" PRId64, __func__, i, - CBitcoinAddress(output_destination).ToString(), + EncodeDestination(output_destination), actual_output, required_output); } @@ -980,7 +980,7 @@ class ClaimValidator } // The sidestake destination must match that specified by FoundationSideStakeAddress(). - if (foundation_sidestake_destination != FoundationSideStakeAddress().Get()) { + if (foundation_sidestake_destination != FoundationSideStakeAddress()) { error_out = "MRC Foundation sidestake destination is incorrect."; return error("%s: FAILED: foundation MRC sidestake destination does not match protocol", @@ -1352,9 +1352,9 @@ class ClaimValidator const GRC::BeaconOption beacon = GRC::GetBeaconRegistry().TryActive(*cpid, mrc_index->nTime); if (beacon) { - CBitcoinAddress beacon_address = beacon->GetAddress(); + CTxDestination beacon_address = beacon->GetAddress(); CScript script_beacon_key; - script_beacon_key.SetDestination(beacon_address.Get()); + script_beacon_key.SetDestination(beacon_address); // If an MRC fails validation no point in continuing. Return false immediately with an // appropriate DoS. @@ -1373,7 +1373,7 @@ class ClaimValidator CAmount coinstake_mrc_reward = 0; CScript mrc_beacon_script_public_key; - mrc_beacon_script_public_key.SetDestination(beacon->GetAddress().Get()); + mrc_beacon_script_public_key.SetDestination(beacon->GetAddress()); // Start at the first actual MRC output. The MRC outputs come last in the coinstake. // We must exclude the other outputs, because it is possible, and allowed, for a diff --git a/src/validation.h b/src/validation.h index 3564409a2e..c746e4e0b0 100644 --- a/src/validation.h +++ b/src/validation.h @@ -17,7 +17,6 @@ class CBlockHeader; namespace Consensus { struct Params; } -class CBitcoinAddress; namespace GRC { class MRC; } @@ -111,7 +110,7 @@ bool CheckBlockSignature(const CBlock& block); unsigned int GetCoinstakeOutputLimit(const int& block_version); unsigned int GetMandatorySideStakeOutputLimit(const int& block_version); Fraction FoundationSideStakeAllocation(); -CBitcoinAddress FoundationSideStakeAddress(); +CTxDestination FoundationSideStakeAddress(); unsigned int GetMRCOutputLimit(const int& block_version, bool include_foundation_sidestake); bool ValidateMRC(const GRC::Contract &contract, const CTransaction& tx, int& DoS); bool ValidateMRC(const CBlockIndex* mrc_last_pindex, const GRC::MRC& mrc); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index b229dc7880..8e8e85c216 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -9,7 +9,6 @@ #include "rpc/server.h" #include "rpc/protocol.h" #include "node/ui_interface.h" -#include "base58.h" #include #include @@ -123,19 +122,11 @@ UniValue importprivkey(const UniValue& params, bool fHelp) if (params.size() > 2) fRescan = params[2].get_bool(); - CBitcoinSecret vchSecret; - CKey key; + CKey key = DecodeSecret(strSecret); - if (!vchSecret.SetString(strSecret)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key."); - } - - bool fCompressed; - CSecret secret = vchSecret.GetSecret(fCompressed); - key.Set(secret.begin(), secret.end(), fCompressed); - - if (!key.IsValid()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key."); + if (!key.IsValid()) + { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); } if (fWalletUnlockStakingOnly) @@ -212,18 +203,15 @@ UniValue importwallet(const UniValue& params, bool fHelp) boost::split(vstr, line, boost::is_any_of(" ")); if (vstr.size() < 2) continue; - CBitcoinSecret vchSecret; - if (!vchSecret.SetString(vstr[0])) + + CKey key = DecodeSecret(vstr[0]); + if (!key.IsValid()) continue; - bool fCompressed; - CKey key; - CSecret secret = vchSecret.GetSecret(fCompressed); - key.Set(secret.begin(), secret.end(), fCompressed); CKeyID keyid = key.GetPubKey().GetID(); if (pwalletMain->HaveKey(keyid)) { - LogPrintf("Skipping import of %s (key already present)", CBitcoinAddress(keyid).ToString()); + LogPrintf("Skipping import of %s (key already present)", EncodeDestination(keyid)); continue; } int64_t nTime = DecodeDumpTime(vstr[1]); @@ -244,7 +232,7 @@ UniValue importwallet(const UniValue& params, bool fHelp) fLabel = true; } } - LogPrintf("Importing %s...", CBitcoinAddress(keyid).ToString()); + LogPrintf("Importing %s...", EncodeDestination(keyid)); if (!pwalletMain->AddKey(key)) { fGood = false; continue; @@ -293,38 +281,36 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); - string strAddress = params[0].get_str(); - CBitcoinAddress address; - if (!address.SetString(strAddress)) + CTxDestination address = DecodeDestination(params[0].get_str()); + if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin address"); if (fWalletUnlockStakingOnly) throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for staking only."); LOCK2(cs_main, pwalletMain->cs_wallet); - CKeyID keyID; - if (!address.GetKeyID(keyID)) + CKeyID* keyID = std::get_if(&address); + if (!keyID) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); - CSecret vchSecret; - bool fCompressed; - if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed)) - throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known"); + CKey vchSecret; + if (!pwalletMain->GetKey(*keyID, vchSecret)) + throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + params[0].get_str() + " is not known"); if (params.size() == 2 && params[1].isBool() && params[1].get_bool()) { CKey key_out; - pwalletMain->GetKey(keyID, key_out); + pwalletMain->GetKey(*keyID, key_out); UniValue result(UniValue::VOBJ); - result.pushKV("private_key", CBitcoinSecret(vchSecret, fCompressed).ToString()); + result.pushKV("private_key", EncodeSecret(vchSecret)); result.pushKV("private_key_hex", HexStr(key_out.GetPrivKey())); result.pushKV("public_key_hex", HexStr(key_out.GetPubKey())); return result; } - return CBitcoinSecret(vchSecret, fCompressed).ToString(); + return EncodeSecret(vchSecret); } UniValue dumpwallet(const UniValue& params, bool fHelp) @@ -393,12 +379,11 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) for (std::vector >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) { const CKeyID &keyid = it->second; std::string strTime = EncodeDumpTime(it->first); - std::string strAddr = CBitcoinAddress(keyid).ToString(); + std::string strAddr = EncodeDestination(keyid); CKey key; if (pwalletMain->GetKey(keyid, key)) { - CSecret secret(key.begin(), key.end()); - file << strprintf("%s %s ", CBitcoinSecret(secret, key.IsCompressed()).ToString(), strTime); + file << strprintf("%s %s ", EncodeSecret(key), strTime); if (pwalletMain->mapAddressBook.count(keyid)) { file << strprintf("label=%s", EncodeDumpString(pwalletMain->mapAddressBook[keyid])); } else if (keyid == masterKeyID) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 17b5b96fe4..75214478b2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3,12 +3,12 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or https://opensource.org/licenses/mit-license.php. +#include #include "version.h" #include "txdb.h" #include "rpc/server.h" #include "rpc/protocol.h" #include "init.h" -#include "base58.h" #include "streams.h" #include "util.h" #include "gridcoin/backup.h" @@ -228,11 +228,11 @@ UniValue getnewaddress(const UniValue& params, bool fHelp) pwalletMain->SetAddressBookName(keyID, strAccount); - return CBitcoinAddress(keyID).ToString(); + return EncodeDestination(keyID); } -CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) EXCLUSIVE_LOCKS_REQUIRED(pwalletMain->cs_wallet) +CTxDestination GetAccountAddress(string strAccount, bool bForceNew=false) EXCLUSIVE_LOCKS_REQUIRED(pwalletMain->cs_wallet) { CWalletDB walletdb(pwalletMain->strWalletFile); @@ -267,7 +267,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) EXCLU walletdb.WriteAccount(strAccount, account); } - return CBitcoinAddress(account.vchPubKey.GetID()); + return CTxDestination(account.vchPubKey.GetID()); } UniValue getaccountaddress(const UniValue& params, bool fHelp) @@ -285,7 +285,7 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - ret = GetAccountAddress(strAccount).ToString(); + ret = EncodeDestination(GetAccountAddress(strAccount)); return ret; } @@ -300,8 +300,8 @@ UniValue setaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); - if (!address.IsValid()) + CTxDestination address = DecodeDestination(params[0].get_str()); + if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin address"); string strAccount; @@ -309,14 +309,14 @@ UniValue setaccount(const UniValue& params, bool fHelp) strAccount = AccountFromValue(params[1]); // Detect when changing the account of an address that is the 'unused current key' of another account: - if (pwalletMain->mapAddressBook.count(address.Get())) + if (pwalletMain->mapAddressBook.count(address)) { - string strOldAccount = pwalletMain->mapAddressBook[address.Get()]; + string strOldAccount = pwalletMain->mapAddressBook[address]; if (address == GetAccountAddress(strOldAccount)) GetAccountAddress(strOldAccount, true); } - pwalletMain->SetAddressBookName(address.Get(), strAccount); + pwalletMain->SetAddressBookName(address, strAccount); return NullUniValue; } @@ -332,13 +332,13 @@ UniValue getaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); - if (!address.IsValid()) + CTxDestination address = DecodeDestination(params[0].get_str()); + if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin address"); string strAccount; - map::iterator mi = pwalletMain->mapAddressBook.find(address.Get()); + map::iterator mi = pwalletMain->mapAddressBook.find(address); if (mi != pwalletMain->mapAddressBook.end() && !mi->second.empty()) { strAccount = mi->second; } @@ -363,10 +363,10 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) for (auto const& item : pwalletMain->mapAddressBook) { - const CBitcoinAddress& address = item.first; + const CTxDestination& address = item.first; const string& strName = item.second; if (strName == strAccount) - ret.push_back(address.ToString()); + ret.push_back(EncodeDestination(address)); } return ret; } @@ -388,8 +388,8 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); - if (!address.IsValid()) + CTxDestination address = DecodeDestination(params[0].get_str()); + if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin address"); // Amount @@ -408,7 +408,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) if (pwalletMain->IsLocked()) throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); - string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); + string strError = pwalletMain->SendMoneyToDestination(address, nAmount, wtx); if (!strError.empty()) throw JSONRPCError(RPC_WALLET_ERROR, strError); @@ -435,11 +435,11 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp) for (auto const& address : grouping) { UniValue addressInfo(UniValue::VARR); - addressInfo.push_back(CBitcoinAddress(address).ToString()); + addressInfo.push_back(EncodeDestination(address)); addressInfo.push_back(ValueFromAmount(balances[address])); { - if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end()) - addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second); + if (pwalletMain->mapAddressBook.find(address) != pwalletMain->mapAddressBook.end()) + addressInfo.push_back(pwalletMain->mapAddressBook.find(address)->second); } jsonGrouping.push_back(addressInfo); } @@ -463,16 +463,16 @@ UniValue signmessage(const UniValue& params, bool fHelp) string strAddress = params[0].get_str(); string strMessage = params[1].get_str(); - CBitcoinAddress addr(strAddress); - if (!addr.IsValid()) + CTxDestination addr = DecodeDestination(strAddress); + if (!IsValidDestination(addr)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - CKeyID keyID; - if (!addr.GetKeyID(keyID)) + CKeyID* keyID = std::get_if(&addr); + if (!keyID) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); CKey key; - if (!pwalletMain->GetKey(keyID, key)) + if (!pwalletMain->GetKey(*keyID, key)) throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available"); CDataStream ss(SER_GETHASH, 0); @@ -500,12 +500,12 @@ UniValue verifymessage(const UniValue& params, bool fHelp) LOCK(cs_main); - CBitcoinAddress addr(strAddress); - if (!addr.IsValid()) + CTxDestination addr = DecodeDestination(strAddress); + if (!IsValidDestination(addr)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - CKeyID keyID; - if (!addr.GetKeyID(keyID)) + CKeyID* keyID = std::get_if(&addr); + if (!keyID) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); bool fInvalid = false; @@ -522,7 +522,7 @@ UniValue verifymessage(const UniValue& params, bool fHelp) if (!pubkey.RecoverCompact(Hash(ss), vchSig)) return false; - return pubkey.GetID() == keyID; + return pubkey.GetID() == *keyID; } @@ -537,11 +537,11 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); // Bitcoin address - CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); + CTxDestination address = DecodeDestination(params[0].get_str()); CScript scriptPubKey; - if (!address.IsValid()) + if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin address"); - scriptPubKey.SetDestination(address.Get()); + scriptPubKey.SetDestination(address); if (IsMine(*pwalletMain,scriptPubKey) == ISMINE_NO) return ValueFromAmount(0); @@ -805,8 +805,7 @@ UniValue getbalancedetail(const UniValue& params, bool fHelp) { std::string addressStr; - CBitcoinAddress addr; - addressStr = addr.Set(r.destination) ? addr.ToString() : std::string {}; + addressStr = IsValidDestination(r.destination) ? EncodeDestination(r.destination) : std::string {}; nBalance += r.amount; @@ -825,8 +824,7 @@ UniValue getbalancedetail(const UniValue& params, bool fHelp) { std::string addressStr; - CBitcoinAddress addr; - addressStr = addr.Set(s.destination) ? addr.ToString() : std::string {}; + addressStr = IsValidDestination(s.destination) ? EncodeDestination(s.destination) : std::string {}; nBalance -= s.amount; @@ -954,8 +952,8 @@ UniValue sendfrom(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[1].get_str()); - if (!address.IsValid()) + CTxDestination address = DecodeDestination(params[1].get_str()); + if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin address"); int64_t nAmount = AmountFromValue(params[2]); @@ -981,7 +979,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); // Send - string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); + string strError = pwalletMain->SendMoneyToDestination(address, nAmount, wtx); if (!strError.empty()) throw JSONRPCError(RPC_WALLET_ERROR, strError); @@ -1020,15 +1018,15 @@ UniValue sendmany(const UniValue& params, bool fHelp) if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); - set setAddress; + set setAddress; vector > vecSend; vector addrList = sendTo.getKeys(); int64_t totalAmount = 0; for (auto const& name_: addrList) { - CBitcoinAddress address(name_); - if (!address.IsValid()) + CTxDestination address = DecodeDestination(name_); + if (!IsValidDestination(address)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Gridcoin address: ")+name_); if (setAddress.count(address)) @@ -1036,7 +1034,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) setAddress.insert(address); CScript scriptPubKey; - scriptPubKey.SetDestination(address.Get()); + scriptPubKey.SetDestination(address); int64_t nAmount = AmountFromValue(sendTo[name_]); totalAmount += nAmount; @@ -1136,15 +1134,15 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp) const std::string& ks = keys[i].get_str(); // Case 1: Bitcoin address and we have full public key: - CBitcoinAddress address(ks); - if (address.IsValid()) + CTxDestination address = DecodeDestination(ks); + if (IsValidDestination(address)) { - CKeyID keyID; - if (!address.GetKeyID(keyID)) + CKeyID* keyID = std::get_if(&address); + if (!keyID) throw runtime_error( strprintf("%s does not refer to a key",ks)); CPubKey vchPubKey; - if (!pwalletMain->GetPubKey(keyID, vchPubKey)) + if (!pwalletMain->GetPubKey(*keyID, vchPubKey)) throw runtime_error( strprintf("no full public key for address %s",ks)); if (!vchPubKey.IsValid()) @@ -1174,7 +1172,7 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp) throw runtime_error("AddCScript() failed"); pwalletMain->SetAddressBookName(innerID, strAccount); - return CBitcoinAddress(innerID).ToString(); + return EncodeDestination(innerID); } UniValue addredeemscript(const UniValue& params, bool fHelp) @@ -1202,7 +1200,7 @@ UniValue addredeemscript(const UniValue& params, bool fHelp) throw runtime_error("AddCScript() failed"); pwalletMain->SetAddressBookName(innerID, strAccount); - return CBitcoinAddress(innerID).ToString(); + return EncodeDestination(innerID); } struct tallyitem @@ -1238,7 +1236,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) EXCLUSIVE_LOCKS_ fIncludeEmpty = params[1].get_bool(); // Tally - map mapTally; + map mapTally; for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = it->second; @@ -1276,9 +1274,9 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) EXCLUSIVE_LOCKS_ for (auto const& item : pwalletMain->mapAddressBook) { - const CBitcoinAddress& address = item.first; + const CTxDestination& address = item.first; const string& strAccount = item.second; - map::iterator it = mapTally.find(address); + map::iterator it = mapTally.find(address); if (it == mapTally.end() && !fIncludeEmpty) continue; @@ -1306,7 +1304,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) EXCLUSIVE_LOCKS_ if (fIsWatchonly) { obj.pushKV("involvesWatchonly", true); } - obj.pushKV("address", address.ToString()); + obj.pushKV("address", EncodeDestination(address)); obj.pushKV("account", strAccount); obj.pushKV("amount", ValueFromAmount(nAmount)); obj.pushKV("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf)); @@ -1419,8 +1417,7 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) std::string addressStr; - CBitcoinAddress addr; - addressStr = addr.Set(s.destination) ? addr.ToString() : std::string {}; + addressStr = IsValidDestination(s.destination) ? EncodeDestination(s.destination) : std::string {}; entry.pushKV("address", addressStr); @@ -1480,8 +1477,7 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) std::string addressStr; - CBitcoinAddress addr; - addressStr = addr.Set(r.destination) ? addr.ToString() : std::string {}; + addressStr = IsValidDestination(r.destination) ? EncodeDestination(r.destination) : std::string {}; entry.pushKV("address", addressStr); @@ -2438,7 +2434,7 @@ class DescribeAddressVisitor obj.pushKV("hex", HexStr(subscript)); UniValue a(UniValue::VARR); for (auto const& addr : addresses) - a.push_back(CBitcoinAddress(addr).ToString()); + a.push_back(EncodeDestination(addr)); obj.pushKV("addresses", a); if (whichType == TX_MULTISIG) obj.pushKV("sigsrequired", nRequired); @@ -2456,15 +2452,14 @@ UniValue validateaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); - bool isValid = address.IsValid(); + CTxDestination dest = DecodeDestination(params[0].get_str()); + bool isValid = IsValidDestination(dest); UniValue ret(UniValue::VOBJ); ret.pushKV("isvalid", isValid); if (isValid) { - CTxDestination dest = address.Get(); - string currentAddress = address.ToString(); + string currentAddress = EncodeDestination(dest); ret.pushKV("address", currentAddress); bool fMine = IsMine(*pwalletMain, dest) != ISMINE_NO; ret.pushKV("ismine", fMine); @@ -2474,11 +2469,11 @@ UniValue validateaddress(const UniValue& params, bool fHelp) } if (pwalletMain->mapAddressBook.count(dest)) ret.pushKV("account", pwalletMain->mapAddressBook[dest]); - CKeyID keyID; - if (pwalletMain && address.GetKeyID(keyID) && pwalletMain->mapKeyMetadata.count(keyID) && !pwalletMain->mapKeyMetadata[keyID].hdKeypath.empty()) + CKeyID* keyID = std::get_if(&dest); + if (pwalletMain && keyID && pwalletMain->mapKeyMetadata.count(*keyID) && !pwalletMain->mapKeyMetadata[*keyID].hdKeypath.empty()) { - ret.pushKV("hdkeypath", pwalletMain->mapKeyMetadata[keyID].hdKeypath); - ret.pushKV("hdmasterkeyid", pwalletMain->mapKeyMetadata[keyID].hdMasterKeyID.GetHex()); + ret.pushKV("hdkeypath", pwalletMain->mapKeyMetadata[*keyID].hdKeypath); + ret.pushKV("hdmasterkeyid", pwalletMain->mapKeyMetadata[*keyID].hdMasterKeyID.GetHex()); } } return ret; @@ -2502,15 +2497,14 @@ UniValue validatepubkey(const UniValue& params, bool fHelp) bool isCompressed = pubKey.IsCompressed(); CKeyID keyID = pubKey.GetID(); - CBitcoinAddress address; - address.Set(keyID); + CTxDestination address(keyID); UniValue ret(UniValue::VOBJ); ret.pushKV("isvalid", isValid); if (isValid) { - CTxDestination dest = address.Get(); - string currentAddress = address.ToString(); + CTxDestination dest = address; + string currentAddress = EncodeDestination(address); ret.pushKV("address", currentAddress); bool fMine = IsMine(*pwalletMain, dest) != ISMINE_NO; ret.pushKV("ismine", fMine); @@ -2724,16 +2718,7 @@ UniValue sethdseed(const UniValue& params, bool fHelp) if (params[1].isNull()) { master_pub_key = pwalletMain->GenerateNewHDMasterKey(); } else { - CKey key; - CBitcoinSecret vchSecret; - - if (!vchSecret.SetString(params[1].get_str())) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); - } - - bool fCompressed; - CSecret secret = vchSecret.GetSecret(fCompressed); - key.Set(secret.begin(), secret.end(), fCompressed); + CKey key = DecodeSecret(params[1].get_str()); if (!key.IsValid()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index df01975f35..504532c160 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4,12 +4,12 @@ // file COPYING or https://opensource.org/licenses/mit-license.php. #include "chainparams.h" +#include #include "txdb.h" #include "wallet/wallet.h" #include "wallet/walletdb.h" #include "crypter.h" #include "node/ui_interface.h" -#include "base58.h" #include "wallet/coincontrol.h" #include #include @@ -55,12 +55,9 @@ struct CompareValueOnly // Class: CWallet // ----------------------------------------------------------------------------- -const CBitcoinAddress CWallet::MasterAddress(int height) +const CTxDestination CWallet::MasterAddress(int height) { - CBitcoinAddress master_address; - master_address.Set(CPubKey(Params().MasterKey(height)).GetID()); - - return master_address; + return CPubKey(Params().MasterKey(height)).GetID(); } CKey CWallet::MasterPrivateKey(int height) const @@ -208,7 +205,7 @@ bool CWallet::LoadCScript(const CScript& redeemScript) * these. Do not add them to the wallet and warn. */ if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE) { - std::string strAddr = CBitcoinAddress(redeemScript.GetID()).ToString(); + std::string strAddr = EncodeDestination(redeemScript.GetID()); LogPrintf("%s: Warning: This wallet contains a redeemScript of size %" PRIszu " which exceeds maximum size %i thus can never be redeemed. Do not use address %s.", __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr); return true; @@ -2136,7 +2133,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, // coin control: send change to custom address if (coinControl && !std::get_if(&coinControl->destChange)) { LogPrintf("INFO: %s: Setting custom change address: %s", __func__, - CBitcoinAddress(coinControl->destChange).ToString()); + EncodeDestination(coinControl->destChange)); scriptChange.SetDestination(coinControl->destChange); } else { // no coin control @@ -2155,7 +2152,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, } LogPrintf("INFO: %s: Sending change to input address %s", __func__, - CBitcoinAddress(change_address).ToString()); + EncodeDestination(change_address)); } } else { // send change to newly generated address // Note: We use a new key here to keep it from being obvious which side is the change. @@ -2469,7 +2466,7 @@ bool CWallet::SetAddressBookName(const CTxDestination& address, const string& st (fUpdated ? CT_UPDATED : CT_NEW) ); if (!fFileBacked) return false; - return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName); + return CWalletDB(strWalletFile).WriteName(EncodeDestination(address), strName); } bool CWallet::DelAddressBookName(const CTxDestination& address) @@ -2484,7 +2481,7 @@ bool CWallet::DelAddressBookName(const CTxDestination& address) if (!fFileBacked) return false; - return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString()); + return CWalletDB(strWalletFile).EraseName(EncodeDestination(address)); } @@ -2966,77 +2963,6 @@ void CWallet::GetAllReserveKeys(set& setAddress) const } } -std::vector> CWallet::GetAllPrivateKeys(std::string& sError) const -{ - CWalletDB walletdb(strWalletFile); - - LOCK2(cs_main, cs_wallet); - - std::vector> res; - // Get Private Keys from mapAddressBook - for (auto const& item : mapAddressBook) - { - const CBitcoinAddress& address = item.first; - isminetype fMine = ::IsMine(*this, address.Get()); - if (fMine != ISMINE_NO) - { - CKeyID keyID; - if (!address.GetKeyID(keyID)) - { - LogPrintf("GetAllPrivateKeys: During private key backup, Address %s does not refer to a key", address.ToString()); - } - else - { - CKey vchSecret; - if (!GetKey(keyID, vchSecret)) - { - LogPrintf("GetAllPrivateKeys: During private key backup, Private key for address %s is not known", address.ToString()); - } - else - { - CSecret secret(vchSecret.begin(), vchSecret.end()); - CBitcoinSecret privateKey(secret, vchSecret.IsCompressed()); - res.push_back(std::make_pair(address, privateKey)); - } - } - } - } - // Get Private Keys from KeyPool - for (auto const& id : setKeyPool) - { - CKeyPool keypool; - if (!walletdb.ReadPool(id, keypool)) - { - // Important to know. - sError = "GetAllPrivateKeys: Failed to read pool"; - } - assert(keypool.vchPubKey.IsValid()); - CKeyID keyID = keypool.vchPubKey.GetID(); - - if (!HaveKey(keyID)) - { - LogPrintf("GetAllPrivateKeys: Unknown key in key pool"); - } - else - { - CKey vchSecret; - //CSecret vchSecret; - if (!GetKey(keyID, vchSecret)) - { - LogPrintf("GetAllPrivateKeys: During Private Key Backup, Private key for address %s is not known", keyID.ToString()); - } - else - { - CSecret secret(vchSecret.begin(), vchSecret.end()); - CBitcoinAddress address(keyID); - CBitcoinSecret privateKey(secret, vchSecret.IsCompressed()); - res.push_back(std::make_pair(address, privateKey)); - } - } - } - return res; -} - void CWallet::UpdatedTransaction(const uint256 &hashTx) { { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index beed549c93..5bf9f9dcef 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -135,7 +135,7 @@ class CWallet : public CCryptoKeyStore //! //! \return Address as calculated from the master public key. //! - static const CBitcoinAddress MasterAddress(int height); + static const CTxDestination MasterAddress(int height); //! //! \brief Get the imported master private key used to sign administrative @@ -286,7 +286,6 @@ class CWallet : public CCryptoKeyStore bool GetKeyFromPool(CPubKey &key, bool fAllowReuse=true); int64_t GetOldestKeyPoolTime(); void GetAllReserveKeys(std::set& setAddress) const; - std::vector> GetAllPrivateKeys(std::string& sError) const; std::set< std::set > GetAddressGroupings(); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 305b412b4e..a1af5ad9de 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -227,7 +227,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, { string strAddress; ssKey >> strAddress; - ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()]; + ssValue >> pwallet->mapAddressBook[DecodeDestination(strAddress)]; } else if (strType == "tx") { diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 3e35ccf163..dd48d6129b 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -7,7 +7,7 @@ #define BITCOIN_WALLET_WALLETDB_H #include "wallet/db.h" -#include "base58.h" +#include class CKeyPool; class CAccount;