Keep address labels for pubkey pair addresses.
authorCryptoManiac <balthazar@yandex.ru>
Fri, 11 Mar 2016 17:10:20 +0000 (20:10 +0300)
committerCryptoManiac <balthazar@yandex.ru>
Fri, 11 Mar 2016 17:10:20 +0000 (20:10 +0300)
16 files changed:
src/base58.cpp
src/base58.h
src/init.cpp
src/qt/addresstablemodel.cpp
src/qt/coincontroldialog.cpp
src/qt/multisigdialog.cpp
src/qt/transactiondesc.cpp
src/qt/transactionrecord.cpp
src/qt/walletmodel.cpp
src/rpcdump.cpp
src/rpcwallet.cpp
src/script.cpp
src/script.h
src/wallet.cpp
src/wallet.h
src/walletdb.cpp

index 2691ea4..1c26380 100644 (file)
@@ -254,6 +254,13 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe
         return true;
     }
 
+    bool CBitcoinAddress::Set(const CBitcoinAddress &dest)
+    {
+        nVersion = dest.nVersion;
+        vchData = dest.vchData;
+        return true;
+    }
+
     bool CBitcoinAddress::IsValid() const
     {
         unsigned int nExpectedSize = 20;
index 2b6e326..0ca0fda 100644 (file)
@@ -115,6 +115,7 @@ public:
     bool Set(const CScriptID &id);
     bool Set(const CTxDestination &dest);
     bool Set(const CMalleablePubKey &mpk);
+    bool Set(const CBitcoinAddress &dest);
     bool IsValid() const;
 
     CBitcoinAddress()
index 417b342..2f237c0 100644 (file)
@@ -900,7 +900,7 @@ bool AppInit2()
         if (!pwalletMain->GetKeyFromPool(newDefaultKey, false))
             strErrors << _("Cannot initialize keypool") << "\n";
         pwalletMain->SetDefaultKey(newDefaultKey);
-        if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), ""))
+        if (!pwalletMain->SetAddressBookName(CBitcoinAddress(pwalletMain->vchDefaultKey.GetID()), ""))
             strErrors << _("Cannot write default address") << "\n";
     }
 
index 03b09cd..a5dc784 100644 (file)
@@ -59,11 +59,11 @@ public:
         cachedAddressTable.clear();
         {
             LOCK(wallet->cs_wallet);
-            BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& item, wallet->mapAddressBook)
+            BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook)
             {
                 const CBitcoinAddress& address = item.first;
                 const std::string& strName = item.second;
-                bool fMine = IsMine(*wallet, address.Get());
+                bool fMine = IsMine(*wallet, address);
                 cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending,
                                   QString::fromStdString(strName),
                                   QString::fromStdString(address.ToString())));
@@ -229,7 +229,7 @@ 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(CBitcoinAddress(rec->address.toStdString()), value.toString().toStdString());
             break;
         case Address:
             // Do nothing, if old address == new address
@@ -246,7 +246,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value,
             }
             // Check for duplicate addresses to prevent accidental deletion of addresses, if you try
             // to paste an existing address over another address (with a different label)
-            else if(wallet->mapAddressBook.count(CBitcoinAddress(value.toString().toStdString()).Get()))
+            else if(wallet->mapAddressBook.count(CBitcoinAddress(value.toString().toStdString())))
             {
                 editStatus = DUPLICATE_ADDRESS;
                 return false;
@@ -257,9 +257,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(CBitcoinAddress(rec->address.toStdString()));
                     // Add new entry with new address
-                    wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()).Get(), rec->label.toStdString());
+                    wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()), rec->label.toStdString());
                 }
             }
             break;
@@ -335,7 +335,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(CBitcoinAddress(strAddress)))
             {
                 editStatus = DUPLICATE_ADDRESS;
                 return QString();
@@ -368,7 +368,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(CBitcoinAddress(strAddress), strLabel);
     }
     return QString::fromStdString(strAddress);
 }
@@ -385,7 +385,7 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex &parent
     }
     {
         LOCK(wallet->cs_wallet);
-        wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get());
+        wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()));
     }
     return true;
 }
@@ -397,7 +397,7 @@ QString AddressTableModel::labelForAddress(const QString &address) const
     {
         LOCK(wallet->cs_wallet);
         CBitcoinAddress address_parsed(address.toStdString());
-        std::map<CTxDestination, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed.Get());
+        std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed);
         if (mi != wallet->mapAddressBook.end())
         {
             return QString::fromStdString(mi->second);
index 9ea82a4..7b7472b 100644 (file)
@@ -4,7 +4,7 @@
 #include "init.h"
 #include "base58.h"
 #include "bitcoinunits.h"
-#include "wallet.h"
+#include "script.h"
 #include "walletmodel.h"
 #include "addresstablemodel.h"
 #include "optionsmodel.h"
@@ -471,16 +471,15 @@ void CoinControlDialog::updateLabels(WalletModel *model, QWidget* dialog)
 
         // Bytes
         CBitcoinAddress address;
-        if(pwalletMain->ExtractAddress(out.tx->vout[out.i].scriptPubKey, address))
+        if(ExtractAddress(*pwalletMain, out.tx->vout[out.i].scriptPubKey, address))
         {
             if (address.IsPair())
                 nBytesInputs += 213;
             else if (address.IsPubKey())
             {
                 CPubKey pubkey;
-                CTxDestination dest = address.Get();
-                CKeyID *keyid = boost::get< CKeyID >(&dest);
-                if (keyid && model->getPubKey(*keyid, pubkey))
+                CKeyID keyid;
+                if (address.GetKeyID(keyid) && model->getPubKey(keyid, pubkey))
                     nBytesInputs += (pubkey.IsCompressed() ? 148 : 180);
                 else
                     nBytesInputs += 148; // in all error cases, simply assume 148 here
@@ -640,7 +639,7 @@ void CoinControlDialog::updateView()
             CBitcoinAddress outputAddress;
             QString sAddress = "";
 
-            if(pwalletMain->ExtractAddress(out.tx->vout[out.i].scriptPubKey, outputAddress))
+            if(ExtractAddress(*pwalletMain, out.tx->vout[out.i].scriptPubKey, outputAddress))
             {
                 sAddress = CBitcoinAddress(outputAddress).ToString().c_str();
 
@@ -651,9 +650,8 @@ void CoinControlDialog::updateView()
                 if (outputAddress.IsPubKey())
                 {
                     CPubKey pubkey;
-                    CTxDestination dest = outputAddress.Get();
-                    CKeyID *keyid = boost::get< CKeyID >(&dest);
-                    if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed())
+                    CKeyID keyid;
+                    if (outputAddress.GetKeyID(keyid) && model->getPubKey(keyid, pubkey) && !pubkey.IsCompressed())
                         nInputSize = 180;
                 }
             }
index 8f9beea..a82f76e 100644 (file)
@@ -243,8 +243,8 @@ void MultisigDialog::on_saveMultisigAddressButton_clicked()
     LOCK(wallet->cs_wallet);
     if(!wallet->HaveCScript(scriptID))
         wallet->AddCScript(script);
-    if(!wallet->mapAddressBook.count(CBitcoinAddress(address).Get()))
-        wallet->SetAddressBookName(CBitcoinAddress(address).Get(), label);
+    if(!wallet->mapAddressBook.count(CBitcoinAddress(address)))
+        wallet->SetAddressBookName(CBitcoinAddress(address), label);
 }
 
 void MultisigDialog::clear()
index 4033621..72bc460 100644 (file)
@@ -142,9 +142,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
             // Online transaction
             std::string strAddress = wtx.mapValue["to"];
             strHTML += "<b>" + tr("To") + ":</b> ";
-            CTxDestination dest = CBitcoinAddress(strAddress).Get();
-            if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].empty())
-                strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest]) + " ";
+            CBitcoinAddress addr(strAddress);
+            if (wallet->mapAddressBook.count(addr) && !wallet->mapAddressBook[addr].empty())
+                strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[addr]) + " ";
             strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>";
         }
 
index 98b6171..a4066cf 100644 (file)
@@ -50,7 +50,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
                 sub.credit = txout.nValue;
 
                 CBitcoinAddress addressRet;
-                if (pwalletMain->ExtractAddress(txout.scriptPubKey, addressRet))
+                if (ExtractAddress(*pwalletMain, txout.scriptPubKey, addressRet))
                 {
                     sub.type = TransactionRecord::RecvWithAddress;
                     sub.address = addressRet.ToString();
index d761fa0..faf5049 100644 (file)
@@ -239,17 +239,17 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
     foreach(const SendCoinsRecipient &rcp, recipients)
     {
         std::string strAddress = rcp.address.toStdString();
-        CTxDestination dest = CBitcoinAddress(strAddress).Get();
+        CBitcoinAddress addr(strAddress);
         std::string strLabel = rcp.label.toStdString();
         {
             LOCK(wallet->cs_wallet);
 
-            std::map<CTxDestination, std::string>::iterator mi = wallet->mapAddressBook.find(dest);
+            std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(addr);
 
             // Check if we have a new address or an updated label
             if (mi == wallet->mapAddressBook.end() || mi->second != strLabel)
             {
-                wallet->SetAddressBookName(dest, strLabel);
+                wallet->SetAddressBookName(addr, strLabel);
             }
         }
     }
@@ -359,11 +359,11 @@ static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStor
     QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
 }
 
-static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)
+static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CBitcoinAddress &address, const std::string &label, bool isMine, ChangeType status)
 {
-    OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", CBitcoinAddress(address).ToString().c_str(), label.c_str(), isMine, status);
+    OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", address.ToString().c_str(), label.c_str(), isMine, status);
     QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
-                              Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())),
+                              Q_ARG(QString, QString::fromStdString(address.ToString())),
                               Q_ARG(QString, QString::fromStdString(label)),
                               Q_ARG(bool, isMine),
                               Q_ARG(int, status));
@@ -496,7 +496,7 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins)
         }
 
         CBitcoinAddress addressRet;
-        if(!out.fSpendable || !wallet->ExtractAddress(cout.tx->vout[cout.i].scriptPubKey, addressRet))
+        if(!out.fSpendable || !ExtractAddress(*wallet, cout.tx->vout[cout.i].scriptPubKey, addressRet))
             continue;
 
         mapCoins[addressRet.ToString().c_str()].push_back(out);
index 1499ace..94eaad2 100644 (file)
@@ -62,18 +62,19 @@ Value importprivkey(const Array& params, bool fHelp)
     bool fCompressed;
     CSecret secret = vchSecret.GetSecret(fCompressed);
     key.SetSecret(secret, fCompressed);
-    CKeyID vchAddress = key.GetPubKey().GetID();
+    CKeyID keyid = key.GetPubKey().GetID();
+    CBitcoinAddress addr = CBitcoinAddress(keyid);
     {
         LOCK2(cs_main, pwalletMain->cs_wallet);
 
         pwalletMain->MarkDirty();
-        pwalletMain->SetAddressBookName(vchAddress, strLabel);
+        pwalletMain->SetAddressBookName(addr, strLabel);
 
         // Don't throw error in case a key is already there
-        if (pwalletMain->HaveKey(vchAddress))
+        if (pwalletMain->HaveKey(keyid))
             return Value::null;
 
-        pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1;
+        pwalletMain->mapKeyMetadata[addr].nCreateTime = 1;
 
         if (!pwalletMain->AddKey(key))
             throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
@@ -131,7 +132,7 @@ Value importaddress(const Array& params, bool fHelp)
         pwalletMain->MarkDirty();
 
         if (address.IsValid())
-            pwalletMain->SetAddressBookName(address.Get(), strLabel);
+            pwalletMain->SetAddressBookName(address, strLabel);
 
         if (!pwalletMain->AddWatchOnly(script))
             throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
index bab881d..61ee9e9 100644 (file)
@@ -134,11 +134,11 @@ Value getnewaddress(const Array& params, bool fHelp)
     CPubKey newKey;
     if (!pwalletMain->GetKeyFromPool(newKey, false))
         throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
-    CKeyID keyID = newKey.GetID();
+    CBitcoinAddress address(newKey.GetID());
 
-    pwalletMain->SetAddressBookName(keyID, strAccount);
+    pwalletMain->SetAddressBookName(address, strAccount);
 
-    return CBitcoinAddress(keyID).ToString();
+    return address.ToString();
 }
 
 
@@ -173,7 +173,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
         if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
             throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
 
-        pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), strAccount);
+        pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey.GetID()), strAccount);
         walletdb.WriteAccount(strAccount, account);
     }
 
@@ -216,14 +216,14 @@ Value setaccount(const Array& 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 Value::null;
 }
@@ -241,7 +241,7 @@ Value getaccount(const Array& params, bool fHelp)
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
 
     string strAccount;
-    map<CTxDestination, string>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
+    map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
     if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
         strAccount = (*mi).second;
     return strAccount;
@@ -366,19 +366,19 @@ Value listaddressgroupings(const Array& params, bool fHelp)
             "in past transactions");
 
     Array jsonGroupings;
-    map<CTxDestination, int64_t> balances = pwalletMain->GetAddressBalances();
-    BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
+    map<CBitcoinAddress, int64_t> balances = pwalletMain->GetAddressBalances();
+    BOOST_FOREACH(set<CBitcoinAddress> grouping, pwalletMain->GetAddressGroupings())
     {
         Array jsonGrouping;
-        BOOST_FOREACH(CTxDestination address, grouping)
+        BOOST_FOREACH(CBitcoinAddress address, grouping)
         {
             Array addressInfo;
-            addressInfo.push_back(CBitcoinAddress(address).ToString());
+            addressInfo.push_back(address.ToString());
             addressInfo.push_back(ValueFromAmount(balances[address]));
             {
                 LOCK(pwalletMain->cs_wallet);
-                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);
         }
@@ -487,7 +487,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
         {
             CBitcoinAddress addressRet;
-            if (!pwalletMain->ExtractAddress(txout.scriptPubKey, addressRet))
+            if (!ExtractAddress(*pwalletMain, txout.scriptPubKey, addressRet))
                 continue;
             if (addressRet == address)
                 if (wtx.GetDepthInMainChain() >= nMinDepth)
@@ -498,11 +498,11 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
     return  ValueFromAmount(nAmount);
 }
 
-void GetAccountAddresses(string strAccount, set<CTxDestination>& setAddress)
+void GetAccountAddresses(string strAccount, set<CBitcoinAddress>& setAddress)
 {
-    BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& item, pwalletMain->mapAddressBook)
+    BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
     {
-        const CTxDestination& address = item.first;
+        const CBitcoinAddress& address = item.first;
         const string& strName = item.second;
         if (strName == strAccount)
             setAddress.insert(address);
@@ -523,7 +523,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
 
     // Get the set of pub keys assigned to account
     string strAccount = AccountFromValue(params[0]);
-    set<CTxDestination> setAddress;
+    set<CBitcoinAddress> setAddress;
     GetAccountAddresses(strAccount, setAddress);
 
     // Tally
@@ -536,8 +536,8 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
 
         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
         {
-            CTxDestination address;
-            if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
+            CBitcoinAddress address;
+            if (ExtractAddress(*pwalletMain, txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
                 if (wtx.GetDepthInMainChain() >= nMinDepth)
                     nAmount += txout.nValue;
         }
@@ -614,15 +614,15 @@ Value getbalance(const Array& params, bool fHelp)
             allGeneratedImmature = allGeneratedMature = allFee = 0;
 
             string strSentAccount;
-            list<pair<CTxDestination, int64_t> > listReceived;
-            list<pair<CTxDestination, int64_t> > listSent;
+            list<pair<CBitcoinAddress, int64_t> > listReceived;
+            list<pair<CBitcoinAddress, int64_t> > listSent;
             wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter);
             if (wtx.GetDepthInMainChain() >= nMinDepth)
             {
-                BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
+                BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64_t)& r, listReceived)
                     nBalance += r.second;
             }
-            BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listSent)
+            BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64_t)& r, listSent)
                 nBalance -= r.second;
             nBalance -= allFee;
             nBalance += allGeneratedMature;
@@ -886,11 +886,11 @@ Value addmultisigaddress(const Array& params, bool fHelp)
     throw runtime_error(
         strprintf("redeemScript exceeds size limit: %" PRIszu " > %d", inner.size(), MAX_SCRIPT_ELEMENT_SIZE));
 
-    CScriptID innerID = inner.GetID();
     pwalletMain->AddCScript(inner);
+    CBitcoinAddress address(inner.GetID());
 
-    pwalletMain->SetAddressBookName(innerID, strAccount);
-    return CBitcoinAddress(innerID).ToString();
+    pwalletMain->SetAddressBookName(address, strAccount);
+    return address.ToString();
 }
 
 Value addredeemscript(const Array& params, bool fHelp)
@@ -910,11 +910,11 @@ Value addredeemscript(const Array& params, bool fHelp)
     // Construct using pay-to-script-hash:
     vector<unsigned char> innerData = ParseHexV(params[0], "redeemScript");
     CScript inner(innerData.begin(), innerData.end());
-    CScriptID innerID = inner.GetID();
     pwalletMain->AddCScript(inner);
+    CBitcoinAddress address(inner.GetID());
 
-    pwalletMain->SetAddressBookName(innerID, strAccount);
-    return CBitcoinAddress(innerID).ToString();
+    pwalletMain->SetAddressBookName(address, strAccount);
+    return address.ToString();
 }
 
 struct tallyitem
@@ -1049,19 +1049,17 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
     return ListReceived(params, true);
 }
 
-static void MaybePushAddress(Object & entry, const CTxDestination &dest)
+static void MaybePushAddress(Object & entry, const CBitcoinAddress &dest)
 {
-    CBitcoinAddress addr;
-    if (addr.Set(dest))
-        entry.push_back(Pair("address", addr.ToString()));
+    entry.push_back(Pair("address", dest.ToString()));
 }
 
 void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter)
 {
     int64_t nGeneratedImmature, nGeneratedMature, nFee;
     string strSentAccount;
-    list<pair<CTxDestination, int64_t> > listReceived;
-    list<pair<CTxDestination, int64_t> > listSent;
+    list<pair<CBitcoinAddress, int64_t> > listReceived;
+    list<pair<CBitcoinAddress, int64_t> > listSent;
 
     wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount, filter);
 
@@ -1091,7 +1089,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
     // Sent
     if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
     {
-        BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent)
+        BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64_t)& s, listSent)
         {
             Object entry;
             entry.push_back(Pair("account", strSentAccount));
@@ -1116,7 +1114,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
     // Received
     if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
     {
-        BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived)
+        BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64_t)& r, listReceived)
         {
             string account;
             if (pwalletMain->mapAddressBook.count(r.first))
@@ -1246,7 +1244,7 @@ Value listaccounts(const Array& params, bool fHelp)
 
 
     map<string, int64_t> mapAccountBalances;
-    BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) {
+    BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
         if (IsMine(*pwalletMain, entry.first)) // This address belongs to me
             mapAccountBalances[entry.second] = 0;
     }
@@ -1256,16 +1254,16 @@ Value listaccounts(const Array& params, bool fHelp)
         const CWalletTx& wtx = (*it).second;
         int64_t nGeneratedImmature, nGeneratedMature, nFee;
         string strSentAccount;
-        list<pair<CTxDestination, int64_t> > listReceived;
-        list<pair<CTxDestination, int64_t> > listSent;
+        list<pair<CBitcoinAddress, int64_t> > listReceived;
+        list<pair<CBitcoinAddress, int64_t> > listSent;
         wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount, includeWatchonly);
         mapAccountBalances[strSentAccount] -= nFee;
-        BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent)
+        BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64_t)& s, listSent)
             mapAccountBalances[strSentAccount] -= s.second;
         if (wtx.GetDepthInMainChain() >= nMinDepth)
         {
             mapAccountBalances[""] += nGeneratedMature;
-            BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived)
+            BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64_t)& r, listReceived)
                 if (pwalletMain->mapAddressBook.count(r.first))
                     mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
                 else
@@ -1750,18 +1748,18 @@ Value validateaddress(const Array& params, bool fHelp)
         }
         else
         {
-            CTxDestination dest = address.Get();
             string currentAddress = address.ToString();
+            CTxDestination dest = address.Get();
             ret.push_back(Pair("address", currentAddress));
-            isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : MINE_NO;
+            isminetype mine = pwalletMain ? IsMine(*pwalletMain, address) : MINE_NO;
             ret.push_back(Pair("ismine", mine != MINE_NO));
             if (mine != MINE_NO) {
                 ret.push_back(Pair("watchonly", mine == MINE_WATCH_ONLY));
                 Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
                 ret.insert(ret.end(), detail.begin(), detail.end());
             }
-            if (pwalletMain->mapAddressBook.count(dest))
-                ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest]));
+            if (pwalletMain->mapAddressBook.count(address))
+                ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
         }
     }
     return ret;
index 2212fe1..16dfa99 100644 (file)
@@ -1640,12 +1640,13 @@ public:
     bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); }
 };
 
+/*
 isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest)
 {
     CScript script;
     script.SetDestination(dest);
     return IsMine(keystore, script);
-}
+}*/
 
 isminetype IsMine(const CKeyStore &keystore, const CBitcoinAddress& dest)
 {
@@ -1744,6 +1745,42 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
     return false;
 }
 
+bool ExtractAddress(const CKeyStore &keystore, const CScript& scriptPubKey, CBitcoinAddress& addressRet)
+{
+    vector<valtype> vSolutions;
+    txnouttype whichType;
+    if (!Solver(scriptPubKey, whichType, vSolutions))
+        return false;
+
+    if (whichType == TX_PUBKEY)
+    {
+        addressRet = CBitcoinAddress(CPubKey(vSolutions[0]).GetID());
+        return true;
+    }
+    if (whichType == TX_PUBKEY_DROP)
+    {
+        // Pay-to-Pubkey-R
+        CMalleableKeyView view;
+        if (!keystore.CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view))
+            return false;
+
+        addressRet = CBitcoinAddress(view.GetMalleablePubKey());
+        return true;
+    }
+    else if (whichType == TX_PUBKEYHASH)
+    {
+        addressRet = CBitcoinAddress(CKeyID(uint160(vSolutions[0])));
+        return true;
+    }
+    else if (whichType == TX_SCRIPTHASH)
+    {
+        addressRet = CBitcoinAddress(CScriptID(uint160(vSolutions[0])));
+        return true;
+    }
+    // Multisig txns have more than one address...
+    return false;
+}
+
 class CAffectedKeysVisitor : public boost::static_visitor<void> {
 private:
     const CKeyStore &keystore;
index 7177339..c24ab9c 100644 (file)
@@ -637,10 +637,11 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
 int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
 bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType);
 isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
-isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest);
+//isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest);
 isminetype IsMine(const CKeyStore& keystore, const CBitcoinAddress& dest);
 void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector<CKeyID> &vKeys);
 bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
+bool ExtractAddress(const CKeyStore &keystore, const CScript& scriptPubKey, CBitcoinAddress& addressRet);
 bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
 bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
 bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
index 07518d0..8006674 100644 (file)
@@ -48,7 +48,7 @@ CPubKey CWallet::GenerateNewKey()
 
     // Create new metadata
     int64_t nCreationTime = GetTime();
-    mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
+    mapKeyMetadata[CBitcoinAddress(pubkey.GetID())] = CKeyMetadata(nCreationTime);
     if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
         nTimeFirstKey = nCreationTime;
 
@@ -70,7 +70,7 @@ CMalleableKeyView CWallet::GenerateNewMalleableKey()
 
     // Create new metadata
     int64_t nCreationTime = GetTime();
-    mapMalleableKeyMetadata[keyView] = CKeyMetadata(nCreationTime);
+    mapKeyMetadata[CBitcoinAddress(keyView.GetMalleablePubKey())] = CKeyMetadata(nCreationTime);
     if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
         nTimeFirstKey = nCreationTime;
 
@@ -87,7 +87,7 @@ bool CWallet::AddKey(const CKey& key)
     if (!fFileBacked)
         return true;
     if (!IsCrypted())
-        return CWalletDB(strWalletFile).WriteKey(pubkey, key.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]);
+        return CWalletDB(strWalletFile).WriteKey(pubkey, key.GetPrivKey(), mapKeyMetadata[CBitcoinAddress(pubkey.GetID())]);
     return true;
 }
 
@@ -100,7 +100,7 @@ bool CWallet::AddMalleableKey(const CMalleableKey& mKey)
     if (!fFileBacked)
         return true;
     if (!IsCrypted())
-        return CWalletDB(strWalletFile).WriteMalleableKey(keyView, vchSecretH, mapMalleableKeyMetadata[keyView]);
+        return CWalletDB(strWalletFile).WriteMalleableKey(keyView, vchSecretH, mapKeyMetadata[CBitcoinAddress(keyView.GetMalleablePubKey())]);
     return true;
 }
 
@@ -114,10 +114,11 @@ bool CWallet::AddCryptedMalleableKey(const CMalleableKeyView& keyView, const std
 
     {
         LOCK(cs_wallet);
+        CBitcoinAddress addr(keyView.GetMalleablePubKey());
         if (pwalletdbEncryption)
-            return pwalletdbEncryption->WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapMalleableKeyMetadata[keyView]);
+            return pwalletdbEncryption->WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapKeyMetadata[addr]);
         else
-            return CWalletDB(strWalletFile).WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapMalleableKeyMetadata[keyView]);
+            return CWalletDB(strWalletFile).WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapKeyMetadata[addr]);
     }
 
     return true;
@@ -138,10 +139,11 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char
         return true;
     {
         LOCK(cs_wallet);
+        CBitcoinAddress addr(vchPubKey.GetID());
         if (pwalletdbEncryption)
-            return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
+            return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[addr]);
         else
-            return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
+            return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[addr]);
     }
     return false;
 }
@@ -151,16 +153,16 @@ bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
     if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
         nTimeFirstKey = meta.nCreateTime;
 
-    mapKeyMetadata[pubkey.GetID()] = meta;
+    mapKeyMetadata[CBitcoinAddress(pubkey.GetID())] = meta;
     return true;
 }
 
-bool CWallet::LoadMalleableKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata)
+bool CWallet::LoadKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata)
 {
     if (metadata.nCreateTime && (!nTimeFirstKey || metadata.nCreateTime < nTimeFirstKey))
         nTimeFirstKey = metadata.nCreateTime;
 
-    mapMalleableKeyMetadata[keyView] = metadata;
+    mapKeyMetadata[CBitcoinAddress(keyView.GetMalleablePubKey())] = metadata;
     return true;
 }
 
@@ -476,7 +478,7 @@ bool CWallet::DecryptWallet(const SecureString& strWalletPassphrase)
                 CKey key;
                 key.SetSecret((*mi).second.first, (*mi).second.second);
                 pwalletdbDecryption->EraseCryptedKey(key.GetPubKey());
-                pwalletdbDecryption->WriteKey(key.GetPubKey(), key.GetPrivKey(), mapKeyMetadata[(*mi).first]);
+                pwalletdbDecryption->WriteKey(key.GetPubKey(), key.GetPrivKey(), mapKeyMetadata[CBitcoinAddress(mi->first)]);
                 mi++;
             }
 
@@ -486,7 +488,7 @@ bool CWallet::DecryptWallet(const SecureString& strWalletPassphrase)
                 const CSecret &vchSecretH = mi2->second;
                 const CMalleableKeyView &keyView = mi2->first;
                 pwalletdbDecryption->EraseCryptedMalleableKey(keyView);
-                pwalletdbDecryption->WriteMalleableKey(keyView, vchSecretH, mapMalleableKeyMetadata[keyView]);
+                pwalletdbDecryption->WriteMalleableKey(keyView, vchSecretH, mapKeyMetadata[CBitcoinAddress(keyView.GetMalleablePubKey())]);
                 mi2++;
             }
 
@@ -867,8 +869,8 @@ int CWalletTx::GetRequestCount() const
     return nRequests;
 }
 
-void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, list<pair<CTxDestination, int64_t> >& listReceived,
-                           list<pair<CTxDestination, int64_t> >& listSent, int64_t& nFee, string& strSentAccount, const isminefilter& filter) const
+void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, list<pair<CBitcoinAddress, int64_t> >& listReceived,
+                           list<pair<CBitcoinAddress, int64_t> >& listSent, int64_t& nFee, string& strSentAccount, const isminefilter& filter) const
 {
     nGeneratedImmature = nGeneratedMature = nFee = 0;
     listReceived.clear();
@@ -909,12 +911,12 @@ void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMatur
             continue;
 
         // In either case, we need to get the destination address
-        CTxDestination address;
-        if (!ExtractDestination(txout.scriptPubKey, address))
+        CBitcoinAddress address;
+        if (!ExtractAddress(*pwallet, txout.scriptPubKey, address))
         {
             printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
                    this->GetHash().ToString().c_str());
-            address = CNoDestination();
+            address = CBitcoinAddress();
         }
 
         // If we are debited by the transaction, add the output as a "sent" entry
@@ -936,25 +938,25 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nGenerated,
     int64_t allGeneratedImmature, allGeneratedMature, allFee;
     allGeneratedImmature = allGeneratedMature = allFee = 0;
     string strSentAccount;
-    list<pair<CTxDestination, int64_t> > listReceived;
-    list<pair<CTxDestination, int64_t> > listSent;
+    list<pair<CBitcoinAddress, int64_t> > listReceived;
+    list<pair<CBitcoinAddress, int64_t> > listSent;
     GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter);
 
     if (strAccount == "")
         nGenerated = allGeneratedMature;
     if (strAccount == strSentAccount)
     {
-        BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& s, listSent)
+        BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64_t)& s, listSent)
             nSent += s.second;
         nFee = allFee;
     }
     {
         LOCK(pwallet->cs_wallet);
-        BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
+        BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64_t)& r, listReceived)
         {
             if (pwallet->mapAddressBook.count(r.first))
             {
-                map<CTxDestination, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
+                map<CBitcoinAddress, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
                 if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
                     nReceived += r.second;
             }
@@ -2234,23 +2236,23 @@ DBErrors CWallet::ZapWalletTx()
     return DB_LOAD_OK;
 }
 
-bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName)
+bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
 {
-    std::map<CTxDestination, std::string>::iterator mi = mapAddressBook.find(address);
+    std::map<CBitcoinAddress, string>::iterator mi = mapAddressBook.find(address);
     mapAddressBook[address] = strName;
     NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != MINE_NO, (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
     if (!fFileBacked)
         return false;
-    return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
+    return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
 }
 
-bool CWallet::DelAddressBookName(const CTxDestination& address)
+bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
 {
     mapAddressBook.erase(address);
     NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != MINE_NO, CT_DELETED);
     if (!fFileBacked)
         return false;
-    return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
+    return CWalletDB(strWalletFile).EraseName(address.ToString());
 }
 
 
@@ -2470,9 +2472,9 @@ int64_t CWallet::GetOldestKeyPoolTime()
     return keypool.nTime;
 }
 
-std::map<CTxDestination, int64_t> CWallet::GetAddressBalances()
+std::map<CBitcoinAddress, int64_t> CWallet::GetAddressBalances()
 {
-    map<CTxDestination, int64_t> balances;
+    map<CBitcoinAddress, int64_t> balances;
 
     {
         LOCK(cs_wallet);
@@ -2492,10 +2494,10 @@ std::map<CTxDestination, int64_t> CWallet::GetAddressBalances()
 
             for (unsigned int i = 0; i < pcoin->vout.size(); i++)
             {
-                CTxDestination addr;
+                CBitcoinAddress addr;
                 if (!IsMine(pcoin->vout[i]))
                     continue;
-                if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
+                if(!ExtractAddress(*this, pcoin->vout[i].scriptPubKey, addr))
                     continue;
 
                 int64_t n = pcoin->IsSpent(i) ? 0 : pcoin->vout[i].nValue;
@@ -2510,10 +2512,10 @@ std::map<CTxDestination, int64_t> CWallet::GetAddressBalances()
     return balances;
 }
 
-set< set<CTxDestination> > CWallet::GetAddressGroupings()
+set< set<CBitcoinAddress> > CWallet::GetAddressGroupings()
 {
-    set< set<CTxDestination> > groupings;
-    set<CTxDestination> grouping;
+    set< set<CBitcoinAddress> > groupings;
+    set<CBitcoinAddress> grouping;
 
     BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
     {
@@ -2524,8 +2526,8 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
             // group all input addresses with each other
             BOOST_FOREACH(CTxIn txin, pcoin->vin)
             {
-                CTxDestination address;
-                if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
+                CBitcoinAddress address;
+                if(!ExtractAddress(*this, mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
                     continue;
                 grouping.insert(address);
             }
@@ -2535,8 +2537,8 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
                 if (IsChange(txout))
                 {
                     CWalletTx tx = mapWallet[pcoin->vin[0].prevout.hash];
-                    CTxDestination txoutAddr;
-                    if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
+                    CBitcoinAddress txoutAddr;
+                    if(!ExtractAddress(*this, txout.scriptPubKey, txoutAddr))
                         continue;
                     grouping.insert(txoutAddr);
                 }
@@ -2548,8 +2550,8 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
         for (unsigned int i = 0; i < pcoin->vout.size(); i++)
             if (IsMine(pcoin->vout[i]))
             {
-                CTxDestination address;
-                if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
+                CBitcoinAddress address;
+                if(!ExtractAddress(*this, pcoin->vout[i].scriptPubKey, address))
                     continue;
                 grouping.insert(address);
                 groupings.insert(grouping);
@@ -2557,20 +2559,20 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
             }
     }
 
-    set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
-    map< CTxDestination, set<CTxDestination>* > setmap;  // map addresses to the unique group containing it
-    BOOST_FOREACH(set<CTxDestination> grouping, groupings)
+    set< set<CBitcoinAddress>* > uniqueGroupings; // a set of pointers to groups of addresses
+    map< CBitcoinAddress, set<CBitcoinAddress>* > setmap;  // map addresses to the unique group containing it
+    BOOST_FOREACH(set<CBitcoinAddress> grouping, groupings)
     {
         // make a set of all the groups hit by this new group
-        set< set<CTxDestination>* > hits;
-        map< CTxDestination, set<CTxDestination>* >::iterator it;
-        BOOST_FOREACH(CTxDestination address, grouping)
+        set< set<CBitcoinAddress>* > hits;
+        map< CBitcoinAddress, set<CBitcoinAddress>* >::iterator it;
+        BOOST_FOREACH(CBitcoinAddress address, grouping)
             if ((it = setmap.find(address)) != setmap.end())
                 hits.insert((*it).second);
 
         // merge all hit groups into a new single group and delete old groups
-        set<CTxDestination>* merged = new set<CTxDestination>(grouping);
-        BOOST_FOREACH(set<CTxDestination>* hit, hits)
+        set<CBitcoinAddress>* merged = new set<CBitcoinAddress>(grouping);
+        BOOST_FOREACH(set<CBitcoinAddress>* hit, hits)
         {
             merged->insert(hit->begin(), hit->end());
             uniqueGroupings.erase(hit);
@@ -2579,12 +2581,12 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
         uniqueGroupings.insert(merged);
 
         // update setmap
-        BOOST_FOREACH(CTxDestination element, *merged)
+        BOOST_FOREACH(CBitcoinAddress element, *merged)
             setmap[element] = merged;
     }
 
-    set< set<CTxDestination> > ret;
-    BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
+    set< set<CBitcoinAddress> > ret;
+    BOOST_FOREACH(set<CBitcoinAddress>* uniqueGrouping, uniqueGroupings)
     {
         ret.insert(*uniqueGrouping);
         delete uniqueGrouping;
@@ -2747,14 +2749,8 @@ void CWallet::GetAddresses(std::map<CBitcoinAddress, int64_t> &mapAddresses) con
     mapAddresses.clear();
 
     // get birth times for keys with metadata
-    for (std::map<CMalleableKeyView, CKeyMetadata>::const_iterator it = mapMalleableKeyMetadata.begin(); it != mapMalleableKeyMetadata.end(); it++) {
-        CBitcoinAddress addr(it->first.GetMalleablePubKey());
-        mapAddresses[addr] = it->second.nCreateTime ? it->second.nCreateTime : 0;
-    }
-
-    for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) {
-        CBitcoinAddress addr(it->first);
-        mapAddresses[addr] = it->second.nCreateTime ? it->second.nCreateTime : 0;
+    for (std::map<CBitcoinAddress, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) {
+        mapAddresses[it->first] = it->second.nCreateTime ? it->second.nCreateTime : 0;
     }
 
     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
@@ -2767,7 +2763,7 @@ void CWallet::GetAddresses(std::map<CBitcoinAddress, int64_t> &mapAddresses) con
             const CTxOut &out = (*it2);
             // iterate over all their outputs
             CBitcoinAddress addressRet;
-            if (const_cast<CWallet*>(this)->ExtractAddress(out.scriptPubKey, addressRet)) {
+            if (ExtractAddress(*this, out.scriptPubKey, addressRet)) {
                 if (mapAddresses.find(addressRet) != mapAddresses.end() && (mapAddresses[addressRet] == 0 || mapAddresses[addressRet] > wtx.nTime))
                     mapAddresses[addressRet] = wtx.nTime;
             }
@@ -2805,38 +2801,3 @@ void CWallet::ClearOrphans()
         EraseFromWallet(*it);
 }
 
-bool CWallet::ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet)
-{
-    vector<valtype> vSolutions;
-    txnouttype whichType;
-    if (!Solver(scriptPubKey, whichType, vSolutions))
-        return false;
-
-    if (whichType == TX_PUBKEY)
-    {
-        addressRet = CBitcoinAddress(CPubKey(vSolutions[0]).GetID());
-        return true;
-    }
-    if (whichType == TX_PUBKEY_DROP)
-    {
-        // Pay-to-Pubkey-R
-        CMalleableKeyView view;
-        if (!CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view))
-            return false;
-
-        addressRet = CBitcoinAddress(view.GetMalleablePubKey());
-        return true;
-    }
-    else if (whichType == TX_PUBKEYHASH)
-    {
-        addressRet = CBitcoinAddress(CKeyID(uint160(vSolutions[0])));
-        return true;
-    }
-    else if (whichType == TX_SCRIPTHASH)
-    {
-        addressRet = CBitcoinAddress(CScriptID(uint160(vSolutions[0])));
-        return true;
-    }
-    // Multisig txns have more than one address...
-    return false;
-}
index 6e36e9d..b3d7d33 100644 (file)
@@ -96,8 +96,12 @@ public:
     std::string strWalletFile;
 
     std::set<int64_t> setKeyPool;
+    /*
     std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
     std::map<CMalleableKeyView, CKeyMetadata> mapMalleableKeyMetadata;
+    */
+
+    std::map<CBitcoinAddress, CKeyMetadata> mapKeyMetadata;
 
     typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
     MasterKeyMap mapMasterKeys;
@@ -133,7 +137,7 @@ public:
     int64_t nOrderPosNext;
     std::map<uint256, int> mapRequestCount;
 
-    std::map<CTxDestination, std::string> mapAddressBook;
+    std::map<CBitcoinAddress, std::string> mapAddressBook;
 
     CPubKey vchDefaultKey;
     int64_t nTimeFirstKey;
@@ -159,7 +163,7 @@ public:
     bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); }
     // Load metadata (used by LoadWallet)
     bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata);
-    bool LoadMalleableKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata);
+    bool LoadKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata);
 
     // Load malleable key without saving it to disk (used by LoadWallet)
     bool LoadMalleableKey(const CMalleableKeyView &keyView, const CSecret &vchSecretH) { return CCryptoKeyStore::AddMalleableKey(keyView, vchSecretH); }
@@ -243,8 +247,8 @@ public:
     int64_t GetOldestKeyPoolTime();
     void GetAllReserveKeys(std::set<CKeyID>& setAddress) const;
 
-    std::set< std::set<CTxDestination> > GetAddressGroupings();
-    std::map<CTxDestination, int64_t> GetAddressBalances();
+    std::set< std::set<CBitcoinAddress> > GetAddressGroupings();
+    std::map<CBitcoinAddress, int64_t> GetAddressBalances();
 
     isminetype IsMine(const CTxIn& txin) const;
     int64_t GetDebit(const CTxIn& txin, const isminefilter& filter) const;
@@ -315,9 +319,9 @@ public:
 
     DBErrors ZapWalletTx();
 
-    bool SetAddressBookName(const CTxDestination& address, const std::string& strName);
+    bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName);
 
-    bool DelAddressBookName(const CTxDestination& address);
+    bool DelAddressBookName(const CBitcoinAddress& address);
 
     void UpdatedTransaction(const uint256 &hashTx);
 
@@ -340,8 +344,6 @@ public:
 
     bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
 
-    bool ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet);
-
     bool SetDefaultKey(const CPubKey &vchPubKey);
 
     // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
@@ -359,7 +361,7 @@ public:
     /** Address book entry changed.
      * @note called with lock cs_wallet held.
      */
-    boost::signals2::signal<void (CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)> NotifyAddressBookChanged;
+    boost::signals2::signal<void (CWallet *wallet, const CBitcoinAddress &address, const std::string &label, bool isMine, ChangeType status)> NotifyAddressBookChanged;
 
     /** Wallet transaction added, removed or updated.
      * @note called with lock cs_wallet held.
@@ -797,8 +799,8 @@ public:
         return nChangeCached;
     }
 
-    void GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, std::list<std::pair<CTxDestination, int64_t> >& listReceived,
-                    std::list<std::pair<CTxDestination, int64_t> >& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter) const;
+    void GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, std::list<std::pair<CBitcoinAddress, int64_t> >& listReceived,
+                    std::list<std::pair<CBitcoinAddress, int64_t> >& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter) const;
 
     void GetAccountAmounts(const std::string& strAccount, int64_t& nGenerated, int64_t& nReceived,
                            int64_t& nSent, int64_t& nFee, const isminefilter& filter) const;
index c8e64ca..e44885d 100644 (file)
@@ -225,7 +225,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
         {
             string strAddress;
             ssKey >> strAddress;
-            ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()];
+            ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress)];
         }
         else if (strType == "tx")
         {
@@ -428,7 +428,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
             ssValue >> keyMeta;
             wss.nKeyMeta++;
 
-            pwallet->LoadMalleableKeyMetadata(keyView, keyMeta);
+            pwallet->LoadKeyMetadata(keyView, keyMeta);
         }
         else if (strType == "keymeta")
         {
@@ -460,9 +460,9 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
             // If no metadata exists yet, create a default with the pool key's
             // creation time. Note that this may be overwritten by actually
             // stored metadata for that key later, which is fine.
-            CKeyID keyid = keypool.vchPubKey.GetID();
-            if (pwallet->mapKeyMetadata.count(keyid) == 0)
-                pwallet->mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
+            CBitcoinAddress addr = CBitcoinAddress(keypool.vchPubKey.GetID());
+            if (pwallet->mapKeyMetadata.count(addr) == 0)
+                pwallet->mapKeyMetadata[addr] = CKeyMetadata(keypool.nTime);
 
         }
         else if (strType == "version")
@@ -827,7 +827,11 @@ bool DumpWallet(CWallet* pwallet, const string& strDest)
                 continue;
             CMalleableKey mKey;
             pwallet->GetMalleableKey(keyView, mKey);
-            file << strprintf("%s %s # view=%s addr=%s\n", mKey.ToString().c_str(), strTime.c_str(), keyView.ToString().c_str(), strAddr.c_str());
+            file << mKey.ToString();
+            if (pwallet->mapAddressBook.count(addr))
+                file << strprintf(" %s label=%s # view=%s addr=%s\n", strTime.c_str(), EncodeDumpString(pwallet->mapAddressBook[addr]).c_str(), keyView.ToString().c_str(), strAddr.c_str());
+            else
+                file << strprintf(" %s # view=%s addr=%s\n", strTime.c_str(), keyView.ToString().c_str(), strAddr.c_str());
         }
         else {
             // Pubkey hash address
@@ -839,8 +843,8 @@ bool DumpWallet(CWallet* pwallet, const string& strDest)
                 continue;
             CSecret secret = key.GetSecret(IsCompressed);
             file << CBitcoinSecret(secret, IsCompressed).ToString();
-            if (pwallet->mapAddressBook.count(keyid))
-                file << strprintf(" %s label=%s # addr=%s\n", strTime.c_str(), EncodeDumpString(pwallet->mapAddressBook[keyid]).c_str(), strAddr.c_str());
+            if (pwallet->mapAddressBook.count(addr))
+                file << strprintf(" %s label=%s # addr=%s\n", strTime.c_str(), EncodeDumpString(pwallet->mapAddressBook[addr]).c_str(), strAddr.c_str());
             else if (setKeyPool.count(keyid))
                 file << strprintf(" %s reserve=1 # addr=%s\n", strTime.c_str(), strAddr.c_str());
             else
@@ -899,6 +903,7 @@ bool ImportWallet(CWallet *pwallet, const string& strLocation)
            }
        }
 
+       CBitcoinAddress addr;
        CBitcoinSecret vchSecret;
        if (vchSecret.SetString(vstr[0])) {
            // Simple private key
@@ -908,20 +913,18 @@ bool ImportWallet(CWallet *pwallet, const string& strLocation)
            CSecret secret = vchSecret.GetSecret(fCompressed);
            key.SetSecret(secret, fCompressed);
            CKeyID keyid = key.GetPubKey().GetID();
+           addr = CBitcoinAddress(keyid);
 
            if (pwallet->HaveKey(keyid)) {
-               printf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString().c_str());
+               printf("Skipping import of %s (key already present)\n", addr.ToString().c_str());
                continue;
            }
 
-           printf("Importing %s...\n", CBitcoinAddress(keyid).ToString().c_str());
+           printf("Importing %s...\n", addr.ToString().c_str());
            if (!pwallet->AddKey(key)) {
                fGood = false;
                continue;
            }
-           pwallet->mapKeyMetadata[keyid].nCreateTime = nTime;
-           if (fLabel)
-               pwallet->SetAddressBookName(keyid, strLabel);
        } else {
            // A pair of private keys
 
@@ -929,18 +932,24 @@ bool ImportWallet(CWallet *pwallet, const string& strLocation)
            if (!mKey.SetString(vstr[0]))
                continue;
            CMalleablePubKey mPubKey = mKey.GetMalleablePubKey();
+           addr = CBitcoinAddress(mPubKey);
+
            if (pwallet->CheckOwnership(mPubKey)) {
-               printf("Skipping import of %s (key already present)\n", CBitcoinAddress(mPubKey).ToString().c_str());
+               printf("Skipping import of %s (key already present)\n", addr.ToString().c_str());
                continue;
            }
 
-           printf("Importing %s...\n", CBitcoinAddress(mPubKey).ToString().c_str());
+           printf("Importing %s...\n", addr.ToString().c_str());
            if (!pwallet->AddMalleableKey(mKey)) {
                fGood = false;
                continue;
            }
-           pwallet->mapMalleableKeyMetadata[CMalleableKeyView(mKey)].nCreateTime = nTime;
        }
+
+       pwallet->mapKeyMetadata[addr].nCreateTime = nTime;
+       if (fLabel)
+           pwallet->SetAddressBookName(addr, strLabel);
+
        nTimeBegin = std::min(nTimeBegin, nTime);
    }
    file.close();