Master Core  v0.0.9 - 2abfd2849db8ba7a83957c64eb976b406713c123
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
rpcwallet.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "base58.h"
7 #include "rpcserver.h"
8 #include "init.h"
9 #include "net.h"
10 #include "netbase.h"
11 #include "util.h"
12 #include "wallet.h"
13 #include "walletdb.h"
14 
15 #include <stdint.h>
16 
17 #include <boost/assign/list_of.hpp>
18 #include "json/json_spirit_utils.h"
19 #include "json/json_spirit_value.h"
20 
21 using namespace std;
22 using namespace boost;
23 using namespace boost::assign;
24 using namespace json_spirit;
25 
28 
30 {
31  return pwalletMain && pwalletMain->IsCrypted()
32  ? "\nRequires wallet passphrase to be set with walletpassphrase call."
33  : "";
34 }
35 
37 {
38  if (pwalletMain->IsLocked())
39  throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
40 }
41 
42 void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
43 {
44  int confirms = wtx.GetDepthInMainChain();
45  entry.push_back(Pair("confirmations", confirms));
46  if (wtx.IsCoinBase())
47  entry.push_back(Pair("generated", true));
48  if (confirms > 0)
49  {
50  entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
51  entry.push_back(Pair("blockindex", wtx.nIndex));
52  entry.push_back(Pair("blocktime", (int64_t)(mapBlockIndex[wtx.hashBlock]->nTime)));
53  }
54  uint256 hash = wtx.GetHash();
55  entry.push_back(Pair("txid", hash.GetHex()));
56  Array conflicts;
57  BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts())
58  conflicts.push_back(conflict.GetHex());
59  entry.push_back(Pair("walletconflicts", conflicts));
60  entry.push_back(Pair("time", wtx.GetTxTime()));
61  entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
62  BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
63  entry.push_back(Pair(item.first, item.second));
64 }
65 
66 string AccountFromValue(const Value& value)
67 {
68  string strAccount = value.get_str();
69  if (strAccount == "*")
70  throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
71  return strAccount;
72 }
73 
74 Value getnewaddress(const Array& params, bool fHelp)
75 {
76  if (fHelp || params.size() > 1)
77  throw runtime_error(
78  "getnewaddress ( \"account\" )\n"
79  "\nReturns a new Bitcoin address for receiving payments.\n"
80  "If 'account' is specified (recommended), it is added to the address book \n"
81  "so payments received with the address will be credited to 'account'.\n"
82  "\nArguments:\n"
83  "1. \"account\" (string, optional) The account name for the address to be linked to. if not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
84  "\nResult:\n"
85  "\"bitcoinaddress\" (string) The new bitcoin address\n"
86  "\nExamples:\n"
87  + HelpExampleCli("getnewaddress", "")
88  + HelpExampleCli("getnewaddress", "\"\"")
89  + HelpExampleCli("getnewaddress", "\"myaccount\"")
90  + HelpExampleRpc("getnewaddress", "\"myaccount\"")
91  );
92 
93  // Parse the account first so we don't generate a key if there's an error
94  string strAccount;
95  if (params.size() > 0)
96  strAccount = AccountFromValue(params[0]);
97 
98  if (!pwalletMain->IsLocked())
100 
101  // Generate a new key that is added to wallet
102  CPubKey newKey;
103  if (!pwalletMain->GetKeyFromPool(newKey))
104  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
105  CKeyID keyID = newKey.GetID();
106 
107  pwalletMain->SetAddressBook(keyID, strAccount, "receive");
108 
109  return CBitcoinAddress(keyID).ToString();
110 }
111 
112 
113 CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
114 {
116 
117  CAccount account;
118  walletdb.ReadAccount(strAccount, account);
119 
120  bool bKeyUsed = false;
121 
122  // Check if the current key has been used
123  if (account.vchPubKey.IsValid())
124  {
125  CScript scriptPubKey;
126  scriptPubKey.SetDestination(account.vchPubKey.GetID());
127  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
128  it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
129  ++it)
130  {
131  const CWalletTx& wtx = (*it).second;
132  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
133  if (txout.scriptPubKey == scriptPubKey)
134  bKeyUsed = true;
135  }
136  }
137 
138  // Generate a new key
139  if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
140  {
141  if (!pwalletMain->GetKeyFromPool(account.vchPubKey))
142  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
143 
144  pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive");
145  walletdb.WriteAccount(strAccount, account);
146  }
147 
148  return CBitcoinAddress(account.vchPubKey.GetID());
149 }
150 
151 Value getaccountaddress(const Array& params, bool fHelp)
152 {
153  if (fHelp || params.size() != 1)
154  throw runtime_error(
155  "getaccountaddress \"account\"\n"
156  "\nReturns the current Bitcoin address for receiving payments to this account.\n"
157  "\nArguments:\n"
158  "1. \"account\" (string, required) The account name for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n"
159  "\nResult:\n"
160  "\"bitcoinaddress\" (string) The account bitcoin address\n"
161  "\nExamples:\n"
162  + HelpExampleCli("getaccountaddress", "")
163  + HelpExampleCli("getaccountaddress", "\"\"")
164  + HelpExampleCli("getaccountaddress", "\"myaccount\"")
165  + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
166  );
167 
168  // Parse the account first so we don't generate a key if there's an error
169  string strAccount = AccountFromValue(params[0]);
170 
171  Value ret;
172 
173  ret = GetAccountAddress(strAccount).ToString();
174 
175  return ret;
176 }
177 
178 
179 Value getrawchangeaddress(const Array& params, bool fHelp)
180 {
181  if (fHelp || params.size() > 1)
182  throw runtime_error(
183  "getrawchangeaddress\n"
184  "\nReturns a new Bitcoin address, for receiving change.\n"
185  "This is for use with raw transactions, NOT normal use.\n"
186  "\nResult:\n"
187  "\"address\" (string) The address\n"
188  "\nExamples:\n"
189  + HelpExampleCli("getrawchangeaddress", "")
190  + HelpExampleRpc("getrawchangeaddress", "")
191  );
192 
193  if (!pwalletMain->IsLocked())
195 
196  CReserveKey reservekey(pwalletMain);
197  CPubKey vchPubKey;
198  if (!reservekey.GetReservedKey(vchPubKey))
199  throw JSONRPCError(RPC_WALLET_ERROR, "Error: Unable to obtain key for change");
200 
201  reservekey.KeepKey();
202 
203  CKeyID keyID = vchPubKey.GetID();
204 
205  return CBitcoinAddress(keyID).ToString();
206 }
207 
208 
209 Value setaccount(const Array& params, bool fHelp)
210 {
211  if (fHelp || params.size() < 1 || params.size() > 2)
212  throw runtime_error(
213  "setaccount \"bitcoinaddress\" \"account\"\n"
214  "\nSets the account associated with the given address.\n"
215  "\nArguments:\n"
216  "1. \"bitcoinaddress\" (string, required) The bitcoin address to be associated with an account.\n"
217  "2. \"account\" (string, required) The account to assign the address to.\n"
218  "\nExamples:\n"
219  + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"tabby\"")
220  + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"")
221  );
222 
223  CBitcoinAddress address(params[0].get_str());
224  if (!address.IsValid())
225  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
226 
227 
228  string strAccount;
229  if (params.size() > 1)
230  strAccount = AccountFromValue(params[1]);
231 
232  // Detect when changing the account of an address that is the 'unused current key' of another account:
233  if (pwalletMain->mapAddressBook.count(address.Get()))
234  {
235  string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name;
236  if (address == GetAccountAddress(strOldAccount))
237  GetAccountAddress(strOldAccount, true);
238  }
239 
240  pwalletMain->SetAddressBook(address.Get(), strAccount, "receive");
241 
242  return Value::null;
243 }
244 
245 
246 Value getaccount(const Array& params, bool fHelp)
247 {
248  if (fHelp || params.size() != 1)
249  throw runtime_error(
250  "getaccount \"bitcoinaddress\"\n"
251  "\nReturns the account associated with the given address.\n"
252  "\nArguments:\n"
253  "1. \"bitcoinaddress\" (string, required) The bitcoin address for account lookup.\n"
254  "\nResult:\n"
255  "\"accountname\" (string) the account address\n"
256  "\nExamples:\n"
257  + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"")
258  + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"")
259  );
260 
261  CBitcoinAddress address(params[0].get_str());
262  if (!address.IsValid())
263  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
264 
265  string strAccount;
266  map<CTxDestination, CAddressBookData>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
267  if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty())
268  strAccount = (*mi).second.name;
269  return strAccount;
270 }
271 
272 
273 Value getaddressesbyaccount(const Array& params, bool fHelp)
274 {
275  if (fHelp || params.size() != 1)
276  throw runtime_error(
277  "getaddressesbyaccount \"account\"\n"
278  "\nReturns the list of addresses for the given account.\n"
279  "\nArguments:\n"
280  "1. \"account\" (string, required) The account name.\n"
281  "\nResult:\n"
282  "[ (json array of string)\n"
283  " \"bitcoinaddress\" (string) a bitcoin address associated with the given account\n"
284  " ,...\n"
285  "]\n"
286  "\nExamples:\n"
287  + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
288  + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
289  );
290 
291  string strAccount = AccountFromValue(params[0]);
292 
293  // Find all addresses that have the given account
294  Array ret;
296  {
297  const CBitcoinAddress& address = item.first;
298  const string& strName = item.second.name;
299  if (strName == strAccount)
300  ret.push_back(address.ToString());
301  }
302  return ret;
303 }
304 
305 Value sendtoaddress(const Array& params, bool fHelp)
306 {
307  if (fHelp || params.size() < 2 || params.size() > 4)
308  throw runtime_error(
309  "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" )\n"
310  "\nSent an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n"
312  "\nArguments:\n"
313  "1. \"bitcoinaddress\" (string, required) The bitcoin address to send to.\n"
314  "2. \"amount\" (numeric, required) The amount in btc to send. eg 0.1\n"
315  "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
316  " This is not part of the transaction, just kept in your wallet.\n"
317  "4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n"
318  " to which you're sending the transaction. This is not part of the \n"
319  " transaction, just kept in your wallet.\n"
320  "\nResult:\n"
321  "\"transactionid\" (string) The transaction id.\n"
322  "\nExamples:\n"
323  + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
324  + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
325  + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
326  );
327 
328  CBitcoinAddress address(params[0].get_str());
329  if (!address.IsValid())
330  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
331 
332  // Amount
333  int64_t nAmount = AmountFromValue(params[1]);
334 
335  // Wallet comments
336  CWalletTx wtx;
337  if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty())
338  wtx.mapValue["comment"] = params[2].get_str();
339  if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
340  wtx.mapValue["to"] = params[3].get_str();
341 
343 
344  string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
345  if (strError != "")
346  throw JSONRPCError(RPC_WALLET_ERROR, strError);
347 
348  return wtx.GetHash().GetHex();
349 }
350 
351 Value listaddressgroupings(const Array& params, bool fHelp)
352 {
353  if (fHelp)
354  throw runtime_error(
355  "listaddressgroupings\n"
356  "\nLists groups of addresses which have had their common ownership\n"
357  "made public by common use as inputs or as the resulting change\n"
358  "in past transactions\n"
359  "\nResult:\n"
360  "[\n"
361  " [\n"
362  " [\n"
363  " \"bitcoinaddress\", (string) The bitcoin address\n"
364  " amount, (numeric) The amount in btc\n"
365  " \"account\" (string, optional) The account\n"
366  " ]\n"
367  " ,...\n"
368  " ]\n"
369  " ,...\n"
370  "]\n"
371  "\nExamples:\n"
372  + HelpExampleCli("listaddressgroupings", "")
373  + HelpExampleRpc("listaddressgroupings", "")
374  );
375 
376  Array jsonGroupings;
377  map<CTxDestination, int64_t> balances = pwalletMain->GetAddressBalances();
378  BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
379  {
380  Array jsonGrouping;
381  BOOST_FOREACH(CTxDestination address, grouping)
382  {
383  Array addressInfo;
384  addressInfo.push_back(CBitcoinAddress(address).ToString());
385  addressInfo.push_back(ValueFromAmount(balances[address]));
386  {
388  if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end())
389  addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name);
390  }
391  jsonGrouping.push_back(addressInfo);
392  }
393  jsonGroupings.push_back(jsonGrouping);
394  }
395  return jsonGroupings;
396 }
397 
398 Value signmessage(const Array& params, bool fHelp)
399 {
400  if (fHelp || params.size() != 2)
401  throw runtime_error(
402  "signmessage \"bitcoinaddress\" \"message\"\n"
403  "\nSign a message with the private key of an address"
404  + HelpRequiringPassphrase() + "\n"
405  "\nArguments:\n"
406  "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the private key.\n"
407  "2. \"message\" (string, required) The message to create a signature of.\n"
408  "\nResult:\n"
409  "\"signature\" (string) The signature of the message encoded in base 64\n"
410  "\nExamples:\n"
411  "\nUnlock the wallet for 30 seconds\n"
412  + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
413  "\nCreate the signature\n"
414  + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
415  "\nVerify the signature\n"
416  + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
417  "\nAs json rpc\n"
418  + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"")
419  );
420 
422 
423  string strAddress = params[0].get_str();
424  string strMessage = params[1].get_str();
425 
426  CBitcoinAddress addr(strAddress);
427  if (!addr.IsValid())
428  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
429 
430  CKeyID keyID;
431  if (!addr.GetKeyID(keyID))
432  throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
433 
434  CKey key;
435  if (!pwalletMain->GetKey(keyID, key))
436  throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
437 
438  CHashWriter ss(SER_GETHASH, 0);
439  ss << strMessageMagic;
440  ss << strMessage;
441 
442  vector<unsigned char> vchSig;
443  if (!key.SignCompact(ss.GetHash(), vchSig))
444  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
445 
446  return EncodeBase64(&vchSig[0], vchSig.size());
447 }
448 
449 Value getreceivedbyaddress(const Array& params, bool fHelp)
450 {
451  if (fHelp || params.size() < 1 || params.size() > 2)
452  throw runtime_error(
453  "getreceivedbyaddress \"bitcoinaddress\" ( minconf )\n"
454  "\nReturns the total amount received by the given bitcoinaddress in transactions with at least minconf confirmations.\n"
455  "\nArguments:\n"
456  "1. \"bitcoinaddress\" (string, required) The bitcoin address for transactions.\n"
457  "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
458  "\nResult:\n"
459  "amount (numeric) The total amount in btc received at this address.\n"
460  "\nExamples:\n"
461  "\nThe amount from transactions with at least 1 confirmation\n"
462  + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") +
463  "\nThe amount including unconfirmed transactions, zero confirmations\n"
464  + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 0") +
465  "\nThe amount with at least 6 confirmation, very safe\n"
466  + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 6") +
467  "\nAs a json rpc call\n"
468  + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6")
469  );
470 
471  // Bitcoin address
472  CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
473  CScript scriptPubKey;
474  if (!address.IsValid())
475  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
476  scriptPubKey.SetDestination(address.Get());
477  if (!IsMine(*pwalletMain,scriptPubKey))
478  return (double)0.0;
479 
480  // Minimum confirmations
481  int nMinDepth = 1;
482  if (params.size() > 1)
483  nMinDepth = params[1].get_int();
484 
485  // Tally
486  int64_t nAmount = 0;
487  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
488  {
489  const CWalletTx& wtx = (*it).second;
490  if (wtx.IsCoinBase() || !IsFinalTx(wtx))
491  continue;
492 
493  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
494  if (txout.scriptPubKey == scriptPubKey)
495  if (wtx.GetDepthInMainChain() >= nMinDepth)
496  nAmount += txout.nValue;
497  }
498 
499  return ValueFromAmount(nAmount);
500 }
501 
502 
503 Value getreceivedbyaccount(const Array& params, bool fHelp)
504 {
505  if (fHelp || params.size() < 1 || params.size() > 2)
506  throw runtime_error(
507  "getreceivedbyaccount \"account\" ( minconf )\n"
508  "\nReturns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
509  "\nArguments:\n"
510  "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
511  "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
512  "\nResult:\n"
513  "amount (numeric) The total amount in btc received for this account.\n"
514  "\nExamples:\n"
515  "\nAmount received by the default account with at least 1 confirmation\n"
516  + HelpExampleCli("getreceivedbyaccount", "\"\"") +
517  "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
518  + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
519  "\nThe amount with at least 6 confirmation, very safe\n"
520  + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
521  "\nAs a json rpc call\n"
522  + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
523  );
524 
525  // Minimum confirmations
526  int nMinDepth = 1;
527  if (params.size() > 1)
528  nMinDepth = params[1].get_int();
529 
530  // Get the set of pub keys assigned to account
531  string strAccount = AccountFromValue(params[0]);
532  set<CTxDestination> setAddress = pwalletMain->GetAccountAddresses(strAccount);
533 
534  // Tally
535  int64_t nAmount = 0;
536  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
537  {
538  const CWalletTx& wtx = (*it).second;
539  if (wtx.IsCoinBase() || !IsFinalTx(wtx))
540  continue;
541 
542  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
543  {
544  CTxDestination address;
545  if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
546  if (wtx.GetDepthInMainChain() >= nMinDepth)
547  nAmount += txout.nValue;
548  }
549  }
550 
551  return (double)nAmount / (double)COIN;
552 }
553 
554 
555 int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
556 {
557  int64_t nBalance = 0;
558 
559  // Tally wallet transactions
560  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
561  {
562  const CWalletTx& wtx = (*it).second;
563  if (!IsFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0)
564  continue;
565 
566  int64_t nReceived, nSent, nFee;
567  wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee);
568 
569  if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
570  nBalance += nReceived;
571  nBalance -= nSent + nFee;
572  }
573 
574  // Tally internal accounting entries
575  nBalance += walletdb.GetAccountCreditDebit(strAccount);
576 
577  return nBalance;
578 }
579 
580 int64_t GetAccountBalance(const string& strAccount, int nMinDepth)
581 {
583  return GetAccountBalance(walletdb, strAccount, nMinDepth);
584 }
585 
586 
587 Value getbalance(const Array& params, bool fHelp)
588 {
589  if (fHelp || params.size() > 2)
590  throw runtime_error(
591  "getbalance ( \"account\" minconf )\n"
592  "\nIf account is not specified, returns the server's total available balance.\n"
593  "If account is specified, returns the balance in the account.\n"
594  "Note that the account \"\" is not the same as leaving the parameter out.\n"
595  "The server total may be different to the balance in the default \"\" account.\n"
596  "\nArguments:\n"
597  "1. \"account\" (string, optional) The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
598  "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
599  "\nResult:\n"
600  "amount (numeric) The total amount in btc received for this account.\n"
601  "\nExamples:\n"
602  "\nThe total amount in the server across all accounts\n"
603  + HelpExampleCli("getbalance", "") +
604  "\nThe total amount in the server across all accounts, with at least 5 confirmations\n"
605  + HelpExampleCli("getbalance", "\"*\" 6") +
606  "\nThe total amount in the default account with at least 1 confirmation\n"
607  + HelpExampleCli("getbalance", "\"\"") +
608  "\nThe total amount in the account named tabby with at least 6 confirmations\n"
609  + HelpExampleCli("getbalance", "\"tabby\" 6") +
610  "\nAs a json rpc call\n"
611  + HelpExampleRpc("getbalance", "\"tabby\", 6")
612  );
613 
614  if (params.size() == 0)
616 
617  int nMinDepth = 1;
618  if (params.size() > 1)
619  nMinDepth = params[1].get_int();
620 
621  if (params[0].get_str() == "*") {
622  // Calculate total balance a different way from GetBalance()
623  // (GetBalance() sums up all unspent TxOuts)
624  // getbalance and getbalance '*' 0 should return the same number
625  int64_t nBalance = 0;
626  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
627  {
628  const CWalletTx& wtx = (*it).second;
629  if (!wtx.IsTrusted() || wtx.GetBlocksToMaturity() > 0)
630  continue;
631 
632  int64_t allFee;
633  string strSentAccount;
634  list<pair<CTxDestination, int64_t> > listReceived;
635  list<pair<CTxDestination, int64_t> > listSent;
636  wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount);
637  if (wtx.GetDepthInMainChain() >= nMinDepth)
638  {
639  BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
640  nBalance += r.second;
641  }
642  BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listSent)
643  nBalance -= r.second;
644  nBalance -= allFee;
645  }
646  return ValueFromAmount(nBalance);
647  }
648 
649  string strAccount = AccountFromValue(params[0]);
650 
651  int64_t nBalance = GetAccountBalance(strAccount, nMinDepth);
652 
653  return ValueFromAmount(nBalance);
654 }
655 
656 Value getunconfirmedbalance(const Array &params, bool fHelp)
657 {
658  if (fHelp || params.size() > 0)
659  throw runtime_error(
660  "getunconfirmedbalance\n"
661  "Returns the server's total unconfirmed balance\n");
663 }
664 
665 
666 Value movecmd(const Array& params, bool fHelp)
667 {
668  if (fHelp || params.size() < 3 || params.size() > 5)
669  throw runtime_error(
670  "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
671  "\nMove a specified amount from one account in your wallet to another.\n"
672  "\nArguments:\n"
673  "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
674  "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
675  "3. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
676  "4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
677  "\nResult:\n"
678  "true|false (boolean) true if successfull.\n"
679  "\nExamples:\n"
680  "\nMove 0.01 btc from the default account to the account named tabby\n"
681  + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
682  "\nMove 0.01 btc timotei to akiko with a comment and funds have 6 confirmations\n"
683  + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
684  "\nAs a json rpc call\n"
685  + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
686  );
687 
688  string strFrom = AccountFromValue(params[0]);
689  string strTo = AccountFromValue(params[1]);
690  int64_t nAmount = AmountFromValue(params[2]);
691  if (params.size() > 3)
692  // unused parameter, used to be nMinDepth, keep type-checking it though
693  (void)params[3].get_int();
694  string strComment;
695  if (params.size() > 4)
696  strComment = params[4].get_str();
697 
699  if (!walletdb.TxnBegin())
700  throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
701 
702  int64_t nNow = GetAdjustedTime();
703 
704  // Debit
705  CAccountingEntry debit;
706  debit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
707  debit.strAccount = strFrom;
708  debit.nCreditDebit = -nAmount;
709  debit.nTime = nNow;
710  debit.strOtherAccount = strTo;
711  debit.strComment = strComment;
712  walletdb.WriteAccountingEntry(debit);
713 
714  // Credit
715  CAccountingEntry credit;
716  credit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
717  credit.strAccount = strTo;
718  credit.nCreditDebit = nAmount;
719  credit.nTime = nNow;
720  credit.strOtherAccount = strFrom;
721  credit.strComment = strComment;
722  walletdb.WriteAccountingEntry(credit);
723 
724  if (!walletdb.TxnCommit())
725  throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
726 
727  return true;
728 }
729 
730 
731 Value sendfrom(const Array& params, bool fHelp)
732 {
733  if (fHelp || params.size() < 3 || params.size() > 6)
734  throw runtime_error(
735  "sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n"
736  "\nSent an amount from an account to a bitcoin address.\n"
737  "The amount is a real and is rounded to the nearest 0.00000001."
738  + HelpRequiringPassphrase() + "\n"
739  "\nArguments:\n"
740  "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
741  "2. \"tobitcoinaddress\" (string, required) The bitcoin address to send funds to.\n"
742  "3. amount (numeric, required) The amount in btc. (transaction fee is added on top).\n"
743  "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
744  "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
745  " This is not part of the transaction, just kept in your wallet.\n"
746  "6. \"comment-to\" (string, optional) An optional comment to store the name of the person or organization \n"
747  " to which you're sending the transaction. This is not part of the transaction, \n"
748  " it is just kept in your wallet.\n"
749  "\nResult:\n"
750  "\"transactionid\" (string) The transaction id.\n"
751  "\nExamples:\n"
752  "\nSend 0.01 btc from the default account to the address, must have at least 1 confirmation\n"
753  + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
754  "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
755  + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
756  "\nAs a json rpc call\n"
757  + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
758  );
759 
760  string strAccount = AccountFromValue(params[0]);
761  CBitcoinAddress address(params[1].get_str());
762  if (!address.IsValid())
763  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
764  int64_t nAmount = AmountFromValue(params[2]);
765  int nMinDepth = 1;
766  if (params.size() > 3)
767  nMinDepth = params[3].get_int();
768 
769  CWalletTx wtx;
770  wtx.strFromAccount = strAccount;
771  if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty())
772  wtx.mapValue["comment"] = params[4].get_str();
773  if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty())
774  wtx.mapValue["to"] = params[5].get_str();
775 
777 
778  // Check funds
779  int64_t nBalance = GetAccountBalance(strAccount, nMinDepth);
780  if (nAmount > nBalance)
781  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
782 
783  // Send
784  string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
785  if (strError != "")
786  throw JSONRPCError(RPC_WALLET_ERROR, strError);
787 
788  return wtx.GetHash().GetHex();
789 }
790 
791 
792 Value sendmany(const Array& params, bool fHelp)
793 {
794  if (fHelp || params.size() < 2 || params.size() > 4)
795  throw runtime_error(
796  "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" )\n"
797  "\nSend multiple times. Amounts are double-precision floating point numbers."
798  + HelpRequiringPassphrase() + "\n"
799  "\nArguments:\n"
800  "1. \"fromaccount\" (string, required) The account to send the funds from, can be \"\" for the default account\n"
801  "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
802  " {\n"
803  " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in btc is the value\n"
804  " ,...\n"
805  " }\n"
806  "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
807  "4. \"comment\" (string, optional) A comment\n"
808  "\nResult:\n"
809  "\"transactionid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
810  " the number of addresses.\n"
811  "\nExamples:\n"
812  "\nSend two amounts to two different addresses:\n"
813  + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
814  "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
815  + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
816  "\nAs a json rpc call\n"
817  + HelpExampleRpc("sendmany", "\"tabby\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
818  );
819 
820  string strAccount = AccountFromValue(params[0]);
821  Object sendTo = params[1].get_obj();
822  int nMinDepth = 1;
823  if (params.size() > 2)
824  nMinDepth = params[2].get_int();
825 
826  CWalletTx wtx;
827  wtx.strFromAccount = strAccount;
828  if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
829  wtx.mapValue["comment"] = params[3].get_str();
830 
831  set<CBitcoinAddress> setAddress;
832  vector<pair<CScript, int64_t> > vecSend;
833 
834  int64_t totalAmount = 0;
835  BOOST_FOREACH(const Pair& s, sendTo)
836  {
837  CBitcoinAddress address(s.name_);
838  if (!address.IsValid())
839  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
840 
841  if (setAddress.count(address))
842  throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
843  setAddress.insert(address);
844 
845  CScript scriptPubKey;
846  scriptPubKey.SetDestination(address.Get());
847  int64_t nAmount = AmountFromValue(s.value_);
848  totalAmount += nAmount;
849 
850  vecSend.push_back(make_pair(scriptPubKey, nAmount));
851  }
852 
854 
855  // Check funds
856  int64_t nBalance = GetAccountBalance(strAccount, nMinDepth);
857  if (totalAmount > nBalance)
858  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
859 
860  // Send
861  CReserveKey keyChange(pwalletMain);
862  int64_t nFeeRequired = 0;
863  string strFailReason;
864  bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason);
865  if (!fCreated)
866  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
867  if (!pwalletMain->CommitTransaction(wtx, keyChange))
868  throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed");
869 
870  return wtx.GetHash().GetHex();
871 }
872 
873 // Defined in rpcmisc.cpp
874 extern CScript _createmultisig_redeemScript(const Array& params);
875 
876 Value addmultisigaddress(const Array& params, bool fHelp)
877 {
878  if (fHelp || params.size() < 2 || params.size() > 3)
879  {
880  string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
881  "\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
882  "Each key is a Bitcoin address or hex-encoded public key.\n"
883  "If 'account' is specified, assign address to that account.\n"
884 
885  "\nArguments:\n"
886  "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
887  "2. \"keysobject\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
888  " [\n"
889  " \"address\" (string) bitcoin address or hex-encoded public key\n"
890  " ...,\n"
891  " ]\n"
892  "3. \"account\" (string, optional) An account to assign the addresses to.\n"
893 
894  "\nResult:\n"
895  "\"bitcoinaddress\" (string) A bitcoin address associated with the keys.\n"
896 
897  "\nExamples:\n"
898  "\nAdd a multisig address from 2 addresses\n"
899  + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
900  "\nAs json rpc call\n"
901  + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
902  ;
903  throw runtime_error(msg);
904  }
905 
906  string strAccount;
907  if (params.size() > 2)
908  strAccount = AccountFromValue(params[2]);
909 
910  // Construct using pay-to-script-hash:
911  CScript inner = _createmultisig_redeemScript(params);
912  CScriptID innerID = inner.GetID();
913  pwalletMain->AddCScript(inner);
914 
915  pwalletMain->SetAddressBook(innerID, strAccount, "send");
916  return CBitcoinAddress(innerID).ToString();
917 }
918 
919 
920 struct tallyitem
921 {
922  int64_t nAmount;
923  int nConf;
924  vector<uint256> txids;
926  {
927  nAmount = 0;
928  nConf = std::numeric_limits<int>::max();
929  }
930 };
931 
932 Value ListReceived(const Array& params, bool fByAccounts)
933 {
934  // Minimum confirmations
935  int nMinDepth = 1;
936  if (params.size() > 0)
937  nMinDepth = params[0].get_int();
938 
939  // Whether to include empty accounts
940  bool fIncludeEmpty = false;
941  if (params.size() > 1)
942  fIncludeEmpty = params[1].get_bool();
943 
944  // Tally
945  map<CBitcoinAddress, tallyitem> mapTally;
946  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
947  {
948  const CWalletTx& wtx = (*it).second;
949 
950  if (wtx.IsCoinBase() || !IsFinalTx(wtx))
951  continue;
952 
953  int nDepth = wtx.GetDepthInMainChain();
954  if (nDepth < nMinDepth)
955  continue;
956 
957  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
958  {
959  CTxDestination address;
960  if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address))
961  continue;
962 
963  tallyitem& item = mapTally[address];
964  item.nAmount += txout.nValue;
965  item.nConf = min(item.nConf, nDepth);
966  item.txids.push_back(wtx.GetHash());
967  }
968  }
969 
970  // Reply
971  Array ret;
972  map<string, tallyitem> mapAccountTally;
974  {
975  const CBitcoinAddress& address = item.first;
976  const string& strAccount = item.second.name;
977  map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
978  if (it == mapTally.end() && !fIncludeEmpty)
979  continue;
980 
981  int64_t nAmount = 0;
982  int nConf = std::numeric_limits<int>::max();
983  if (it != mapTally.end())
984  {
985  nAmount = (*it).second.nAmount;
986  nConf = (*it).second.nConf;
987  }
988 
989  if (fByAccounts)
990  {
991  tallyitem& item = mapAccountTally[strAccount];
992  item.nAmount += nAmount;
993  item.nConf = min(item.nConf, nConf);
994  }
995  else
996  {
997  Object obj;
998  obj.push_back(Pair("address", address.ToString()));
999  obj.push_back(Pair("account", strAccount));
1000  obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1001  obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1002  Array transactions;
1003  if (it != mapTally.end())
1004  {
1005  BOOST_FOREACH(const uint256& item, (*it).second.txids)
1006  {
1007  transactions.push_back(item.GetHex());
1008  }
1009  }
1010  obj.push_back(Pair("txids", transactions));
1011  ret.push_back(obj);
1012  }
1013  }
1014 
1015  if (fByAccounts)
1016  {
1017  for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
1018  {
1019  int64_t nAmount = (*it).second.nAmount;
1020  int nConf = (*it).second.nConf;
1021  Object obj;
1022  obj.push_back(Pair("account", (*it).first));
1023  obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1024  obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1025  ret.push_back(obj);
1026  }
1027  }
1028 
1029  return ret;
1030 }
1031 
1032 Value listreceivedbyaddress(const Array& params, bool fHelp)
1033 {
1034  if (fHelp || params.size() > 2)
1035  throw runtime_error(
1036  "listreceivedbyaddress ( minconf includeempty )\n"
1037  "\nList balances by receiving address.\n"
1038  "\nArguments:\n"
1039  "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1040  "2. includeempty (numeric, optional, dafault=false) Whether to include addresses that haven't received any payments.\n"
1041 
1042  "\nResult:\n"
1043  "[\n"
1044  " {\n"
1045  " \"address\" : \"receivingaddress\", (string) The receiving address\n"
1046  " \"account\" : \"accountname\", (string) The account of the receiving address. The default account is \"\".\n"
1047  " \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n"
1048  " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
1049  " }\n"
1050  " ,...\n"
1051  "]\n"
1052 
1053  "\nExamples:\n"
1054  + HelpExampleCli("listreceivedbyaddress", "")
1055  + HelpExampleCli("listreceivedbyaddress", "6 true")
1056  + HelpExampleRpc("listreceivedbyaddress", "6, true")
1057  );
1058 
1059  return ListReceived(params, false);
1060 }
1061 
1062 Value listreceivedbyaccount(const Array& params, bool fHelp)
1063 {
1064  if (fHelp || params.size() > 2)
1065  throw runtime_error(
1066  "listreceivedbyaccount ( minconf includeempty )\n"
1067  "\nList balances by account.\n"
1068  "\nArguments:\n"
1069  "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1070  "2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n"
1071 
1072  "\nResult:\n"
1073  "[\n"
1074  " {\n"
1075  " \"account\" : \"accountname\", (string) The account name of the receiving account\n"
1076  " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
1077  " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
1078  " }\n"
1079  " ,...\n"
1080  "]\n"
1081 
1082  "\nExamples:\n"
1083  + HelpExampleCli("listreceivedbyaccount", "")
1084  + HelpExampleCli("listreceivedbyaccount", "6 true")
1085  + HelpExampleRpc("listreceivedbyaccount", "6, true")
1086  );
1087 
1088  return ListReceived(params, true);
1089 }
1090 
1091 static void MaybePushAddress(Object & entry, const CTxDestination &dest)
1092 {
1093  CBitcoinAddress addr;
1094  if (addr.Set(dest))
1095  entry.push_back(Pair("address", addr.ToString()));
1096 }
1097 
1098 void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
1099 {
1100  int64_t nFee;
1101  string strSentAccount;
1102  list<pair<CTxDestination, int64_t> > listReceived;
1103  list<pair<CTxDestination, int64_t> > listSent;
1104 
1105  wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount);
1106 
1107  bool fAllAccounts = (strAccount == string("*"));
1108 
1109  // Sent
1110  if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1111  {
1112  BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent)
1113  {
1114  Object entry;
1115  entry.push_back(Pair("account", strSentAccount));
1116  MaybePushAddress(entry, s.first);
1117  entry.push_back(Pair("category", "send"));
1118  entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
1119  entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1120  if (fLong)
1121  WalletTxToJSON(wtx, entry);
1122  ret.push_back(entry);
1123  }
1124  }
1125 
1126  // Received
1127  if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1128  {
1129  BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived)
1130  {
1131  string account;
1132  if (pwalletMain->mapAddressBook.count(r.first))
1133  account = pwalletMain->mapAddressBook[r.first].name;
1134  if (fAllAccounts || (account == strAccount))
1135  {
1136  Object entry;
1137  entry.push_back(Pair("account", account));
1138  MaybePushAddress(entry, r.first);
1139  if (wtx.IsCoinBase())
1140  {
1141  if (wtx.GetDepthInMainChain() < 1)
1142  entry.push_back(Pair("category", "orphan"));
1143  else if (wtx.GetBlocksToMaturity() > 0)
1144  entry.push_back(Pair("category", "immature"));
1145  else
1146  entry.push_back(Pair("category", "generate"));
1147  }
1148  else
1149  {
1150  entry.push_back(Pair("category", "receive"));
1151  }
1152  entry.push_back(Pair("amount", ValueFromAmount(r.second)));
1153  if (fLong)
1154  WalletTxToJSON(wtx, entry);
1155  ret.push_back(entry);
1156  }
1157  }
1158  }
1159 }
1160 
1161 void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret)
1162 {
1163  bool fAllAccounts = (strAccount == string("*"));
1164 
1165  if (fAllAccounts || acentry.strAccount == strAccount)
1166  {
1167  Object entry;
1168  entry.push_back(Pair("account", acentry.strAccount));
1169  entry.push_back(Pair("category", "move"));
1170  entry.push_back(Pair("time", acentry.nTime));
1171  entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1172  entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1173  entry.push_back(Pair("comment", acentry.strComment));
1174  ret.push_back(entry);
1175  }
1176 }
1177 
1178 Value listtransactions(const Array& params, bool fHelp)
1179 {
1180  if (fHelp || params.size() > 3)
1181  throw runtime_error(
1182  "listtransactions ( \"account\" count from )\n"
1183  "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
1184  "\nArguments:\n"
1185  "1. \"account\" (string, optional) The account name. If not included, it will list all transactions for all accounts.\n"
1186  " If \"\" is set, it will list transactions for the default account.\n"
1187  "2. count (numeric, optional, default=10) The number of transactions to return\n"
1188  "3. from (numeric, optional, default=0) The number of transactions to skip\n"
1189 
1190  "\nResult:\n"
1191  "[\n"
1192  " {\n"
1193  " \"account\":\"accountname\", (string) The account name associated with the transaction. \n"
1194  " It will be \"\" for the default account.\n"
1195  " \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for \n"
1196  " move transactions (category = move).\n"
1197  " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
1198  " transaction between accounts, and not associated with an address,\n"
1199  " transaction id or block. 'send' and 'receive' transactions are \n"
1200  " associated with an address, transaction id and block details\n"
1201  " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the\n"
1202  " 'move' category for moves outbound. It is positive for the 'receive' category,\n"
1203  " and for the 'move' category for inbound funds.\n"
1204  " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the \n"
1205  " 'send' category of transactions.\n"
1206  " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
1207  " 'receive' category of transactions.\n"
1208  " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
1209  " category of transactions.\n"
1210  " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n"
1211  " category of transactions.\n"
1212  " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1213  " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
1214  " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
1215  " for 'send' and 'receive' category of transactions.\n"
1216  " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1217  " \"otheraccount\": \"accountname\", (string) For the 'move' category of transactions, the account the funds came \n"
1218  " from (for receiving funds, positive amounts), or went to (for sending funds,\n"
1219  " negative amounts).\n"
1220  " }\n"
1221  "]\n"
1222 
1223  "\nExamples:\n"
1224  "\nList the most recent 10 transactions in the systems\n"
1225  + HelpExampleCli("listtransactions", "") +
1226  "\nList the most recent 10 transactions for the tabby account\n"
1227  + HelpExampleCli("listtransactions", "\"tabby\"") +
1228  "\nList transactions 100 to 120 from the tabby account\n"
1229  + HelpExampleCli("listtransactions", "\"tabby\" 20 100") +
1230  "\nAs a json rpc call\n"
1231  + HelpExampleRpc("listtransactions", "\"tabby\", 20, 100")
1232  );
1233 
1234  string strAccount = "*";
1235  if (params.size() > 0)
1236  strAccount = params[0].get_str();
1237  int nCount = 10;
1238  if (params.size() > 1)
1239  nCount = params[1].get_int();
1240  int nFrom = 0;
1241  if (params.size() > 2)
1242  nFrom = params[2].get_int();
1243 
1244  if (nCount < 0)
1245  throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
1246  if (nFrom < 0)
1247  throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
1248 
1249  Array ret;
1250 
1251  std::list<CAccountingEntry> acentries;
1252  CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount);
1253 
1254  // iterate backwards until we have nCount items to return:
1255  for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1256  {
1257  CWalletTx *const pwtx = (*it).second.first;
1258  if (pwtx != 0)
1259  ListTransactions(*pwtx, strAccount, 0, true, ret);
1260  CAccountingEntry *const pacentry = (*it).second.second;
1261  if (pacentry != 0)
1262  AcentryToJSON(*pacentry, strAccount, ret);
1263 
1264  if ((int)ret.size() >= (nCount+nFrom)) break;
1265  }
1266  // ret is newest to oldest
1267 
1268  if (nFrom > (int)ret.size())
1269  nFrom = ret.size();
1270  if ((nFrom + nCount) > (int)ret.size())
1271  nCount = ret.size() - nFrom;
1272  Array::iterator first = ret.begin();
1273  std::advance(first, nFrom);
1274  Array::iterator last = ret.begin();
1275  std::advance(last, nFrom+nCount);
1276 
1277  if (last != ret.end()) ret.erase(last, ret.end());
1278  if (first != ret.begin()) ret.erase(ret.begin(), first);
1279 
1280  std::reverse(ret.begin(), ret.end()); // Return oldest to newest
1281 
1282  return ret;
1283 }
1284 
1285 Value listaccounts(const Array& params, bool fHelp)
1286 {
1287  if (fHelp || params.size() > 1)
1288  throw runtime_error(
1289  "listaccounts ( minconf )\n"
1290  "\nReturns Object that has account names as keys, account balances as values.\n"
1291  "\nArguments:\n"
1292  "1. minconf (numeric, optional, default=1) Only onclude transactions with at least this many confirmations\n"
1293  "\nResult:\n"
1294  "{ (json object where keys are account names, and values are numeric balances\n"
1295  " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
1296  " ...\n"
1297  "}\n"
1298  "\nExamples:\n"
1299  "\nList account balances where there at least 1 confirmation\n"
1300  + HelpExampleCli("listaccounts", "") +
1301  "\nList account balances including zero confirmation transactions\n"
1302  + HelpExampleCli("listaccounts", "0") +
1303  "\nList account balances for 6 or more confirmations\n"
1304  + HelpExampleCli("listaccounts", "6") +
1305  "\nAs json rpc call\n"
1306  + HelpExampleRpc("listaccounts", "6")
1307  );
1308 
1309  int nMinDepth = 1;
1310  if (params.size() > 0)
1311  nMinDepth = params[0].get_int();
1312 
1313  map<string, int64_t> mapAccountBalances;
1314  BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwalletMain->mapAddressBook) {
1315  if (IsMine(*pwalletMain, entry.first)) // This address belongs to me
1316  mapAccountBalances[entry.second.name] = 0;
1317  }
1318 
1319  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1320  {
1321  const CWalletTx& wtx = (*it).second;
1322  int64_t nFee;
1323  string strSentAccount;
1324  list<pair<CTxDestination, int64_t> > listReceived;
1325  list<pair<CTxDestination, int64_t> > listSent;
1326  int nDepth = wtx.GetDepthInMainChain();
1327  if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
1328  continue;
1329  wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount);
1330  mapAccountBalances[strSentAccount] -= nFee;
1331  BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent)
1332  mapAccountBalances[strSentAccount] -= s.second;
1333  if (nDepth >= nMinDepth)
1334  {
1335  BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived)
1336  if (pwalletMain->mapAddressBook.count(r.first))
1337  mapAccountBalances[pwalletMain->mapAddressBook[r.first].name] += r.second;
1338  else
1339  mapAccountBalances[""] += r.second;
1340  }
1341  }
1342 
1343  list<CAccountingEntry> acentries;
1345  BOOST_FOREACH(const CAccountingEntry& entry, acentries)
1346  mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1347 
1348  Object ret;
1349  BOOST_FOREACH(const PAIRTYPE(string, int64_t)& accountBalance, mapAccountBalances) {
1350  ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1351  }
1352  return ret;
1353 }
1354 
1355 Value listsinceblock(const Array& params, bool fHelp)
1356 {
1357  if (fHelp)
1358  throw runtime_error(
1359  "listsinceblock ( \"blockhash\" target-confirmations )\n"
1360  "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
1361  "\nArguments:\n"
1362  "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
1363  "2. target-confirmations: (numeric, optional) The confirmations required, must be 1 or more\n"
1364  "\nResult:\n"
1365  "{\n"
1366  " \"transactions\": [\n"
1367  " \"account\":\"accountname\", (string) The account name associated with the transaction. Will be \"\" for the default account.\n"
1368  " \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
1369  " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
1370  " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the 'move' category for moves \n"
1371  " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
1372  " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the 'send' category of transactions.\n"
1373  " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
1374  " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1375  " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1376  " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1377  " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1378  " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
1379  " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
1380  " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1381  " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
1382  " ],\n"
1383  " \"lastblock\": \"lastblockhash\" (string) The hash of the last block\n"
1384  "}\n"
1385  "\nExamples:\n"
1386  + HelpExampleCli("listsinceblock", "")
1387  + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1388  + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1389  );
1390 
1391  CBlockIndex *pindex = NULL;
1392  int target_confirms = 1;
1393 
1394  if (params.size() > 0)
1395  {
1396  uint256 blockId = 0;
1397 
1398  blockId.SetHex(params[0].get_str());
1399  std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(blockId);
1400  if (it != mapBlockIndex.end())
1401  pindex = it->second;
1402  }
1403 
1404  if (params.size() > 1)
1405  {
1406  target_confirms = params[1].get_int();
1407 
1408  if (target_confirms < 1)
1409  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
1410  }
1411 
1412  int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
1413 
1414  Array transactions;
1415 
1416  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++)
1417  {
1418  CWalletTx tx = (*it).second;
1419 
1420  if (depth == -1 || tx.GetDepthInMainChain() < depth)
1421  ListTransactions(tx, "*", 0, true, transactions);
1422  }
1423 
1424  CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
1425  uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : 0;
1426 
1427  Object ret;
1428  ret.push_back(Pair("transactions", transactions));
1429  ret.push_back(Pair("lastblock", lastblock.GetHex()));
1430 
1431  return ret;
1432 }
1433 
1434 Value gettransaction(const Array& params, bool fHelp)
1435 {
1436  if (fHelp || params.size() != 1)
1437  throw runtime_error(
1438  "gettransaction \"txid\"\n"
1439  "\nGet detailed information about in-wallet transaction <txid>\n"
1440  "\nArguments:\n"
1441  "1. \"txid\" (string, required) The transaction id\n"
1442  "\nResult:\n"
1443  "{\n"
1444  " \"amount\" : x.xxx, (numeric) The transaction amount in btc\n"
1445  " \"confirmations\" : n, (numeric) The number of confirmations\n"
1446  " \"blockhash\" : \"hash\", (string) The block hash\n"
1447  " \"blockindex\" : xx, (numeric) The block index\n"
1448  " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
1449  " \"txid\" : \"transactionid\", (string) The transaction id.\n"
1450  " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
1451  " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
1452  " \"details\" : [\n"
1453  " {\n"
1454  " \"account\" : \"accountname\", (string) The account name involved in the transaction, can be \"\" for the default account.\n"
1455  " \"address\" : \"bitcoinaddress\", (string) The bitcoin address involved in the transaction\n"
1456  " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
1457  " \"amount\" : x.xxx (numeric) The amount in btc\n"
1458  " }\n"
1459  " ,...\n"
1460  " ],\n"
1461  " \"hex\" : \"data\" (string) Raw data for transaction\n"
1462  "}\n"
1463 
1464  "\nbExamples\n"
1465  + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1466  + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1467  );
1468 
1469  uint256 hash;
1470  hash.SetHex(params[0].get_str());
1471 
1472  Object entry;
1473  if (!pwalletMain->mapWallet.count(hash))
1474  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
1475  const CWalletTx& wtx = pwalletMain->mapWallet[hash];
1476 
1477  int64_t nCredit = wtx.GetCredit();
1478  int64_t nDebit = wtx.GetDebit();
1479  int64_t nNet = nCredit - nDebit;
1480  int64_t nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
1481 
1482  entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
1483  if (wtx.IsFromMe())
1484  entry.push_back(Pair("fee", ValueFromAmount(nFee)));
1485 
1486  WalletTxToJSON(wtx, entry);
1487 
1488  Array details;
1489  ListTransactions(wtx, "*", 0, false, details);
1490  entry.push_back(Pair("details", details));
1491 
1493  ssTx << static_cast<CTransaction>(wtx);
1494  string strHex = HexStr(ssTx.begin(), ssTx.end());
1495  entry.push_back(Pair("hex", strHex));
1496 
1497  return entry;
1498 }
1499 
1500 
1501 Value backupwallet(const Array& params, bool fHelp)
1502 {
1503  if (fHelp || params.size() != 1)
1504  throw runtime_error(
1505  "backupwallet \"destination\"\n"
1506  "\nSafely copies wallet.dat to destination, which can be a directory or a path with filename.\n"
1507  "\nArguments:\n"
1508  "1. \"destination\" (string) The destination directory or file\n"
1509  "\nExamples:\n"
1510  + HelpExampleCli("backupwallet", "\"backup.dat\"")
1511  + HelpExampleRpc("backupwallet", "\"backup.dat\"")
1512  );
1513 
1514  string strDest = params[0].get_str();
1515  if (!BackupWallet(*pwalletMain, strDest))
1516  throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
1517 
1518  return Value::null;
1519 }
1520 
1521 
1522 Value keypoolrefill(const Array& params, bool fHelp)
1523 {
1524  if (fHelp || params.size() > 1)
1525  throw runtime_error(
1526  "keypoolrefill ( newsize )\n"
1527  "\nFills the keypool."
1528  + HelpRequiringPassphrase() + "\n"
1529  "\nArguments\n"
1530  "1. newsize (numeric, optional, default=100) The new keypool size\n"
1531  "\nExamples:\n"
1532  + HelpExampleCli("keypoolrefill", "")
1533  + HelpExampleRpc("keypoolrefill", "")
1534  );
1535 
1536  // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
1537  unsigned int kpSize = 0;
1538  if (params.size() > 0) {
1539  if (params[0].get_int() < 0)
1540  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
1541  kpSize = (unsigned int)params[0].get_int();
1542  }
1543 
1545  pwalletMain->TopUpKeyPool(kpSize);
1546 
1547  if (pwalletMain->GetKeyPoolSize() < kpSize)
1548  throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
1549 
1550  return Value::null;
1551 }
1552 
1553 
1554 static void LockWallet(CWallet* pWallet)
1555 {
1556  LOCK(cs_nWalletUnlockTime);
1557  nWalletUnlockTime = 0;
1558  pWallet->Lock();
1559 }
1560 
1561 Value walletpassphrase(const Array& params, bool fHelp)
1562 {
1563  if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1564  throw runtime_error(
1565  "walletpassphrase \"passphrase\" timeout\n"
1566  "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
1567  "This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
1568  "\nArguments:\n"
1569  "1. \"passphrase\" (string, required) The wallet passphrase\n"
1570  "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
1571  "\nNote:\n"
1572  "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
1573  "time that overrides the old one.\n"
1574  "\nExamples:\n"
1575  "\nunlock the wallet for 60 seconds\n"
1576  + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
1577  "\nLock the wallet again (before 60 seconds)\n"
1578  + HelpExampleCli("walletlock", "") +
1579  "\nAs json rpc call\n"
1580  + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
1581  );
1582 
1583  if (fHelp)
1584  return true;
1585  if (!pwalletMain->IsCrypted())
1586  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
1587 
1588  // Note that the walletpassphrase is stored in params[0] which is not mlock()ed
1589  SecureString strWalletPass;
1590  strWalletPass.reserve(100);
1591  // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1592  // Alternately, find a way to make params[0] mlock()'d to begin with.
1593  strWalletPass = params[0].get_str().c_str();
1594 
1595  if (strWalletPass.length() > 0)
1596  {
1597  if (!pwalletMain->Unlock(strWalletPass))
1598  throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
1599  }
1600  else
1601  throw runtime_error(
1602  "walletpassphrase <passphrase> <timeout>\n"
1603  "Stores the wallet decryption key in memory for <timeout> seconds.");
1604 
1606 
1607  int64_t nSleepTime = params[1].get_int64();
1608  LOCK(cs_nWalletUnlockTime);
1609  nWalletUnlockTime = GetTime() + nSleepTime;
1610  RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime);
1611 
1612  return Value::null;
1613 }
1614 
1615 
1616 Value walletpassphrasechange(const Array& params, bool fHelp)
1617 {
1618  if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1619  throw runtime_error(
1620  "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
1621  "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
1622  "\nArguments:\n"
1623  "1. \"oldpassphrase\" (string) The current passphrase\n"
1624  "2. \"newpassphrase\" (string) The new passphrase\n"
1625  "\nExamples:\n"
1626  + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
1627  + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
1628  );
1629 
1630  if (fHelp)
1631  return true;
1632  if (!pwalletMain->IsCrypted())
1633  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
1634 
1635  // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
1636  // Alternately, find a way to make params[0] mlock()'d to begin with.
1637  SecureString strOldWalletPass;
1638  strOldWalletPass.reserve(100);
1639  strOldWalletPass = params[0].get_str().c_str();
1640 
1641  SecureString strNewWalletPass;
1642  strNewWalletPass.reserve(100);
1643  strNewWalletPass = params[1].get_str().c_str();
1644 
1645  if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
1646  throw runtime_error(
1647  "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1648  "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1649 
1650  if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
1651  throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
1652 
1653  return Value::null;
1654 }
1655 
1656 
1657 Value walletlock(const Array& params, bool fHelp)
1658 {
1659  if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0))
1660  throw runtime_error(
1661  "walletlock\n"
1662  "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
1663  "After calling this method, you will need to call walletpassphrase again\n"
1664  "before being able to call any methods which require the wallet to be unlocked.\n"
1665  "\nExamples:\n"
1666  "\nSet the passphrase for 2 minutes to perform a transaction\n"
1667  + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
1668  "\nPerform a send (requires passphrase set)\n"
1669  + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
1670  "\nClear the passphrase since we are done before 2 minutes is up\n"
1671  + HelpExampleCli("walletlock", "") +
1672  "\nAs json rpc call\n"
1673  + HelpExampleRpc("walletlock", "")
1674  );
1675 
1676  if (fHelp)
1677  return true;
1678  if (!pwalletMain->IsCrypted())
1679  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
1680 
1681  {
1682  LOCK(cs_nWalletUnlockTime);
1683  pwalletMain->Lock();
1684  nWalletUnlockTime = 0;
1685  }
1686 
1687  return Value::null;
1688 }
1689 
1690 
1691 Value encryptwallet(const Array& params, bool fHelp)
1692 {
1693  if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
1694  throw runtime_error(
1695  "encryptwallet \"passphrase\"\n"
1696  "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
1697  "After this, any calls that interact with private keys such as sending or signing \n"
1698  "will require the passphrase to be set prior the making these calls.\n"
1699  "Use the walletpassphrase call for this, and then walletlock call.\n"
1700  "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
1701  "Note that this will shutdown the server.\n"
1702  "\nArguments:\n"
1703  "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
1704  "\nExamples:\n"
1705  "\nEncrypt you wallet\n"
1706  + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
1707  "\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n"
1708  + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
1709  "\nNow we can so something like sign\n"
1710  + HelpExampleCli("signmessage", "\"bitcoinaddress\" \"test message\"") +
1711  "\nNow lock the wallet again by removing the passphrase\n"
1712  + HelpExampleCli("walletlock", "") +
1713  "\nAs a json rpc call\n"
1714  + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
1715  );
1716 
1717  if (fHelp)
1718  return true;
1719  if (pwalletMain->IsCrypted())
1720  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
1721 
1722  // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1723  // Alternately, find a way to make params[0] mlock()'d to begin with.
1724  SecureString strWalletPass;
1725  strWalletPass.reserve(100);
1726  strWalletPass = params[0].get_str().c_str();
1727 
1728  if (strWalletPass.length() < 1)
1729  throw runtime_error(
1730  "encryptwallet <passphrase>\n"
1731  "Encrypts the wallet with <passphrase>.");
1732 
1733  if (!pwalletMain->EncryptWallet(strWalletPass))
1734  throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
1735 
1736  // BDB seems to have a bad habit of writing old data into
1737  // slack space in .dat files; that is bad if the old data is
1738  // unencrypted private keys. So:
1739  StartShutdown();
1740  return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
1741 }
1742 
1743 Value lockunspent(const Array& params, bool fHelp)
1744 {
1745  if (fHelp || params.size() < 1 || params.size() > 2)
1746  throw runtime_error(
1747  "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n"
1748  "\nUpdates list of temporarily unspendable outputs.\n"
1749  "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
1750  "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
1751  "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
1752  "is always cleared (by virtue of process exit) when a node stops or fails.\n"
1753  "Also see the listunspent call\n"
1754  "\nArguments:\n"
1755  "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
1756  "2. \"transactions\" (string, required) A json array of objects. Each object the txid (string) vout (numeric)\n"
1757  " [ (json array of json objects)\n"
1758  " {\n"
1759  " \"txid\":\"id\", (string) The transaction id\n"
1760  " \"vout\": n (numeric) The output number\n"
1761  " }\n"
1762  " ,...\n"
1763  " ]\n"
1764 
1765  "\nResult:\n"
1766  "true|false (boolean) Whether the command was successful or not\n"
1767 
1768  "\nExamples:\n"
1769  "\nList the unspent transactions\n"
1770  + HelpExampleCli("listunspent", "") +
1771  "\nLock an unspent transaction\n"
1772  + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
1773  "\nList the locked transactions\n"
1774  + HelpExampleCli("listlockunspent", "") +
1775  "\nUnlock the transaction again\n"
1776  + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
1777  "\nAs a json rpc call\n"
1778  + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
1779  );
1780 
1781  if (params.size() == 1)
1782  RPCTypeCheck(params, list_of(bool_type));
1783  else
1784  RPCTypeCheck(params, list_of(bool_type)(array_type));
1785 
1786  bool fUnlock = params[0].get_bool();
1787 
1788  if (params.size() == 1) {
1789  if (fUnlock)
1791  return true;
1792  }
1793 
1794  Array outputs = params[1].get_array();
1795  BOOST_FOREACH(Value& output, outputs)
1796  {
1797  if (output.type() != obj_type)
1798  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
1799  const Object& o = output.get_obj();
1800 
1801  RPCTypeCheck(o, map_list_of("txid", str_type)("vout", int_type));
1802 
1803  string txid = find_value(o, "txid").get_str();
1804  if (!IsHex(txid))
1805  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
1806 
1807  int nOutput = find_value(o, "vout").get_int();
1808  if (nOutput < 0)
1809  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
1810 
1811  COutPoint outpt(uint256(txid), nOutput);
1812 
1813  if (fUnlock)
1814  pwalletMain->UnlockCoin(outpt);
1815  else
1816  pwalletMain->LockCoin(outpt);
1817  }
1818 
1819  return true;
1820 }
1821 
1822 Value listlockunspent(const Array& params, bool fHelp)
1823 {
1824  if (fHelp || params.size() > 0)
1825  throw runtime_error(
1826  "listlockunspent\n"
1827  "\nReturns list of temporarily unspendable outputs.\n"
1828  "See the lockunspent call to lock and unlock transactions for spending.\n"
1829  "\nResult:\n"
1830  "[\n"
1831  " {\n"
1832  " \"txid\" : \"transactionid\", (string) The transaction id locked\n"
1833  " \"vout\" : n (numeric) The vout value\n"
1834  " }\n"
1835  " ,...\n"
1836  "]\n"
1837  "\nExamples:\n"
1838  "\nList the unspent transactions\n"
1839  + HelpExampleCli("listunspent", "") +
1840  "\nLock an unspent transaction\n"
1841  + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
1842  "\nList the locked transactions\n"
1843  + HelpExampleCli("listlockunspent", "") +
1844  "\nUnlock the transaction again\n"
1845  + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
1846  "\nAs a json rpc call\n"
1847  + HelpExampleRpc("listlockunspent", "")
1848  );
1849 
1850  vector<COutPoint> vOutpts;
1851  pwalletMain->ListLockedCoins(vOutpts);
1852 
1853  Array ret;
1854 
1855  BOOST_FOREACH(COutPoint &outpt, vOutpts) {
1856  Object o;
1857 
1858  o.push_back(Pair("txid", outpt.hash.GetHex()));
1859  o.push_back(Pair("vout", (int)outpt.n));
1860  ret.push_back(o);
1861  }
1862 
1863  return ret;
1864 }
1865 
1866 Value settxfee(const Array& params, bool fHelp)
1867 {
1868  if (fHelp || params.size() < 1 || params.size() > 1)
1869  throw runtime_error(
1870  "settxfee amount\n"
1871  "\nSet the transaction fee per kB.\n"
1872  "\nArguments:\n"
1873  "1. amount (numeric, required) The transaction fee in BTC/kB rounded to the nearest 0.00000001\n"
1874  "\nResult\n"
1875  "true|false (boolean) Returns true if successful\n"
1876  "\nExamples:\n"
1877  + HelpExampleCli("settxfee", "0.00001")
1878  + HelpExampleRpc("settxfee", "0.00001")
1879  );
1880 
1881  // Amount
1882  int64_t nAmount = 0;
1883  if (params[0].get_real() != 0.0)
1884  nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts
1885 
1886  nTransactionFee = nAmount;
1887  return true;
1888 }
1889 
1890 Value getwalletinfo(const Array& params, bool fHelp)
1891 {
1892  if (fHelp || params.size() != 0)
1893  throw runtime_error(
1894  "getwalletinfo\n"
1895  "Returns an object containing various wallet state info.\n"
1896  "\nResult:\n"
1897  "{\n"
1898  " \"walletversion\": xxxxx, (numeric) the wallet version\n"
1899  " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
1900  " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
1901  " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
1902  " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
1903  " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
1904  "}\n"
1905  "\nExamples:\n"
1906  + HelpExampleCli("getwalletinfo", "")
1907  + HelpExampleRpc("getwalletinfo", "")
1908  );
1909 
1910  Object obj;
1911  obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
1912  obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
1913  obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size()));
1914  obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
1915  obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
1916  if (pwalletMain->IsCrypted())
1917  obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
1918  return obj;
1919 }
Value getaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:246
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Definition: main.cpp:594
Value sendmany(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:792
void SetHex(const char *psz)
Definition: uint256.h:305
static CCriticalSection cs_nWalletUnlockTime
Definition: rpcwallet.cpp:27
bool IsValid() const
Definition: base58.cpp:215
Value keypoolrefill(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1522
int64_t GetValueOut() const
Definition: core.cpp:109
bool IsCrypted() const
Definition: crypter.h:137
Account information.
Definition: wallet.h:771
Value getreceivedbyaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:449
int64_t nOrderPos
Definition: wallet.h:808
void RPCRunLater(const std::string &name, boost::function< void(void)> func, int64_t nSeconds)
Definition: rpcserver.cpp:702
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
Definition: wallet.cpp:1548
Value settxfee(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1866
CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
Definition: rpcwallet.cpp:113
void ListTransactions(const CWalletTx &wtx, const string &strAccount, int nMinDepth, bool fLong, Array &ret)
Definition: rpcwallet.cpp:1098
bool WriteAccount(const std::string &strAccount, const CAccount &account)
Definition: walletdb.cpp:166
Value getaddressesbyaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:273
const_iterator begin() const
Definition: serialize.h:924
void KeepKey()
Definition: wallet.cpp:1924
CScript scriptPubKey
Definition: core.h:123
Definition: init.h:13
int64_t nAmount
Definition: rpcwallet.cpp:922
void ListLockedCoins(std::vector< COutPoint > &vOutpts)
Definition: wallet.cpp:1997
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:173
#define PAIRTYPE(t1, t2)
Definition: util.h:48
CCriticalSection cs_wallet
Main wallet lock.
Definition: wallet.h:132
int nIndex
Definition: main.h:434
std::string strFromAccount
Definition: wallet.h:463
Value getwalletinfo(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1890
std::map< CTxDestination, int64_t > GetAddressBalances()
Definition: wallet.cpp:1756
std::string HelpExampleRpc(string methodname, string args)
Definition: rpcserver.cpp:923
void StartShutdown()
Definition: init.cpp:99
uint256 hashBlock
Definition: main.h:432
Value backupwallet(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1501
int64_t GetDebit() const
Definition: wallet.h:579
bool IsFromMe() const
Definition: wallet.h:664
uint256 GetHash() const
Definition: core.cpp:75
bool IsLocked() const
Definition: crypter.h:142
STL namespace.
void ListAccountCreditDebit(const std::string &strAccount, std::list< CAccountingEntry > &acentries)
Definition: walletdb.cpp:193
unsigned int GetKeyPoolSize()
Definition: wallet.h:363
bool IsHex(const string &str)
Definition: util.cpp:409
Double ended buffer combining vector and stream-like interfaces.
Definition: serialize.h:839
std::string name
Definition: wallet.h:85
Object JSONRPCError(int code, const string &message)
base58-encoded Bitcoin addresses.
Definition: base58.h:101
Value getreceivedbyaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:503
bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry &acentry)
Definition: walletdb.cpp:171
unsigned int n
Definition: core.h:26
bool BackupWallet(const CWallet &wallet, const string &strDest)
Definition: walletdb.cpp:825
void RPCTypeCheck(const Array &params, const list< Value_type > &typesExpected, bool fAllowNull)
Definition: rpcserver.cpp:43
bool IsTrusted() const
Definition: wallet.h:669
CTxDestination Get() const
Definition: base58.cpp:222
bool GetKey(const CKeyID &address, CKey &keyOut) const
Definition: crypter.cpp:211
const string strMessageMagic
Definition: main.cpp:82
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:48
void EnsureWalletIsUnlocked()
Definition: rpcwallet.cpp:36
Value listlockunspent(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1822
bool TxnBegin()
Definition: db.h:265
Value ListReceived(const Array &params, bool fByAccounts)
Definition: rpcwallet.cpp:932
int64_t IncOrderPosNext(CWalletDB *pwalletdb=NULL)
Increment the next transaction order id.
Definition: wallet.cpp:437
bool GetKeyID(CKeyID &keyID) const
Definition: base58.cpp:235
mapValue_t mapValue
Definition: wallet.h:457
void SetDestination(const CTxDestination &address)
Definition: script.cpp:1925
std::multimap< int64_t, TxPair > TxItems
Definition: wallet.h:237
Value getunconfirmedbalance(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:656
Value listreceivedbyaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1032
int64_t GetBalance() const
Definition: wallet.cpp:980
void AcentryToJSON(const CAccountingEntry &acentry, const string &strAccount, Array &ret)
Definition: rpcwallet.cpp:1161
bool CreateTransaction(const std::vector< std::pair< CScript, int64_t > > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, int64_t &nFeeRet, std::string &strFailReason, const CCoinControl *coinControl=NULL)
int GetBlocksToMaturity() const
Definition: main.cpp:1033
std::string strComment
Definition: wallet.h:806
string EncodeBase64(const unsigned char *pch, size_t len)
Definition: util.cpp:547
void GetAccountAmounts(const std::string &strAccount, int64_t &nReceived, int64_t &nSent, int64_t &nFee) const
Definition: wallet.cpp:803
Value lockunspent(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1743
int Height() const
Return the maximal height in the chain.
Definition: main.h:1043
bool Set(const CKeyID &id)
Definition: base58.cpp:201
int64_t GetAdjustedTime()
Definition: util.cpp:1236
Value listreceivedbyaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1062
void LockCoin(COutPoint &output)
Definition: wallet.cpp:1971
Value ValueFromAmount(int64_t amount)
Definition: rpcserver.cpp:94
Value walletlock(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1657
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
Definition: wallet.cpp:167
int64_t nTransactionFee
Definition: wallet.cpp:19
int64_t GetAccountCreditDebit(const std::string &strAccount)
Definition: walletdb.cpp:181
Value getaccountaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:151
int64_t GetOldestKeyPoolTime()
Definition: wallet.cpp:1745
int64_t nCreditDebit
Definition: wallet.h:803
#define LOCK(cs)
Definition: sync.h:156
Value walletpassphrase(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1561
std::vector< CTxOut > vout
Definition: core.h:191
Value sendfrom(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:731
int GetVersion()
Definition: wallet.h:378
void UnlockCoin(COutPoint &output)
Definition: wallet.cpp:1977
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: allocators.h:253
An encapsulated public key.
Definition: key.h:42
bool TxnCommit()
Definition: db.h:276
Value walletpassphrasechange(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1616
std::string SendMoneyToDestination(const CTxDestination &address, int64_t nValue, CWalletTx &wtxNew)
Definition: wallet.cpp:1478
bool TopUpKeyPool(unsigned int kpSize=0)
Definition: wallet.cpp:1632
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey)
Definition: wallet.cpp:1401
std::string ToString() const
Definition: base58.cpp:174
Value movecmd(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:666
An output of a transaction.
Definition: core.h:119
bool GetReservedKey(CPubKey &pubkey)
Definition: wallet.cpp:1903
std::set< std::set< CTxDestination > > GetAddressGroupings()
Definition: wallet.cpp:1796
void GetAmounts(std::list< std::pair< CTxDestination, int64_t > > &listReceived, std::list< std::pair< CTxDestination, int64_t > > &listSent, int64_t &nFee, std::string &strSentAccount) const
Definition: wallet.cpp:750
Value getrawchangeaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:179
Value sendtoaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:305
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: core.h:22
string AccountFromValue(const Value &value)
Definition: rpcwallet.cpp:66
std::set< CTxDestination > GetAccountAddresses(std::string strAccount) const
Definition: wallet.cpp:1889
std::string GetHex() const
Definition: uint256.h:297
Value addmultisigaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:876
int64_t GetTime()
Definition: util.cpp:1215
Access to the wallet database (wallet.dat)
Definition: walletdb.h:71
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:451
int64_t GetTxTime() const
Definition: wallet.cpp:705
std::string strWalletFile
Definition: wallet.h:135
CPubKey vchPubKey
Definition: wallet.h:774
uint256 GetHash()
Definition: hash.h:52
256-bit unsigned integer
Definition: uint256.h:531
static const int64_t COIN
Definition: util.h:38
Value signmessage(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:398
int64_t GetUnconfirmedBalance() const
Definition: wallet.cpp:996
CScript _createmultisig_redeemScript(const Array &params)
Definition: rpcmisc.cpp:179
bool EncryptWallet(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:356
A key allocated from the key pool.
Definition: wallet.h:402
Address book data.
Definition: wallet.h:82
bool SignCompact(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Definition: key.cpp:405
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: main.h:688
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:401
int64_t GetAccountBalance(CWalletDB &walletdb, const string &strAccount, int nMinDepth)
Definition: rpcwallet.cpp:555
Value getnewaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:74
static const int PROTOCOL_VERSION
Definition: version.h:29
vector< uint256 > txids
Definition: rpcwallet.cpp:924
bool IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: script.cpp:1448
A reference to a CKey: the Hash160 of its serialized public key.
Definition: key.h:26
Internal transfers.
Definition: wallet.h:799
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Definition: script.cpp:1493
int64_t nWalletUnlockTime
Definition: rpcwallet.cpp:26
bool Unlock(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:147
CScriptID GetID() const
Definition: script.h:708
void WalletTxToJSON(const CWalletTx &wtx, Object &entry)
Definition: rpcwallet.cpp:42
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:100
std::set< uint256 > GetConflicts() const
Definition: wallet.cpp:919
bool IsValid() const
Definition: key.h:143
int GetDepthInMainChain(CBlockIndex *&pindexRet) const
Definition: main.cpp:1023
std::string HelpRequiringPassphrase()
Definition: rpcwallet.cpp:29
int64_t AmountFromValue(const Value &value)
Definition: rpcserver.cpp:83
void UnlockAllCoins()
Definition: wallet.cpp:1983
Value listaccounts(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1285
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:168
Value gettransaction(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1434
Value listaddressgroupings(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:351
bool IsCoinBase() const
Definition: core.h:232
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: key.h:34
bool AddCScript(const CScript &redeemScript)
Definition: wallet.cpp:122
std::string HelpExampleCli(string methodname, string args)
Definition: rpcserver.cpp:919
Value listtransactions(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1178
bool GetKeyFromPool(CPubKey &key)
Definition: wallet.cpp:1726
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: script.h:218
unsigned int nTimeReceived
Definition: wallet.h:460
An encapsulated private key.
Definition: key.h:179
int nHeight
Definition: main.h:698
Value listsinceblock(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1355
static void MaybePushAddress(Object &entry, const CTxDestination &dest)
Definition: rpcwallet.cpp:1091
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
Definition: util.h:263
static void LockWallet(CWallet *pWallet)
Definition: rpcwallet.cpp:1554
Value setaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:209
Value getbalance(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:587
CKeyID GetID() const
Definition: key.h:131
Value encryptwallet(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1691
std::string strOtherAccount
Definition: wallet.h:805
map< uint256, CBlockIndex * > mapBlockIndex
Definition: main.cpp:47
int64_t GetCredit(bool fUseCache=true) const
Definition: wallet.h:590
bool ReadAccount(const std::string &strAccount, CAccount &account)
Definition: walletdb.cpp:160
int64_t nTime
Definition: wallet.h:804
CWallet * pwalletMain
uint256 GetBlockHash() const
Definition: main.h:805
int64_t nValue
Definition: core.h:122
const_iterator end() const
Definition: serialize.h:926
TxItems OrderedTxItems(std::list< CAccountingEntry > &acentries, std::string strAccount="")
Get the wallet's activity log.
Definition: wallet.cpp:449
uint256 hash
Definition: core.h:25
std::string strAccount
Definition: wallet.h:802