JSON methods: listtransactions, gettransaction, move, sendfrom and getbalance <account>
git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@193 1a98c847-1fd6-4fd8-948a-caf3550aa51b
This commit is contained in:
parent
84d7c981dc
commit
bfd471f53e
6 changed files with 268 additions and 98 deletions
19
db.cpp
19
db.cpp
|
@ -596,12 +596,24 @@ bool CWalletDB::WriteAccountingEntry(const string& strAccount, const CAccounting
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 CWalletDB::GetAccountCreditDebit(const string& strAccount)
|
int64 CWalletDB::GetAccountCreditDebit(const string& strAccount)
|
||||||
|
{
|
||||||
|
list<CAccountingEntry> entries;
|
||||||
|
ListAccountCreditDebit(strAccount, entries);
|
||||||
|
|
||||||
|
int64 nCreditDebit = 0;
|
||||||
|
foreach (const CAccountingEntry& entry, entries)
|
||||||
|
nCreditDebit += entry.nCreditDebit;
|
||||||
|
|
||||||
|
return nCreditDebit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& entries)
|
||||||
{
|
{
|
||||||
int64 nCreditDebit = 0;
|
int64 nCreditDebit = 0;
|
||||||
|
|
||||||
Dbc* pcursor = GetCursor();
|
Dbc* pcursor = GetCursor();
|
||||||
if (!pcursor)
|
if (!pcursor)
|
||||||
throw runtime_error("CWalletDB::GetAccountCreditDebit() : cannot create DB cursor");
|
throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor");
|
||||||
unsigned int fFlags = DB_SET_RANGE;
|
unsigned int fFlags = DB_SET_RANGE;
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
|
@ -617,7 +629,7 @@ int64 CWalletDB::GetAccountCreditDebit(const string& strAccount)
|
||||||
else if (ret != 0)
|
else if (ret != 0)
|
||||||
{
|
{
|
||||||
pcursor->close();
|
pcursor->close();
|
||||||
throw runtime_error("CWalletDB::GetAccountCreditDebit() : error scanning DB");
|
throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unserialize
|
// Unserialize
|
||||||
|
@ -632,11 +644,10 @@ int64 CWalletDB::GetAccountCreditDebit(const string& strAccount)
|
||||||
|
|
||||||
CAccountingEntry acentry;
|
CAccountingEntry acentry;
|
||||||
ssValue >> acentry;
|
ssValue >> acentry;
|
||||||
nCreditDebit += acentry.nCreditDebit;
|
entries.push_back(acentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcursor->close();
|
pcursor->close();
|
||||||
return nCreditDebit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::LoadWallet()
|
bool CWalletDB::LoadWallet()
|
||||||
|
|
1
db.h
1
db.h
|
@ -435,6 +435,7 @@ public:
|
||||||
bool WriteAccount(const string& strAccount, const CAccount& account);
|
bool WriteAccount(const string& strAccount, const CAccount& account);
|
||||||
bool WriteAccountingEntry(const string& strAccount, const CAccountingEntry& acentry);
|
bool WriteAccountingEntry(const string& strAccount, const CAccountingEntry& acentry);
|
||||||
int64 GetAccountCreditDebit(const string& strAccount);
|
int64 GetAccountCreditDebit(const string& strAccount);
|
||||||
|
void ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& acentries);
|
||||||
|
|
||||||
bool LoadWallet();
|
bool LoadWallet();
|
||||||
protected:
|
protected:
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -3492,7 +3492,7 @@ int64 GetBalance()
|
||||||
CWalletTx* pcoin = &(*it).second;
|
CWalletTx* pcoin = &(*it).second;
|
||||||
if (!pcoin->IsFinal() || pcoin->fSpent || !pcoin->IsConfirmed())
|
if (!pcoin->IsFinal() || pcoin->fSpent || !pcoin->IsConfirmed())
|
||||||
continue;
|
continue;
|
||||||
nTotal += pcoin->GetCredit(true);
|
nTotal += pcoin->GetCredit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
82
main.h
82
main.h
|
@ -345,9 +345,25 @@ public:
|
||||||
{
|
{
|
||||||
if (!MoneyRange(nValue))
|
if (!MoneyRange(nValue))
|
||||||
throw runtime_error("CTxOut::GetCredit() : value out of range");
|
throw runtime_error("CTxOut::GetCredit() : value out of range");
|
||||||
if (IsMine())
|
return (IsMine() ? nValue : 0);
|
||||||
return nValue;
|
}
|
||||||
return 0;
|
|
||||||
|
bool IsChange() const
|
||||||
|
{
|
||||||
|
// On a debit transaction, a txout that's mine but isn't in the address book is change
|
||||||
|
vector<unsigned char> vchPubKey;
|
||||||
|
if (ExtractPubKey(scriptPubKey, true, vchPubKey))
|
||||||
|
CRITICAL_BLOCK(cs_mapAddressBook)
|
||||||
|
if (!mapAddressBook.count(PubKeyToAddress(vchPubKey)))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 GetChange() const
|
||||||
|
{
|
||||||
|
if (!MoneyRange(nValue))
|
||||||
|
throw runtime_error("CTxOut::GetChange() : value out of range");
|
||||||
|
return (IsChange() ? nValue : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator==(const CTxOut& a, const CTxOut& b)
|
friend bool operator==(const CTxOut& a, const CTxOut& b)
|
||||||
|
@ -520,6 +536,20 @@ public:
|
||||||
return nCredit;
|
return nCredit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64 GetChange() const
|
||||||
|
{
|
||||||
|
if (IsCoinBase())
|
||||||
|
return 0;
|
||||||
|
int64 nChange = 0;
|
||||||
|
foreach(const CTxOut& txout, vout)
|
||||||
|
{
|
||||||
|
nChange += txout.GetChange();
|
||||||
|
if (!MoneyRange(nChange))
|
||||||
|
throw runtime_error("CTransaction::GetChange() : value out of range");
|
||||||
|
}
|
||||||
|
return nChange;
|
||||||
|
}
|
||||||
|
|
||||||
int64 GetValueOut() const
|
int64 GetValueOut() const
|
||||||
{
|
{
|
||||||
int64 nValueOut = 0;
|
int64 nValueOut = 0;
|
||||||
|
@ -731,8 +761,10 @@ public:
|
||||||
// memory only
|
// memory only
|
||||||
mutable char fDebitCached;
|
mutable char fDebitCached;
|
||||||
mutable char fCreditCached;
|
mutable char fCreditCached;
|
||||||
|
mutable char fChangeCached;
|
||||||
mutable int64 nDebitCached;
|
mutable int64 nDebitCached;
|
||||||
mutable int64 nCreditCached;
|
mutable int64 nCreditCached;
|
||||||
|
mutable int64 nChangeCached;
|
||||||
|
|
||||||
// memory only UI hints
|
// memory only UI hints
|
||||||
mutable unsigned int nTimeDisplayed;
|
mutable unsigned int nTimeDisplayed;
|
||||||
|
@ -768,8 +800,10 @@ public:
|
||||||
strFromAccount.clear();
|
strFromAccount.clear();
|
||||||
fDebitCached = false;
|
fDebitCached = false;
|
||||||
fCreditCached = false;
|
fCreditCached = false;
|
||||||
|
fChangeCached = false;
|
||||||
nDebitCached = 0;
|
nDebitCached = 0;
|
||||||
nCreditCached = 0;
|
nCreditCached = 0;
|
||||||
|
nChangeCached = 0;
|
||||||
nTimeDisplayed = 0;
|
nTimeDisplayed = 0;
|
||||||
nLinesDisplayed = 0;
|
nLinesDisplayed = 0;
|
||||||
fConfirmedDisplayed = false;
|
fConfirmedDisplayed = false;
|
||||||
|
@ -808,7 +842,7 @@ public:
|
||||||
return nDebitCached;
|
return nDebitCached;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 GetCredit(bool fUseCache=false) const
|
int64 GetCredit(bool fUseCache=true) const
|
||||||
{
|
{
|
||||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||||
|
@ -822,11 +856,51 @@ public:
|
||||||
return nCreditCached;
|
return nCreditCached;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64 GetChange() const
|
||||||
|
{
|
||||||
|
if (fChangeCached)
|
||||||
|
return nChangeCached;
|
||||||
|
nChangeCached = CTransaction::GetChange();
|
||||||
|
fChangeCached = true;
|
||||||
|
return nChangeCached;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsFromMe() const
|
bool IsFromMe() const
|
||||||
{
|
{
|
||||||
return (GetDebit() > 0);
|
return (GetDebit() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetAccountAmounts(string strAccount, const set<CScript>& setPubKey,
|
||||||
|
int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const
|
||||||
|
{
|
||||||
|
nGenerated = nReceived = nSent = nFee = 0;
|
||||||
|
|
||||||
|
// Generated blocks count to account ""
|
||||||
|
if (IsCoinBase())
|
||||||
|
{
|
||||||
|
if (strAccount == "" && GetBlocksToMaturity() == 0)
|
||||||
|
nGenerated = GetCredit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Received
|
||||||
|
foreach(const CTxOut& txout, vout)
|
||||||
|
if (setPubKey.count(txout.scriptPubKey))
|
||||||
|
nReceived += txout.nValue;
|
||||||
|
|
||||||
|
// Sent
|
||||||
|
if (strFromAccount == strAccount)
|
||||||
|
{
|
||||||
|
int64 nDebit = GetDebit();
|
||||||
|
if (nDebit > 0)
|
||||||
|
{
|
||||||
|
int64 nValueOut = GetValueOut();
|
||||||
|
nFee = nDebit - nValueOut;
|
||||||
|
nSent = nValueOut - GetChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IsConfirmed() const
|
bool IsConfirmed() const
|
||||||
{
|
{
|
||||||
// Quick answer in most cases
|
// Quick answer in most cases
|
||||||
|
|
245
rpc.cpp
245
rpc.cpp
|
@ -71,6 +71,18 @@ int64 AmountFromValue(const Value& value)
|
||||||
return nAmount;
|
return nAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value ValueFromAmount(int64 amount)
|
||||||
|
{
|
||||||
|
return (double)amount / (double)COIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
|
||||||
|
{
|
||||||
|
entry.push_back(Pair("confirmations", wtx.GetDepthInMainChain()));
|
||||||
|
entry.push_back(Pair("txid", wtx.GetHash().GetHex()));
|
||||||
|
foreach(const PAIRTYPE(string,string)& item, wtx.mapValue)
|
||||||
|
entry.push_back(Pair(item.first, item.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -435,27 +447,6 @@ Value sendtoaddress(const Array& params, bool fHelp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Value listtransactions(const Array& params, bool fHelp)
|
|
||||||
{
|
|
||||||
if (fHelp || params.size() > 2)
|
|
||||||
throw runtime_error(
|
|
||||||
"listtransactions [count=10] [includegenerated=false]\n"
|
|
||||||
"Returns up to [count] most recent transactions.");
|
|
||||||
|
|
||||||
int64 nCount = 10;
|
|
||||||
if (params.size() > 0)
|
|
||||||
nCount = params[0].get_int64();
|
|
||||||
bool fGenerated = false;
|
|
||||||
if (params.size() > 1)
|
|
||||||
fGenerated = params[1].get_bool();
|
|
||||||
|
|
||||||
Array ret;
|
|
||||||
//// not finished
|
|
||||||
ret.push_back("not implemented yet");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Value getreceivedbyaddress(const Array& params, bool fHelp)
|
Value getreceivedbyaddress(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||||
|
@ -497,21 +488,8 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Value getreceivedbyaccount(const Array& params, bool fHelp)
|
void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
|
||||||
throw runtime_error(
|
|
||||||
"getreceivedbyaccount <account> [minconf=1]\n"
|
|
||||||
"Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.");
|
|
||||||
|
|
||||||
// Minimum confirmations
|
|
||||||
int nMinDepth = 1;
|
|
||||||
if (params.size() > 1)
|
|
||||||
nMinDepth = params[1].get_int();
|
|
||||||
|
|
||||||
// Get the set of pub keys that have the label
|
|
||||||
string strAccount = params[0].get_str();
|
|
||||||
set<CScript> setPubKey;
|
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
|
foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
|
||||||
|
@ -528,6 +506,25 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Value getreceivedbyaccount(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||||
|
throw runtime_error(
|
||||||
|
"getreceivedbyaccount <account> [minconf=1]\n"
|
||||||
|
"Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.");
|
||||||
|
|
||||||
|
// Minimum confirmations
|
||||||
|
int nMinDepth = 1;
|
||||||
|
if (params.size() > 1)
|
||||||
|
nMinDepth = params[1].get_int();
|
||||||
|
|
||||||
|
// Get the set of pub keys that have the label
|
||||||
|
string strAccount = params[0].get_str();
|
||||||
|
set<CScript> setPubKey;
|
||||||
|
GetAccountPubKeys(strAccount, setPubKey);
|
||||||
|
|
||||||
// Tally
|
// Tally
|
||||||
int64 nAmount = 0;
|
int64 nAmount = 0;
|
||||||
|
@ -552,24 +549,8 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
|
||||||
|
|
||||||
int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
|
int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
|
||||||
{
|
{
|
||||||
// Get the set of pub keys that have the account
|
|
||||||
set<CScript> setPubKey;
|
set<CScript> setPubKey;
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
GetAccountPubKeys(strAccount, setPubKey);
|
||||||
{
|
|
||||||
foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
|
|
||||||
{
|
|
||||||
const string& strAddress = item.first;
|
|
||||||
const string& strName = item.second;
|
|
||||||
if (strName == strAccount)
|
|
||||||
{
|
|
||||||
// We're only counting our own valid bitcoin addresses and not ip addresses
|
|
||||||
CScript scriptPubKey;
|
|
||||||
if (scriptPubKey.SetBitcoinAddress(strAddress))
|
|
||||||
if (IsMine(scriptPubKey))
|
|
||||||
setPubKey.insert(scriptPubKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 nBalance = 0;
|
int64 nBalance = 0;
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(cs_mapWallet)
|
||||||
|
@ -581,26 +562,12 @@ int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinD
|
||||||
if (!wtx.IsFinal())
|
if (!wtx.IsFinal())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Count generated blocks to account ""
|
int64 nGenerated, nReceived, nSent, nFee;
|
||||||
if (wtx.IsCoinBase() && strAccount == "" && wtx.GetBlocksToMaturity() == 0)
|
wtx.GetAccountAmounts(strAccount, setPubKey, nGenerated, nReceived, nSent, nFee);
|
||||||
{
|
|
||||||
nBalance += wtx.GetCredit();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tally received
|
if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
|
||||||
foreach(const CTxOut& txout, wtx.vout)
|
nBalance += nReceived;
|
||||||
if (setPubKey.count(txout.scriptPubKey))
|
nBalance += nGenerated - nSent - nFee;
|
||||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
|
||||||
nBalance += txout.nValue;
|
|
||||||
|
|
||||||
// Tally sent
|
|
||||||
if (wtx.strFromAccount == strAccount)
|
|
||||||
{
|
|
||||||
int64 nNet = wtx.GetCredit() - wtx.GetDebit();
|
|
||||||
if (nNet < 0)
|
|
||||||
nBalance += nNet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tally internal accounting entries
|
// Tally internal accounting entries
|
||||||
|
@ -628,8 +595,6 @@ Value getbalance(const Array& params, bool fHelp)
|
||||||
if (params.size() == 0)
|
if (params.size() == 0)
|
||||||
return ((double)GetBalance() / (double)COIN);
|
return ((double)GetBalance() / (double)COIN);
|
||||||
|
|
||||||
throw runtime_error("under construction"); //// to be released soon
|
|
||||||
|
|
||||||
string strAccount = params[0].get_str();
|
string strAccount = params[0].get_str();
|
||||||
int nMinDepth = 1;
|
int nMinDepth = 1;
|
||||||
if (params.size() > 1)
|
if (params.size() > 1)
|
||||||
|
@ -648,8 +613,6 @@ Value movecmd(const Array& params, bool fHelp)
|
||||||
"move <fromaccount> <toaccount> <amount> [minconf=1] [comment]\n"
|
"move <fromaccount> <toaccount> <amount> [minconf=1] [comment]\n"
|
||||||
"Move from one account in your wallet to another.");
|
"Move from one account in your wallet to another.");
|
||||||
|
|
||||||
throw runtime_error("under construction");
|
|
||||||
|
|
||||||
string strFrom = params[0].get_str();
|
string strFrom = params[0].get_str();
|
||||||
string strTo = params[1].get_str();
|
string strTo = params[1].get_str();
|
||||||
int64 nAmount = AmountFromValue(params[2]);
|
int64 nAmount = AmountFromValue(params[2]);
|
||||||
|
@ -711,8 +674,6 @@ Value sendfrom(const Array& params, bool fHelp)
|
||||||
"sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
|
"sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
|
||||||
"<amount> is a real and is rounded to the nearest 0.01");
|
"<amount> is a real and is rounded to the nearest 0.01");
|
||||||
|
|
||||||
throw runtime_error("under construction");
|
|
||||||
|
|
||||||
string strAccount = params[0].get_str();
|
string strAccount = params[0].get_str();
|
||||||
string strAddress = params[1].get_str();
|
string strAddress = params[1].get_str();
|
||||||
int64 nAmount = AmountFromValue(params[2]);
|
int64 nAmount = AmountFromValue(params[2]);
|
||||||
|
@ -888,6 +849,131 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
|
||||||
return ListReceived(params, true);
|
return ListReceived(params, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ListAccountTransactions(CWalletDB& walletdb, const string& strAccount, int nMinDepth, multimap<int64, Object>& ret)
|
||||||
|
{
|
||||||
|
set<CScript> setPubKey;
|
||||||
|
GetAccountPubKeys(strAccount, setPubKey);
|
||||||
|
|
||||||
|
CRITICAL_BLOCK(cs_mapWallet)
|
||||||
|
{
|
||||||
|
// Wallet: generate/send/receive transactions
|
||||||
|
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
|
{
|
||||||
|
const CWalletTx& wtx = (*it).second;
|
||||||
|
if (!wtx.IsFinal())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int64 nGenerated, nReceived, nSent, nFee;
|
||||||
|
wtx.GetAccountAmounts(strAccount, setPubKey, nGenerated, nReceived, nSent, nFee);
|
||||||
|
|
||||||
|
// Generated blocks count to account ""
|
||||||
|
if (nGenerated != 0)
|
||||||
|
{
|
||||||
|
Object entry;
|
||||||
|
entry.push_back(Pair("category", "generate"));
|
||||||
|
entry.push_back(Pair("amount", ValueFromAmount(nGenerated)));
|
||||||
|
WalletTxToJSON(wtx, entry);
|
||||||
|
ret.insert(make_pair(wtx.GetTxTime(), entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sent
|
||||||
|
if (nSent != 0 || nFee != 0)
|
||||||
|
{
|
||||||
|
Object entry;
|
||||||
|
entry.push_back(Pair("category", "send"));
|
||||||
|
entry.push_back(Pair("amount", ValueFromAmount(-nSent)));
|
||||||
|
entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
|
||||||
|
WalletTxToJSON(wtx, entry);
|
||||||
|
ret.insert(make_pair(wtx.GetTxTime(), entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Received
|
||||||
|
if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
|
||||||
|
{
|
||||||
|
Object entry;
|
||||||
|
entry.push_back(Pair("category", "receive"));
|
||||||
|
entry.push_back(Pair("amount", ValueFromAmount(nReceived)));
|
||||||
|
WalletTxToJSON(wtx, entry);
|
||||||
|
ret.insert(make_pair(wtx.GetTxTime(), entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal accounting entries
|
||||||
|
list<CAccountingEntry> acentries;
|
||||||
|
walletdb.ListAccountCreditDebit(strAccount, acentries);
|
||||||
|
foreach (const CAccountingEntry& acentry, acentries)
|
||||||
|
{
|
||||||
|
Object entry;
|
||||||
|
entry.push_back(Pair("category", "move"));
|
||||||
|
entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
|
||||||
|
entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
|
||||||
|
ret.insert(make_pair(acentry.nTime, entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value listtransactions(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||||
|
throw runtime_error(
|
||||||
|
"listtransactions <account> [count=10]\n"
|
||||||
|
"Returns up to [count] most recent transactions for account <account>.");
|
||||||
|
|
||||||
|
string strAccount = params[0].get_str();
|
||||||
|
int nCount = 10;
|
||||||
|
if (params.size() > 1)
|
||||||
|
nCount = params[1].get_int();
|
||||||
|
|
||||||
|
CWalletDB walletdb;
|
||||||
|
multimap<int64, Object> mapByTime; // keys are transaction time
|
||||||
|
ListAccountTransactions(walletdb, strAccount, 0, mapByTime);
|
||||||
|
|
||||||
|
// Return only last nCount items:
|
||||||
|
int nToErase = mapByTime.size()-nCount;
|
||||||
|
if (nToErase > 0)
|
||||||
|
{
|
||||||
|
multimap<int64, Object>::iterator end = mapByTime.begin();
|
||||||
|
std::advance(end, nToErase);
|
||||||
|
mapByTime.erase(mapByTime.begin(), end);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array ret;
|
||||||
|
foreach(const PAIRTYPE(int64, Object)& item, mapByTime)
|
||||||
|
ret.push_back(item.second);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value gettransaction(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() != 1)
|
||||||
|
throw runtime_error(
|
||||||
|
"gettransaction <txid>\n"
|
||||||
|
"Get detailed information about <txid>");
|
||||||
|
|
||||||
|
uint256 hash;
|
||||||
|
hash.SetHex(params[0].get_str());
|
||||||
|
|
||||||
|
Object entry;
|
||||||
|
CRITICAL_BLOCK(cs_mapWallet)
|
||||||
|
{
|
||||||
|
if (!mapWallet.count(hash))
|
||||||
|
throw JSONRPCError(-5, "Invalid transaction id");
|
||||||
|
const CWalletTx& wtx = mapWallet[hash];
|
||||||
|
|
||||||
|
int64 nCredit = wtx.GetCredit();
|
||||||
|
int64 nDebit = wtx.GetDebit();
|
||||||
|
int64 nNet = nCredit - nDebit;
|
||||||
|
int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
|
||||||
|
|
||||||
|
entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
|
||||||
|
if (wtx.IsFromMe())
|
||||||
|
entry.push_back(Pair("fee", ValueFromAmount(nFee)));
|
||||||
|
WalletTxToJSON(mapWallet[hash], entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Value backupwallet(const Array& params, bool fHelp)
|
Value backupwallet(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
|
@ -1086,6 +1172,8 @@ pair<string, rpcfn_type> pCallTable[] =
|
||||||
make_pair("getbalance", &getbalance),
|
make_pair("getbalance", &getbalance),
|
||||||
make_pair("move", &movecmd),
|
make_pair("move", &movecmd),
|
||||||
make_pair("sendfrom", &sendfrom),
|
make_pair("sendfrom", &sendfrom),
|
||||||
|
make_pair("gettransaction", &gettransaction),
|
||||||
|
make_pair("listtransactions", &listtransactions),
|
||||||
make_pair("getwork", &getwork),
|
make_pair("getwork", &getwork),
|
||||||
};
|
};
|
||||||
map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
|
map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
|
||||||
|
@ -1706,8 +1794,6 @@ int CommandLineRPC(int argc, char *argv[])
|
||||||
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
|
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
|
||||||
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
|
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
|
||||||
if (strMethod == "listtransactions" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
|
||||||
if (strMethod == "listtransactions" && n > 1) ConvertTo<bool>(params[1]);
|
|
||||||
if (strMethod == "getamountreceived" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
|
if (strMethod == "getamountreceived" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
|
||||||
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
|
@ -1725,6 +1811,7 @@ int CommandLineRPC(int argc, char *argv[])
|
||||||
if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
|
if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
|
||||||
if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
|
if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
|
||||||
if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
|
if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
|
||||||
|
if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
Object reply = CallRPC(strMethod, params);
|
Object reply = CallRPC(strMethod, params);
|
||||||
|
|
17
ui.cpp
17
ui.cpp
|
@ -697,16 +697,13 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||||
if (fAllFromMe && fAllToMe)
|
if (fAllFromMe && fAllToMe)
|
||||||
{
|
{
|
||||||
// Payment to self
|
// Payment to self
|
||||||
int64 nValue = wtx.vout[0].nValue;
|
int64 nChange = wtx.GetChange();
|
||||||
InsertLine(fNew, nIndex, hash, strSort, colour,
|
InsertLine(fNew, nIndex, hash, strSort, colour,
|
||||||
strStatus,
|
strStatus,
|
||||||
nTime ? DateTimeStr(nTime) : "",
|
nTime ? DateTimeStr(nTime) : "",
|
||||||
_("Payment to yourself"),
|
_("Payment to yourself"),
|
||||||
"",
|
FormatMoney(-(nDebit - nChange), true),
|
||||||
"");
|
FormatMoney(nCredit - nChange, true));
|
||||||
/// issue: can't tell which is the payment and which is the change anymore
|
|
||||||
// FormatMoney(nNet - nValue, true),
|
|
||||||
// FormatMoney(nValue, true));
|
|
||||||
}
|
}
|
||||||
else if (fAllFromMe)
|
else if (fAllFromMe)
|
||||||
{
|
{
|
||||||
|
@ -1376,10 +1373,10 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails
|
||||||
if (fAllToMe)
|
if (fAllToMe)
|
||||||
{
|
{
|
||||||
// Payment to self
|
// Payment to self
|
||||||
/// issue: can't tell which is the payment and which is the change anymore
|
int64 nChange = wtx.GetChange();
|
||||||
//int64 nValue = wtx.vout[0].nValue;
|
int64 nValue = nCredit - nChange;
|
||||||
//strHTML += _("<b>Debit:</b> ") + FormatMoney(-nValue) + "<br>";
|
strHTML += _("<b>Debit:</b> ") + FormatMoney(-nValue) + "<br>";
|
||||||
//strHTML += _("<b>Credit:</b> ") + FormatMoney(nValue) + "<br>";
|
strHTML += _("<b>Credit:</b> ") + FormatMoney(nValue) + "<br>";
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 nTxFee = nDebit - wtx.GetValueOut();
|
int64 nTxFee = nDebit - wtx.GetValueOut();
|
||||||
|
|
Loading…
Reference in a new issue