From ddb68acebe0c41e1958a783c38a272ae11671f86 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Mon, 20 Dec 2010 14:44:54 -0500 Subject: [PATCH] Add address to listtransactions output --- main.cpp | 57 +++++++++++++++++++++++++++++++++++++------------------- main.h | 2 +- rpc.cpp | 44 ++++++++++++++++++++++++++++--------------- 3 files changed, 68 insertions(+), 35 deletions(-) diff --git a/main.cpp b/main.cpp index 8db6c394e8..b7dfd9fabe 100644 --- a/main.cpp +++ b/main.cpp @@ -395,9 +395,12 @@ int CWalletTx::GetRequestCount() const } void CWalletTx::GetAmounts(int64& nGenerated, list >& listReceived, - int64& nSent, int64& nFee, string& strSentAccount) const + list >& listSent, int64& nFee, string& strSentAccount) const { - nGenerated = nSent = nFee = 0; + nGenerated = nFee = 0; + listReceived.clear(); + listSent.clear(); + strSentAccount = strFromAccount; if (IsCoinBase()) { @@ -406,24 +409,38 @@ void CWalletTx::GetAmounts(int64& nGenerated, list >& listRe return; } - // Received. Standard client will never generate a send-to-multiple-recipients, - // but non-standard clients might (so return a list of address/amount pairs) - foreach(const CTxOut& txout, vout) - { - vector vchPubKey; - if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) - listReceived.push_back(make_pair(PubKeyToAddress(vchPubKey), txout.nValue)); - } - - // Sent + // Compute fee: int64 nDebit = GetDebit(); - if (nDebit > 0) + if (nDebit > 0) // debit>0 means we signed/sent this transaction { int64 nValueOut = GetValueOut(); nFee = nDebit - nValueOut; - nSent = nValueOut - GetChange(); - strSentAccount = strFromAccount; } + + // Sent/received. Standard client will never generate a send-to-multiple-recipients, + // but non-standard clients might (so return a list of address/amount pairs) + foreach(const CTxOut& txout, vout) + { + string address; + uint160 hash160; + vector vchPubKey; + if (ExtractHash160(txout.scriptPubKey, hash160)) + address = Hash160ToAddress(hash160); + else if (ExtractPubKey(txout.scriptPubKey, false, vchPubKey)) + address = PubKeyToAddress(vchPubKey); + else + address = " unknown "; // some type of weird non-standard transaction? + + if (nDebit > 0 && txout.IsChange()) + continue; + + if (nDebit > 0) + listSent.push_back(make_pair(address, txout.nValue)); + + if (txout.IsMine()) + listReceived.push_back(make_pair(address, txout.nValue)); + } + } void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, @@ -431,17 +448,19 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i { nGenerated = nReceived = nSent = nFee = 0; - int64 allGenerated, allSent, allFee; - allGenerated = allSent = allFee = 0; + int64 allGenerated, allFee; + allGenerated = allFee = 0; string strSentAccount; list > listReceived; - GetAmounts(allGenerated, listReceived, allSent, allFee, strSentAccount); + list > listSent; + GetAmounts(allGenerated, listReceived, listSent, allFee, strSentAccount); if (strAccount == "") nGenerated = allGenerated; if (strAccount == strSentAccount) { - nSent = allSent; + foreach(const PAIRTYPE(string,int64)& s, listSent) + nSent += s.second; nFee = allFee; } CRITICAL_BLOCK(cs_mapAddressBook) diff --git a/main.h b/main.h index 11a5862cb0..3c7bcb22f0 100644 --- a/main.h +++ b/main.h @@ -874,7 +874,7 @@ public: } void GetAmounts(int64& nGenerated, list >& listReceived, - int64& nSent, int64& nFee, string& strSentAccount) const; + list >& listSent, int64& nFee, string& strSentAccount) const; void GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const; diff --git a/rpc.cpp b/rpc.cpp index 602de73e44..aede2e4c4c 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -859,10 +859,11 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, Array& ret) { - int64 nGenerated, nSent, nFee; + int64 nGenerated, nFee; string strSentAccount; list > listReceived; - wtx.GetAmounts(nGenerated, listReceived, nSent, nFee, strSentAccount); + list > listSent; + wtx.GetAmounts(nGenerated, listReceived, listSent, nFee, strSentAccount); bool fAllAccounts = (strAccount == string("*")); @@ -878,15 +879,19 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe } // Sent - if ((nSent != 0 || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) + if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) { - Object entry; - entry.push_back(Pair("account", strSentAccount)); - entry.push_back(Pair("category", "send")); - entry.push_back(Pair("amount", ValueFromAmount(-nSent))); - entry.push_back(Pair("fee", ValueFromAmount(-nFee))); - WalletTxToJSON(wtx, entry); - ret.push_back(entry); + foreach(const PAIRTYPE(string, int64)& s, listSent) + { + Object entry; + entry.push_back(Pair("account", strSentAccount)); + entry.push_back(Pair("address", s.first)); + entry.push_back(Pair("category", "send")); + entry.push_back(Pair("amount", ValueFromAmount(-s.second))); + entry.push_back(Pair("fee", ValueFromAmount(-nFee))); + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } } // Received @@ -894,15 +899,21 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe CRITICAL_BLOCK(cs_mapAddressBook) { foreach(const PAIRTYPE(string, int64)& r, listReceived) - if (mapAddressBook.count(r.first) && (fAllAccounts || mapAddressBook[r.first] == strAccount)) + { + string account; + if (mapAddressBook.count(r.first)) + account = mapAddressBook[r.first]; + if (fAllAccounts || (account == strAccount)) { Object entry; - entry.push_back(Pair("account", mapAddressBook[r.first])); + entry.push_back(Pair("account", account)); + entry.push_back(Pair("address", r.first)); entry.push_back(Pair("category", "receive")); entry.push_back(Pair("amount", ValueFromAmount(r.second))); WalletTxToJSON(wtx, entry); ret.push_back(entry); } + } } } @@ -1007,11 +1018,14 @@ Value listaccounts(const Array& params, bool fHelp) for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; - int64 nGenerated, nSent, nFee; + int64 nGenerated, nFee; string strSentAccount; list > listReceived; - wtx.GetAmounts(nGenerated, listReceived, nSent, nFee, strSentAccount); - mapAccountBalances[strSentAccount] -= nSent+nFee; + list > listSent; + wtx.GetAmounts(nGenerated, listReceived, listSent, nFee, strSentAccount); + mapAccountBalances[strSentAccount] -= nFee; + foreach(const PAIRTYPE(string, int64)& s, listSent) + mapAccountBalances[strSentAccount] -= s.second; if (wtx.GetDepthInMainChain() >= nMinDepth) { mapAccountBalances[""] += nGenerated;