Introduce wrappers around CBitcoinAddress

This patch removes the need for the intermediary Base58 type
CBitcoinAddress, by providing {Encode,Decode,IsValid}Destination
function that directly operate on the conversion between strings
and CTxDestination.
This commit is contained in:
Pieter Wuille
2017-08-22 18:02:33 -07:00
committed by Jack Grigg
parent 90304c4214
commit 07444da1db
14 changed files with 225 additions and 186 deletions

View File

@@ -175,9 +175,9 @@ UniValue importaddress(const UniValue& params, bool fHelp)
CScript script;
CBitcoinAddress address(params[0].get_str());
if (address.IsValid()) {
script = GetScriptForDestination(address.Get());
CTxDestination dest = DecodeDestination(params[0].get_str());
if (IsValidDestination(dest)) {
script = GetScriptForDestination(dest);
} else if (IsHex(params[0].get_str())) {
std::vector<unsigned char> data(ParseHex(params[0].get_str()));
script = CScript(data.begin(), data.end());
@@ -199,8 +199,8 @@ UniValue importaddress(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
// add to address book or update label
if (address.IsValid())
pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
if (IsValidDestination(dest))
pwalletMain->SetAddressBook(dest, strLabel, "receive");
// Don't throw error in case an address is already there
if (pwalletMain->HaveWatchOnly(script))
@@ -333,7 +333,7 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
assert(key.VerifyPubKey(pubkey));
CKeyID keyid = pubkey.GetID();
if (pwalletMain->HaveKey(keyid)) {
LogPrintf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString());
LogPrintf("Skipping import of %s (key already present)\n", EncodeDestination(keyid));
continue;
}
int64_t nTime = DecodeDumpTime(vstr[1]);
@@ -351,7 +351,7 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
fLabel = true;
}
}
LogPrintf("Importing %s...\n", CBitcoinAddress(keyid).ToString());
LogPrintf("Importing %s...\n", EncodeDestination(keyid));
if (!pwalletMain->AddKeyPubKey(key, pubkey)) {
fGood = false;
continue;
@@ -405,16 +405,19 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp)
EnsureWalletIsUnlocked();
string strAddress = params[0].get_str();
CBitcoinAddress address;
if (!address.SetString(strAddress))
std::string strAddress = params[0].get_str();
CTxDestination dest = DecodeDestination(strAddress);
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
CKeyID keyID;
if (!address.GetKeyID(keyID))
}
const CKeyID *keyID = boost::get<CKeyID>(&dest);
if (!keyID) {
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
}
CKey vchSecret;
if (!pwalletMain->GetKey(keyID, vchSecret))
if (!pwalletMain->GetKey(*keyID, vchSecret)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
}
return CBitcoinSecret(vchSecret).ToString();
}
@@ -515,7 +518,7 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys)
for (std::vector<std::pair<int64_t, CKeyID> >::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)) {
if (pwalletMain->mapAddressBook.count(keyid)) {

View File

@@ -146,11 +146,11 @@ UniValue getnewaddress(const UniValue& params, bool fHelp)
pwalletMain->SetAddressBook(keyID, strAccount, "receive");
return CBitcoinAddress(keyID).ToString();
return EncodeDestination(keyID);
}
CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
CTxDestination GetAccountAddress(std::string strAccount, bool bForceNew=false)
{
CWalletDB walletdb(pwalletMain->strWalletFile);
@@ -184,7 +184,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
walletdb.WriteAccount(strAccount, account);
}
return CBitcoinAddress(account.vchPubKey.GetID());
return account.vchPubKey.GetID();
}
UniValue getaccountaddress(const UniValue& params, bool fHelp)
@@ -214,7 +214,7 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp)
UniValue ret(UniValue::VSTR);
ret = GetAccountAddress(strAccount).ToString();
ret = EncodeDestination(GetAccountAddress(strAccount));
return ret;
}
@@ -250,7 +250,7 @@ UniValue getrawchangeaddress(const UniValue& params, bool fHelp)
CKeyID keyID = vchPubKey.GetID();
return CBitcoinAddress(keyID).ToString();
return EncodeDestination(keyID);
}
@@ -273,25 +273,25 @@ UniValue setaccount(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
CTxDestination dest = DecodeDestination(params[0].get_str());
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
}
string strAccount;
if (params.size() > 1)
strAccount = AccountFromValue(params[1]);
// Only add the account if the address is yours.
if (IsMine(*pwalletMain, address.Get()))
{
if (IsMine(*pwalletMain, dest)) {
// Detect when changing the account of an address that is the 'unused current key' of another account:
if (pwalletMain->mapAddressBook.count(address.Get()))
{
string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name;
if (address == GetAccountAddress(strOldAccount))
if (pwalletMain->mapAddressBook.count(dest)) {
std::string strOldAccount = pwalletMain->mapAddressBook[dest].name;
if (dest == GetAccountAddress(strOldAccount)) {
GetAccountAddress(strOldAccount, true);
}
}
pwalletMain->SetAddressBook(address.Get(), strAccount, "receive");
pwalletMain->SetAddressBook(dest, strAccount, "receive");
}
else
throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
@@ -320,14 +320,16 @@ UniValue getaccount(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
CTxDestination dest = DecodeDestination(params[0].get_str());
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
}
string strAccount;
map<CTxDestination, CAddressBookData>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty())
std::string strAccount;
std::map<CTxDestination, CAddressBookData>::iterator mi = pwalletMain->mapAddressBook.find(dest);
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty()) {
strAccount = (*mi).second.name;
}
return strAccount;
}
@@ -359,12 +361,12 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp)
// Find all addresses that have the given account
UniValue ret(UniValue::VARR);
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook)
{
const CBitcoinAddress& address = item.first;
const string& strName = item.second.name;
if (strName == strAccount)
ret.push_back(address.ToString());
for (const std::pair<CTxDestination, CAddressBookData>& item : pwalletMain->mapAddressBook) {
const CTxDestination& dest = item.first;
const std::string& strName = item.second.name;
if (strName == strAccount) {
ret.push_back(EncodeDestination(dest));
}
}
return ret;
}
@@ -431,9 +433,10 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
CTxDestination dest = DecodeDestination(params[0].get_str());
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
}
// Amount
CAmount nAmount = AmountFromValue(params[1]);
@@ -453,7 +456,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp)
EnsureWalletIsUnlocked();
SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx);
SendMoney(dest, nAmount, fSubtractFeeFromAmount, wtx);
return wtx.GetHash().GetHex();
}
@@ -489,18 +492,18 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
UniValue jsonGroupings(UniValue::VARR);
map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances();
BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
{
std::map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances();
for (const std::set<CTxDestination>& grouping : pwalletMain->GetAddressGroupings()) {
UniValue jsonGrouping(UniValue::VARR);
BOOST_FOREACH(CTxDestination address, grouping)
for (const CTxDestination& 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.name);
if (pwalletMain->mapAddressBook.find(address) != pwalletMain->mapAddressBook.end()) {
addressInfo.push_back(pwalletMain->mapAddressBook.find(address)->second.name);
}
}
jsonGrouping.push_back(addressInfo);
}
@@ -542,17 +545,20 @@ 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 dest = DecodeDestination(strAddress);
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
}
CKeyID keyID;
if (!addr.GetKeyID(keyID))
const CKeyID *keyID = boost::get<CKeyID>(&dest);
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");
}
CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
@@ -593,12 +599,14 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
// Bitcoin address
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
if (!address.IsValid())
CTxDestination dest = DecodeDestination(params[0].get_str());
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
CScript scriptPubKey = GetScriptForDestination(address.Get());
if (!IsMine(*pwalletMain, scriptPubKey))
}
CScript scriptPubKey = GetScriptForDestination(dest);
if (!IsMine(*pwalletMain, scriptPubKey)) {
return ValueFromAmount(0);
}
// Minimum confirmations
int nMinDepth = 1;
@@ -907,10 +915,11 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
string strAccount = AccountFromValue(params[0]);
CBitcoinAddress address(params[1].get_str());
if (!address.IsValid())
std::string strAccount = AccountFromValue(params[0]);
CTxDestination dest = DecodeDestination(params[1].get_str());
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
}
CAmount nAmount = AmountFromValue(params[2]);
if (nAmount <= 0)
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
@@ -932,7 +941,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
if (nAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
SendMoney(address.Get(), nAmount, false, wtx);
SendMoney(dest, nAmount, false, wtx);
return wtx.GetHash().GetHex();
}
@@ -996,22 +1005,23 @@ UniValue sendmany(const UniValue& params, bool fHelp)
if (params.size() > 4)
subtractFeeFromAmount = params[4].get_array();
set<CBitcoinAddress> setAddress;
vector<CRecipient> vecSend;
std::set<CTxDestination> destinations;
std::vector<CRecipient> vecSend;
CAmount totalAmount = 0;
vector<string> keys = sendTo.getKeys();
BOOST_FOREACH(const string& name_, keys)
{
CBitcoinAddress address(name_);
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zcash address: ")+name_);
std::vector<std::string> keys = sendTo.getKeys();
for (const std::string& name_ : keys) {
CTxDestination dest = DecodeDestination(name_);
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + name_);
}
if (setAddress.count(address))
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
setAddress.insert(address);
if (destinations.count(dest)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
}
destinations.insert(dest);
CScript scriptPubKey = GetScriptForDestination(address.Get());
CScript scriptPubKey = GetScriptForDestination(dest);
CAmount nAmount = AmountFromValue(sendTo[name_]);
if (nAmount <= 0)
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
@@ -1097,7 +1107,7 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp)
pwalletMain->AddCScript(inner);
pwalletMain->SetAddressBook(innerID, strAccount, "send");
return CBitcoinAddress(innerID).ToString();
return EncodeDestination(innerID);
}
@@ -1133,10 +1143,9 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
filter = filter | ISMINE_WATCH_ONLY;
// Tally
map<CBitcoinAddress, tallyitem> mapTally;
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
const CWalletTx& wtx = (*it).second;
std::map<CTxDestination, tallyitem> mapTally;
for (const std::pair<uint256, CWalletTx>& pairWtx : pwalletMain->mapWallet) {
const CWalletTx& wtx = pairWtx.second;
if (wtx.IsCoinBase() || !CheckFinalTx(wtx))
continue;
@@ -1166,12 +1175,11 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
// Reply
UniValue ret(UniValue::VARR);
map<string, tallyitem> mapAccountTally;
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook)
{
const CBitcoinAddress& address = item.first;
const string& strAccount = item.second.name;
map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
std::map<std::string, tallyitem> mapAccountTally;
for (const std::pair<CTxDestination, CAddressBookData>& item : pwalletMain->mapAddressBook) {
const CTxDestination& dest = item.first;
const std::string& strAccount = item.second.name;
std::map<CTxDestination, tallyitem>::iterator it = mapTally.find(dest);
if (it == mapTally.end() && !fIncludeEmpty)
continue;
@@ -1197,7 +1205,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
UniValue obj(UniValue::VOBJ);
if(fIsWatchonly)
obj.push_back(Pair("involvesWatchonly", true));
obj.push_back(Pair("address", address.ToString()));
obj.push_back(Pair("address", EncodeDestination(dest)));
obj.push_back(Pair("account", strAccount));
obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
@@ -1308,9 +1316,9 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp)
static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
{
CBitcoinAddress addr;
if (addr.Set(dest))
entry.push_back(Pair("address", addr.ToString()));
if (IsValidDestination(dest)) {
entry.push_back(Pair("address", EncodeDestination(dest)));
}
}
void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
@@ -2367,17 +2375,18 @@ UniValue listunspent(const UniValue& params, bool fHelp)
if (params.size() > 1)
nMaxDepth = params[1].get_int();
set<CBitcoinAddress> setAddress;
std::set<CTxDestination> destinations;
if (params.size() > 2) {
UniValue inputs = params[2].get_array();
for (size_t idx = 0; idx < inputs.size(); idx++) {
const UniValue& input = inputs[idx];
CBitcoinAddress address(input.get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zcash address: ")+input.get_str());
if (setAddress.count(address))
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str());
setAddress.insert(address);
CTxDestination dest = DecodeDestination(input.get_str());
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + input.get_str());
}
if (!destinations.insert(dest).second) {
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + input.get_str());
}
}
}
@@ -2394,7 +2403,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
const CScript& scriptPubKey = out.tx->vout[out.i].scriptPubKey;
bool fValidAddress = ExtractDestination(scriptPubKey, address);
if (setAddress.size() && (!fValidAddress || !setAddress.count(address)))
if (destinations.size() && (!fValidAddress || !destinations.count(address)))
continue;
UniValue entry(UniValue::VOBJ);
@@ -2403,7 +2412,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
entry.push_back(Pair("generated", out.tx->IsCoinBase()));
if (fValidAddress) {
entry.push_back(Pair("address", CBitcoinAddress(address).ToString()));
entry.push_back(Pair("address", EncodeDestination(address)));
if (pwalletMain->mapAddressBook.count(address))
entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name));

View File

@@ -300,7 +300,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(CScriptID(redeemScript)).ToString();
std::string strAddr = EncodeDestination(CScriptID(redeemScript));
LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n",
__func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
return true;
@@ -3018,9 +3018,9 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam
strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
if (!fFileBacked)
return false;
if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(EncodeDestination(address), strPurpose))
return false;
return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
return CWalletDB(strWalletFile).WriteName(EncodeDestination(address), strName);
}
bool CWallet::DelAddressBook(const CTxDestination& address)
@@ -3031,7 +3031,7 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
if(fFileBacked)
{
// Delete destdata tuples associated with address
std::string strAddress = CBitcoinAddress(address).ToString();
std::string strAddress = EncodeDestination(address);
BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
{
CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
@@ -3044,8 +3044,8 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
if (!fFileBacked)
return false;
CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
CWalletDB(strWalletFile).ErasePurpose(EncodeDestination(address));
return CWalletDB(strWalletFile).EraseName(EncodeDestination(address));
}
bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
@@ -3573,7 +3573,7 @@ bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, co
mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
if (!fFileBacked)
return true;
return CWalletDB(strWalletFile).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
return CWalletDB(strWalletFile).WriteDestData(EncodeDestination(dest), key, value);
}
bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
@@ -3582,7 +3582,7 @@ bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
return false;
if (!fFileBacked)
return true;
return CWalletDB(strWalletFile).EraseDestData(CBitcoinAddress(dest).ToString(), key);
return CWalletDB(strWalletFile).EraseDestData(EncodeDestination(dest), key);
}
bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)

View File

@@ -409,13 +409,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
{
string strAddress;
ssKey >> strAddress;
ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()].name;
ssValue >> pwallet->mapAddressBook[DecodeDestination(strAddress)].name;
}
else if (strType == "purpose")
{
string strAddress;
ssKey >> strAddress;
ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()].purpose;
ssValue >> pwallet->mapAddressBook[DecodeDestination(strAddress)].purpose;
}
else if (strType == "tx")
{
@@ -698,7 +698,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
ssKey >> strAddress;
ssKey >> strKey;
ssValue >> strValue;
if (!pwallet->LoadDestData(CBitcoinAddress(strAddress).Get(), strKey, strValue))
if (!pwallet->LoadDestData(DecodeDestination(strAddress), strKey, strValue))
{
strErr = "Error reading wallet database: LoadDestData failed";
return false;