Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
rpcwallet.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 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 <boost/assign/list_of.hpp>
7 
8 #include "wallet.h"
9 #include "walletdb.h"
10 #include "bitcoinrpc.h"
11 #include "init.h"
12 #include "base58.h"
13 
14 using namespace std;
15 using namespace boost;
16 using namespace boost::assign;
17 using namespace json_spirit;
18 
20 static CCriticalSection cs_nWalletUnlockTime;
21 
23 {
24  return pwalletMain && pwalletMain->IsCrypted()
25  ? "\nrequires wallet passphrase to be set with walletpassphrase first"
26  : "";
27 }
28 
30 {
31  if (pwalletMain->IsLocked())
32  throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
33 }
34 
35 void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
36 {
37  int confirms = wtx.GetDepthInMainChain();
38  entry.push_back(Pair("confirmations", confirms));
39  if (wtx.IsCoinBase())
40  entry.push_back(Pair("generated", true));
41  if (confirms)
42  {
43  entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
44  entry.push_back(Pair("blockindex", wtx.nIndex));
45  entry.push_back(Pair("blocktime", (boost::int64_t)(mapBlockIndex[wtx.hashBlock]->nTime)));
46  }
47  entry.push_back(Pair("txid", wtx.GetHash().GetHex()));
48  entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime()));
49  entry.push_back(Pair("timereceived", (boost::int64_t)wtx.nTimeReceived));
50  BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
51  entry.push_back(Pair(item.first, item.second));
52 }
53 
55 {
56  string strAccount = value.get_str();
57  if (strAccount == "*")
58  throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
59  return strAccount;
60 }
61 
62 Value getinfo(const Array& params, bool fHelp)
63 {
64  if (fHelp || params.size() != 0)
65  throw runtime_error(
66  "getinfo\n"
67  "Returns an object containing various state info.");
68 
69  proxyType proxy;
70  GetProxy(NET_IPV4, proxy);
71 
72  Object obj;
73  obj.push_back(Pair("version", (int)CLIENT_VERSION));
74  obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
75  if (pwalletMain) {
76  obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
77  obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
78  }
79  obj.push_back(Pair("blocks", (int)nBestHeight));
80  obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset()));
81  obj.push_back(Pair("connections", (int)vNodes.size()));
82  obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
83  obj.push_back(Pair("difficulty", (double)GetDifficulty()));
84  obj.push_back(Pair("testnet", fTestNet));
85  if (pwalletMain) {
86  obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
87  obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
88  }
89  obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
90  obj.push_back(Pair("mininput", ValueFromAmount(nMinimumInputValue)));
92  obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
93  obj.push_back(Pair("errors", GetWarnings("statusbar")));
94  return obj;
95 }
96 
97 
98 
99 Value getnewaddress(const Array& params, bool fHelp)
100 {
101  if (fHelp || params.size() > 1)
102  throw runtime_error(
103  "getnewaddress [account]\n"
104  "Returns a new Feathercoin address for receiving payments. "
105  "If [account] is specified (recommended), it is added to the address book "
106  "so payments received with the address will be credited to [account].");
107 
108  // Parse the account first so we don't generate a key if there's an error
109  string strAccount;
110  if (params.size() > 0)
111  strAccount = AccountFromValue(params[0]);
112 
113  if (!pwalletMain->IsLocked())
115 
116  // Generate a new key that is added to wallet
117  CPubKey newKey;
118  if (!pwalletMain->GetKeyFromPool(newKey, false))
119  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
120  CKeyID keyID = newKey.GetID();
121 
122  pwalletMain->SetAddressBookName(keyID, strAccount);
123 
124  return CBitcoinAddress(keyID).ToString();
125 }
126 
127 
128 CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
129 {
131 
132  CAccount account;
133  walletdb.ReadAccount(strAccount, account);
134 
135  bool bKeyUsed = false;
136 
137  // Check if the current key has been used
138  if (account.vchPubKey.IsValid())
139  {
140  CScript scriptPubKey;
141  scriptPubKey.SetDestination(account.vchPubKey.GetID());
142  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
143  it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
144  ++it)
145  {
146  const CWalletTx& wtx = (*it).second;
147  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
148  if (txout.scriptPubKey == scriptPubKey)
149  bKeyUsed = true;
150  }
151  }
152 
153  // Generate a new key
154  if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
155  {
156  if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
157  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
158 
159  pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), strAccount);
160  walletdb.WriteAccount(strAccount, account);
161  }
162 
163  return CBitcoinAddress(account.vchPubKey.GetID());
164 }
165 
166 Value getaccountaddress(const Array& params, bool fHelp)
167 {
168  if (fHelp || params.size() != 1)
169  throw runtime_error(
170  "getaccountaddress <account>\n"
171  "Returns the current Feathercoin address for receiving payments to this account.");
172 
173  // Parse the account first so we don't generate a key if there's an error
174  string strAccount = AccountFromValue(params[0]);
175 
176  Value ret;
177 
178  ret = GetAccountAddress(strAccount).ToString();
179 
180  return ret;
181 }
182 
183 
184 
185 Value setaccount(const Array& params, bool fHelp)
186 {
187  if (fHelp || params.size() < 1 || params.size() > 2)
188  throw runtime_error(
189  "setaccount <feathercoinaddress> <account>\n"
190  "Sets the account associated with the given address.");
191 
192  CBitcoinAddress address(params[0].get_str());
193  if (!address.IsValid())
194  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Feathercoin address");
195 
196 
197  string strAccount;
198  if (params.size() > 1)
199  strAccount = AccountFromValue(params[1]);
200 
201  // Detect when changing the account of an address that is the 'unused current key' of another account:
202  if (pwalletMain->mapAddressBook.count(address.Get()))
203  {
204  string strOldAccount = pwalletMain->mapAddressBook[address.Get()];
205  if (address == GetAccountAddress(strOldAccount))
206  GetAccountAddress(strOldAccount, true);
207  }
208 
209  pwalletMain->SetAddressBookName(address.Get(), strAccount);
210 
211  return Value::null;
212 }
213 
214 
215 Value getaccount(const Array& params, bool fHelp)
216 {
217  if (fHelp || params.size() != 1)
218  throw runtime_error(
219  "getaccount <feathercoinaddress>\n"
220  "Returns the account associated with the given address.");
221 
222  CBitcoinAddress address(params[0].get_str());
223  if (!address.IsValid())
224  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Feathercoin address");
225 
226  string strAccount;
227  map<CTxDestination, string>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
228  if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
229  strAccount = (*mi).second;
230  return strAccount;
231 }
232 
233 
234 Value getaddressesbyaccount(const Array& params, bool fHelp)
235 {
236  if (fHelp || params.size() != 1)
237  throw runtime_error(
238  "getaddressesbyaccount <account>\n"
239  "Returns the list of addresses for the given account.");
240 
241  string strAccount = AccountFromValue(params[0]);
242 
243  // Find all addresses that have the given account
244  Array ret;
245  BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
246  {
247  const CBitcoinAddress& address = item.first;
248  const string& strName = item.second;
249  if (strName == strAccount)
250  ret.push_back(address.ToString());
251  }
252  return ret;
253 }
254 
255 
256 Value setmininput(const Array& params, bool fHelp)
257 {
258  if (fHelp || params.size() < 1 || params.size() > 1)
259  throw runtime_error(
260  "setmininput <amount>\n"
261  "<amount> is a real and is rounded to the nearest 0.00000001");
262 
263  // Amount
264  int64 nAmount = 0;
265  if (params[0].get_real() != 0.0)
266  nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts
267 
268  nMinimumInputValue = nAmount;
269  return true;
270 }
271 
272 
273 Value sendtoaddress(const Array& params, bool fHelp)
274 {
275  if (fHelp || params.size() < 2 || params.size() > 4)
276  throw runtime_error(
277  "sendtoaddress <feathercoinaddress> <amount> [comment] [comment-to]\n"
278  "<amount> is a real and is rounded to the nearest 0.00000001"
280 
281  CBitcoinAddress address(params[0].get_str());
282  if (!address.IsValid())
283  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Feathercoin address");
284 
285  // Amount
286  int64 nAmount = AmountFromValue(params[1]);
287 
288  // Wallet comments
289  CWalletTx wtx;
290  if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty())
291  wtx.mapValue["comment"] = params[2].get_str();
292  if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
293  wtx.mapValue["to"] = params[3].get_str();
294 
295  if (pwalletMain->IsLocked())
296  throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
297 
298  string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
299  if (strError != "")
300  throw JSONRPCError(RPC_WALLET_ERROR, strError);
301 
302  return wtx.GetHash().GetHex();
303 }
304 
305 Value listaddressgroupings(const Array& params, bool fHelp)
306 {
307  if (fHelp)
308  throw runtime_error(
309  "listaddressgroupings\n"
310  "Lists groups of addresses which have had their common ownership\n"
311  "made public by common use as inputs or as the resulting change\n"
312  "in past transactions");
313 
314  Array jsonGroupings;
315  map<CTxDestination, int64> balances = pwalletMain->GetAddressBalances();
316  BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
317  {
318  Array jsonGrouping;
319  BOOST_FOREACH(CTxDestination address, grouping)
320  {
321  Array addressInfo;
322  addressInfo.push_back(CBitcoinAddress(address).ToString());
323  addressInfo.push_back(ValueFromAmount(balances[address]));
324  {
326  if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end())
327  addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second);
328  }
329  jsonGrouping.push_back(addressInfo);
330  }
331  jsonGroupings.push_back(jsonGrouping);
332  }
333  return jsonGroupings;
334 }
335 
336 Value signmessage(const Array& params, bool fHelp)
337 {
338  if (fHelp || params.size() != 2)
339  throw runtime_error(
340  "signmessage <feathercoinaddress> <message>\n"
341  "Sign a message with the private key of an address");
342 
344 
345  string strAddress = params[0].get_str();
346  string strMessage = params[1].get_str();
347 
348  CBitcoinAddress addr(strAddress);
349  if (!addr.IsValid())
350  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
351 
352  CKeyID keyID;
353  if (!addr.GetKeyID(keyID))
354  throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
355 
356  CKey key;
357  if (!pwalletMain->GetKey(keyID, key))
358  throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
359 
360  CHashWriter ss(SER_GETHASH, 0);
361  ss << strMessageMagic;
362  ss << strMessage;
363 
364  vector<unsigned char> vchSig;
365  if (!key.SignCompact(ss.GetHash(), vchSig))
366  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
367 
368  return EncodeBase64(&vchSig[0], vchSig.size());
369 }
370 
371 Value verifymessage(const Array& params, bool fHelp)
372 {
373  if (fHelp || params.size() != 3)
374  throw runtime_error(
375  "verifymessage <feathercoinaddress> <signature> <message>\n"
376  "Verify a signed message");
377 
378  string strAddress = params[0].get_str();
379  string strSign = params[1].get_str();
380  string strMessage = params[2].get_str();
381 
382  CBitcoinAddress addr(strAddress);
383  if (!addr.IsValid())
384  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
385 
386  CKeyID keyID;
387  if (!addr.GetKeyID(keyID))
388  throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
389 
390  bool fInvalid = false;
391  vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
392 
393  if (fInvalid)
394  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
395 
396  CHashWriter ss(SER_GETHASH, 0);
397  ss << strMessageMagic;
398  ss << strMessage;
399 
400  CPubKey pubkey;
401  if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
402  return false;
403 
404  return (pubkey.GetID() == keyID);
405 }
406 
407 
408 Value getreceivedbyaddress(const Array& params, bool fHelp)
409 {
410  if (fHelp || params.size() < 1 || params.size() > 2)
411  throw runtime_error(
412  "getreceivedbyaddress <feathercoinaddress> [minconf=1]\n"
413  "Returns the total amount received by <feathercoinaddress> in transactions with at least [minconf] confirmations.");
414 
415  // Bitcoin address
416  CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
417  CScript scriptPubKey;
418  if (!address.IsValid())
419  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Feathercoin address");
420  scriptPubKey.SetDestination(address.Get());
421  if (!IsMine(*pwalletMain,scriptPubKey))
422  return (double)0.0;
423 
424  // Minimum confirmations
425  int nMinDepth = 1;
426  if (params.size() > 1)
427  nMinDepth = params[1].get_int();
428 
429  // Tally
430  int64 nAmount = 0;
431  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
432  {
433  const CWalletTx& wtx = (*it).second;
434  if (wtx.IsCoinBase() || !wtx.IsFinal())
435  continue;
436 
437  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
438  if (txout.scriptPubKey == scriptPubKey)
439  if (wtx.GetDepthInMainChain() >= nMinDepth)
440  nAmount += txout.nValue;
441  }
442 
443  return ValueFromAmount(nAmount);
444 }
445 
446 
447 void GetAccountAddresses(string strAccount, set<CTxDestination>& setAddress)
448 {
449  BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& item, pwalletMain->mapAddressBook)
450  {
451  const CTxDestination& address = item.first;
452  const string& strName = item.second;
453  if (strName == strAccount)
454  setAddress.insert(address);
455  }
456 }
457 
458 Value getreceivedbyaccount(const Array& params, bool fHelp)
459 {
460  if (fHelp || params.size() < 1 || params.size() > 2)
461  throw runtime_error(
462  "getreceivedbyaccount <account> [minconf=1]\n"
463  "Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.");
464 
465  // Minimum confirmations
466  int nMinDepth = 1;
467  if (params.size() > 1)
468  nMinDepth = params[1].get_int();
469 
470  // Get the set of pub keys assigned to account
471  string strAccount = AccountFromValue(params[0]);
472  set<CTxDestination> setAddress;
473  GetAccountAddresses(strAccount, setAddress);
474 
475  // Tally
476  int64 nAmount = 0;
477  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
478  {
479  const CWalletTx& wtx = (*it).second;
480  if (wtx.IsCoinBase() || !wtx.IsFinal())
481  continue;
482 
483  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
484  {
485  CTxDestination address;
486  if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
487  if (wtx.GetDepthInMainChain() >= nMinDepth)
488  nAmount += txout.nValue;
489  }
490  }
491 
492  return (double)nAmount / (double)COIN;
493 }
494 
495 
496 int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
497 {
498  int64 nBalance = 0;
499 
500  // Tally wallet transactions
501  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
502  {
503  const CWalletTx& wtx = (*it).second;
504  if (!wtx.IsFinal())
505  continue;
506 
507  int64 nReceived, nSent, nFee;
508  wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee);
509 
510  if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
511  nBalance += nReceived;
512  nBalance -= nSent + nFee;
513  }
514 
515  // Tally internal accounting entries
516  nBalance += walletdb.GetAccountCreditDebit(strAccount);
517 
518  return nBalance;
519 }
520 
521 int64 GetAccountBalance(const string& strAccount, int nMinDepth)
522 {
524  return GetAccountBalance(walletdb, strAccount, nMinDepth);
525 }
526 
527 
528 Value getbalance(const Array& params, bool fHelp)
529 {
530  if (fHelp || params.size() > 2)
531  throw runtime_error(
532  "getbalance [account] [minconf=1]\n"
533  "If [account] is not specified, returns the server's total available balance.\n"
534  "If [account] is specified, returns the balance in the account.");
535 
536  if (params.size() == 0)
538 
539  int nMinDepth = 1;
540  if (params.size() > 1)
541  nMinDepth = params[1].get_int();
542 
543  if (params[0].get_str() == "*") {
544  // Calculate total balance a different way from GetBalance()
545  // (GetBalance() sums up all unspent TxOuts)
546  // getbalance and getbalance '*' 0 should return the same number
547  int64 nBalance = 0;
548  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
549  {
550  const CWalletTx& wtx = (*it).second;
551  if (!wtx.IsConfirmed())
552  continue;
553 
554  int64 allFee;
555  string strSentAccount;
556  list<pair<CTxDestination, int64> > listReceived;
557  list<pair<CTxDestination, int64> > listSent;
558  wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount);
559  if (wtx.GetDepthInMainChain() >= nMinDepth)
560  {
561  BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived)
562  nBalance += r.second;
563  }
564  BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent)
565  nBalance -= r.second;
566  nBalance -= allFee;
567  }
568  return ValueFromAmount(nBalance);
569  }
570 
571  string strAccount = AccountFromValue(params[0]);
572 
573  int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
574 
575  return ValueFromAmount(nBalance);
576 }
577 
578 
579 Value movecmd(const Array& params, bool fHelp)
580 {
581  if (fHelp || params.size() < 3 || params.size() > 5)
582  throw runtime_error(
583  "move <fromaccount> <toaccount> <amount> [minconf=1] [comment]\n"
584  "Move from one account in your wallet to another.");
585 
586  string strFrom = AccountFromValue(params[0]);
587  string strTo = AccountFromValue(params[1]);
588  int64 nAmount = AmountFromValue(params[2]);
589  if (params.size() > 3)
590  // unused parameter, used to be nMinDepth, keep type-checking it though
591  (void)params[3].get_int();
592  string strComment;
593  if (params.size() > 4)
594  strComment = params[4].get_str();
595 
597  if (!walletdb.TxnBegin())
598  throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
599 
600  int64 nNow = GetAdjustedTime();
601 
602  // Debit
603  CAccountingEntry debit;
604  debit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
605  debit.strAccount = strFrom;
606  debit.nCreditDebit = -nAmount;
607  debit.nTime = nNow;
608  debit.strOtherAccount = strTo;
609  debit.strComment = strComment;
610  walletdb.WriteAccountingEntry(debit);
611 
612  // Credit
613  CAccountingEntry credit;
614  credit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
615  credit.strAccount = strTo;
616  credit.nCreditDebit = nAmount;
617  credit.nTime = nNow;
618  credit.strOtherAccount = strFrom;
619  credit.strComment = strComment;
620  walletdb.WriteAccountingEntry(credit);
621 
622  if (!walletdb.TxnCommit())
623  throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
624 
625  return true;
626 }
627 
628 
629 Value sendfrom(const Array& params, bool fHelp)
630 {
631  if (fHelp || params.size() < 3 || params.size() > 6)
632  throw runtime_error(
633  "sendfrom <fromaccount> <tofeathercoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
634  "<amount> is a real and is rounded to the nearest 0.00000001"
636 
637  string strAccount = AccountFromValue(params[0]);
638  CBitcoinAddress address(params[1].get_str());
639  if (!address.IsValid())
640  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Feathercoin address");
641  int64 nAmount = AmountFromValue(params[2]);
642  int nMinDepth = 1;
643  if (params.size() > 3)
644  nMinDepth = params[3].get_int();
645 
646  CWalletTx wtx;
647  wtx.strFromAccount = strAccount;
648  if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty())
649  wtx.mapValue["comment"] = params[4].get_str();
650  if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty())
651  wtx.mapValue["to"] = params[5].get_str();
652 
654 
655  // Check funds
656  int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
657  if (nAmount > nBalance)
658  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
659 
660  // Send
661  string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
662  if (strError != "")
663  throw JSONRPCError(RPC_WALLET_ERROR, strError);
664 
665  return wtx.GetHash().GetHex();
666 }
667 
668 
669 Value sendmany(const Array& params, bool fHelp)
670 {
671  if (fHelp || params.size() < 2 || params.size() > 4)
672  throw runtime_error(
673  "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
674  "amounts are double-precision floating point numbers"
676 
677  string strAccount = AccountFromValue(params[0]);
678  Object sendTo = params[1].get_obj();
679  int nMinDepth = 1;
680  if (params.size() > 2)
681  nMinDepth = params[2].get_int();
682 
683  CWalletTx wtx;
684  wtx.strFromAccount = strAccount;
685  if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
686  wtx.mapValue["comment"] = params[3].get_str();
687 
688  set<CBitcoinAddress> setAddress;
689  vector<pair<CScript, int64> > vecSend;
690 
691  int64 totalAmount = 0;
692  BOOST_FOREACH(const Pair& s, sendTo)
693  {
694  CBitcoinAddress address(s.name_);
695  if (!address.IsValid())
696  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Feathercoin address: ")+s.name_);
697 
698  if (setAddress.count(address))
699  throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
700  setAddress.insert(address);
701 
702  CScript scriptPubKey;
703  scriptPubKey.SetDestination(address.Get());
704  int64 nAmount = AmountFromValue(s.value_);
705  totalAmount += nAmount;
706 
707  vecSend.push_back(make_pair(scriptPubKey, nAmount));
708  }
709 
711 
712  // Check funds
713  int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
714  if (totalAmount > nBalance)
715  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
716 
717  // Send
718  CReserveKey keyChange(pwalletMain);
719  int64 nFeeRequired = 0;
720  string strFailReason;
721  bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason);
722  if (!fCreated)
723  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
724  if (!pwalletMain->CommitTransaction(wtx, keyChange))
725  throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed");
726 
727  return wtx.GetHash().GetHex();
728 }
729 
730 //
731 // Used by addmultisigaddress / createmultisig:
732 //
733 static CScript _createmultisig(const Array& params)
734 {
735  int nRequired = params[0].get_int();
736  const Array& keys = params[1].get_array();
737 
738  // Gather public keys
739  if (nRequired < 1)
740  throw runtime_error("a multisignature address must require at least one key to redeem");
741  if ((int)keys.size() < nRequired)
742  throw runtime_error(
743  strprintf("not enough keys supplied "
744  "(got %"PRIszu" keys, but need at least %d to redeem)", keys.size(), nRequired));
745  std::vector<CPubKey> pubkeys;
746  pubkeys.resize(keys.size());
747  for (unsigned int i = 0; i < keys.size(); i++)
748  {
749  const std::string& ks = keys[i].get_str();
750 
751  // Case 1: Feathercoin address and we have full public key:
752  CBitcoinAddress address(ks);
753  if (pwalletMain && address.IsValid())
754  {
755  CKeyID keyID;
756  if (!address.GetKeyID(keyID))
757  throw runtime_error(
758  strprintf("%s does not refer to a key",ks.c_str()));
759  CPubKey vchPubKey;
760  if (!pwalletMain->GetPubKey(keyID, vchPubKey))
761  throw runtime_error(
762  strprintf("no full public key for address %s",ks.c_str()));
763  if (!vchPubKey.IsFullyValid())
764  throw runtime_error(" Invalid public key: "+ks);
765  pubkeys[i] = vchPubKey;
766  }
767 
768  // Case 2: hex public key
769  else if (IsHex(ks))
770  {
771  CPubKey vchPubKey(ParseHex(ks));
772  if (!vchPubKey.IsFullyValid())
773  throw runtime_error(" Invalid public key: "+ks);
774  pubkeys[i] = vchPubKey;
775  }
776  else
777  {
778  throw runtime_error(" Invalid public key: "+ks);
779  }
780  }
781  CScript result;
782  result.SetMultisig(nRequired, pubkeys);
783  return result;
784 }
785 
786 Value addmultisigaddress(const Array& params, bool fHelp)
787 {
788  if (fHelp || params.size() < 2 || params.size() > 3)
789  {
790  string msg = "addmultisigaddress <nrequired> <'[\"key\",\"key\"]'> [account]\n"
791  "Add a nrequired-to-sign multisignature address to the wallet\"\n"
792  "each key is a Feathercoin address or hex-encoded public key\n"
793  "If [account] is specified, assign address to [account].";
794  throw runtime_error(msg);
795  }
796 
797  string strAccount;
798  if (params.size() > 2)
799  strAccount = AccountFromValue(params[2]);
800 
801  // Construct using pay-to-script-hash:
802  CScript inner = _createmultisig(params);
803  CScriptID innerID = inner.GetID();
804  pwalletMain->AddCScript(inner);
805 
806  pwalletMain->SetAddressBookName(innerID, strAccount);
807  return CBitcoinAddress(innerID).ToString();
808 }
809 
810 Value createmultisig(const Array& params, bool fHelp)
811 {
812  if (fHelp || params.size() < 2 || params.size() > 2)
813  {
814  string msg = "createmultisig <nrequired> <'[\"key\",\"key\"]'>\n"
815  "Creates a multi-signature address and returns a json object\n"
816  "with keys:\n"
817  "address : feathercoin address\n"
818  "redeemScript : hex-encoded redemption script";
819  throw runtime_error(msg);
820  }
821 
822  // Construct using pay-to-script-hash:
823  CScript inner = _createmultisig(params);
824  CScriptID innerID = inner.GetID();
825  CBitcoinAddress address(innerID);
826 
827  Object result;
828  result.push_back(Pair("address", address.ToString()));
829  result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
830 
831  return result;
832 }
833 
834 
835 struct tallyitem
836 {
838  int nConf;
839  vector<uint256> txids;
841  {
842  nAmount = 0;
843  nConf = std::numeric_limits<int>::max();
844  }
845 };
846 
847 Value ListReceived(const Array& params, bool fByAccounts)
848 {
849  // Minimum confirmations
850  int nMinDepth = 1;
851  if (params.size() > 0)
852  nMinDepth = params[0].get_int();
853 
854  // Whether to include empty accounts
855  bool fIncludeEmpty = false;
856  if (params.size() > 1)
857  fIncludeEmpty = params[1].get_bool();
858 
859  // Tally
860  map<CBitcoinAddress, tallyitem> mapTally;
861  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
862  {
863  const CWalletTx& wtx = (*it).second;
864 
865  if (wtx.IsCoinBase() || !wtx.IsFinal())
866  continue;
867 
868  int nDepth = wtx.GetDepthInMainChain();
869  if (nDepth < nMinDepth)
870  continue;
871 
872  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
873  {
874  CTxDestination address;
875  if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address))
876  continue;
877 
878  tallyitem& item = mapTally[address];
879  item.nAmount += txout.nValue;
880  item.nConf = min(item.nConf, nDepth);
881  item.txids.push_back(wtx.GetHash());
882  }
883  }
884 
885  // Reply
886  Array ret;
887  map<string, tallyitem> mapAccountTally;
888  BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
889  {
890  const CBitcoinAddress& address = item.first;
891  const string& strAccount = item.second;
892  map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
893  if (it == mapTally.end() && !fIncludeEmpty)
894  continue;
895 
896  int64 nAmount = 0;
897  int nConf = std::numeric_limits<int>::max();
898  if (it != mapTally.end())
899  {
900  nAmount = (*it).second.nAmount;
901  nConf = (*it).second.nConf;
902  }
903 
904  if (fByAccounts)
905  {
906  tallyitem& item = mapAccountTally[strAccount];
907  item.nAmount += nAmount;
908  item.nConf = min(item.nConf, nConf);
909  }
910  else
911  {
912  Object obj;
913  obj.push_back(Pair("address", address.ToString()));
914  obj.push_back(Pair("account", strAccount));
915  obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
916  obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
917  Array transactions;
918  if (it != mapTally.end())
919  {
920  BOOST_FOREACH(const uint256& item, (*it).second.txids)
921  {
922  transactions.push_back(item.GetHex());
923  }
924  }
925  obj.push_back(Pair("txids", transactions));
926  ret.push_back(obj);
927  }
928  }
929 
930  if (fByAccounts)
931  {
932  for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
933  {
934  int64 nAmount = (*it).second.nAmount;
935  int nConf = (*it).second.nConf;
936  Object obj;
937  obj.push_back(Pair("account", (*it).first));
938  obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
939  obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
940  ret.push_back(obj);
941  }
942  }
943 
944  return ret;
945 }
946 
947 Value listreceivedbyaddress(const Array& params, bool fHelp)
948 {
949  if (fHelp || params.size() > 2)
950  throw runtime_error(
951  "listreceivedbyaddress [minconf=1] [includeempty=false]\n"
952  "[minconf] is the minimum number of confirmations before payments are included.\n"
953  "[includeempty] whether to include addresses that haven't received any payments.\n"
954  "Returns an array of objects containing:\n"
955  " \"address\" : receiving address\n"
956  " \"account\" : the account of the receiving address\n"
957  " \"amount\" : total amount received by the address\n"
958  " \"confirmations\" : number of confirmations of the most recent transaction included\n"
959  " \"txids\" : list of transactions with outputs to the address\n");
960 
961  return ListReceived(params, false);
962 }
963 
964 Value listreceivedbyaccount(const Array& params, bool fHelp)
965 {
966  if (fHelp || params.size() > 2)
967  throw runtime_error(
968  "listreceivedbyaccount [minconf=1] [includeempty=false]\n"
969  "[minconf] is the minimum number of confirmations before payments are included.\n"
970  "[includeempty] whether to include accounts that haven't received any payments.\n"
971  "Returns an array of objects containing:\n"
972  " \"account\" : the account of the receiving addresses\n"
973  " \"amount\" : total amount received by addresses with this account\n"
974  " \"confirmations\" : number of confirmations of the most recent transaction included");
975 
976  return ListReceived(params, true);
977 }
978 
979 void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
980 {
981  int64 nFee;
982  string strSentAccount;
983  list<pair<CTxDestination, int64> > listReceived;
984  list<pair<CTxDestination, int64> > listSent;
985 
986  wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount);
987 
988  bool fAllAccounts = (strAccount == string("*"));
989 
990  // Sent
991  if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
992  {
993  BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent)
994  {
995  Object entry;
996  entry.push_back(Pair("account", strSentAccount));
997  entry.push_back(Pair("address", CBitcoinAddress(s.first).ToString()));
998  entry.push_back(Pair("category", "send"));
999  entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
1000  entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1001  if (fLong)
1002  WalletTxToJSON(wtx, entry);
1003  ret.push_back(entry);
1004  }
1005  }
1006 
1007  // Received
1008  if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1009  {
1010  BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived)
1011  {
1012  string account;
1013  if (pwalletMain->mapAddressBook.count(r.first))
1014  account = pwalletMain->mapAddressBook[r.first];
1015  if (fAllAccounts || (account == strAccount))
1016  {
1017  Object entry;
1018  entry.push_back(Pair("account", account));
1019  entry.push_back(Pair("address", CBitcoinAddress(r.first).ToString()));
1020  if (wtx.IsCoinBase())
1021  {
1022  if (wtx.GetDepthInMainChain() < 1)
1023  entry.push_back(Pair("category", "orphan"));
1024  else if (wtx.GetBlocksToMaturity() > 0)
1025  entry.push_back(Pair("category", "immature"));
1026  else
1027  entry.push_back(Pair("category", "generate"));
1028  }
1029  else
1030  entry.push_back(Pair("category", "receive"));
1031  entry.push_back(Pair("amount", ValueFromAmount(r.second)));
1032  if (fLong)
1033  WalletTxToJSON(wtx, entry);
1034  ret.push_back(entry);
1035  }
1036  }
1037  }
1038 }
1039 
1040 void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret)
1041 {
1042  bool fAllAccounts = (strAccount == string("*"));
1043 
1044  if (fAllAccounts || acentry.strAccount == strAccount)
1045  {
1046  Object entry;
1047  entry.push_back(Pair("account", acentry.strAccount));
1048  entry.push_back(Pair("category", "move"));
1049  entry.push_back(Pair("time", (boost::int64_t)acentry.nTime));
1050  entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1051  entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1052  entry.push_back(Pair("comment", acentry.strComment));
1053  ret.push_back(entry);
1054  }
1055 }
1056 
1057 Value listtransactions(const Array& params, bool fHelp)
1058 {
1059  if (fHelp || params.size() > 3)
1060  throw runtime_error(
1061  "listtransactions [account] [count=10] [from=0]\n"
1062  "Returns up to [count] most recent transactions skipping the first [from] transactions for account [account].");
1063 
1064  string strAccount = "*";
1065  if (params.size() > 0)
1066  strAccount = params[0].get_str();
1067  int nCount = 10;
1068  if (params.size() > 1)
1069  nCount = params[1].get_int();
1070  int nFrom = 0;
1071  if (params.size() > 2)
1072  nFrom = params[2].get_int();
1073 
1074  if (nCount < 0)
1075  throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
1076  if (nFrom < 0)
1077  throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
1078 
1079  Array ret;
1080 
1081  std::list<CAccountingEntry> acentries;
1082  CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount);
1083 
1084  // iterate backwards until we have nCount items to return:
1085  for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1086  {
1087  CWalletTx *const pwtx = (*it).second.first;
1088  if (pwtx != 0)
1089  ListTransactions(*pwtx, strAccount, 0, true, ret);
1090  CAccountingEntry *const pacentry = (*it).second.second;
1091  if (pacentry != 0)
1092  AcentryToJSON(*pacentry, strAccount, ret);
1093 
1094  if ((int)ret.size() >= (nCount+nFrom)) break;
1095  }
1096  // ret is newest to oldest
1097 
1098  if (nFrom > (int)ret.size())
1099  nFrom = ret.size();
1100  if ((nFrom + nCount) > (int)ret.size())
1101  nCount = ret.size() - nFrom;
1102  Array::iterator first = ret.begin();
1103  std::advance(first, nFrom);
1104  Array::iterator last = ret.begin();
1105  std::advance(last, nFrom+nCount);
1106 
1107  if (last != ret.end()) ret.erase(last, ret.end());
1108  if (first != ret.begin()) ret.erase(ret.begin(), first);
1109 
1110  std::reverse(ret.begin(), ret.end()); // Return oldest to newest
1111 
1112  return ret;
1113 }
1114 
1115 Value listaccounts(const Array& params, bool fHelp)
1116 {
1117  if (fHelp || params.size() > 1)
1118  throw runtime_error(
1119  "listaccounts [minconf=1]\n"
1120  "Returns Object that has account names as keys, account balances as values.");
1121 
1122  int nMinDepth = 1;
1123  if (params.size() > 0)
1124  nMinDepth = params[0].get_int();
1125 
1126  map<string, int64> mapAccountBalances;
1127  BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) {
1128  if (IsMine(*pwalletMain, entry.first)) // This address belongs to me
1129  mapAccountBalances[entry.second] = 0;
1130  }
1131 
1132  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1133  {
1134  const CWalletTx& wtx = (*it).second;
1135  int64 nFee;
1136  string strSentAccount;
1137  list<pair<CTxDestination, int64> > listReceived;
1138  list<pair<CTxDestination, int64> > listSent;
1139  wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount);
1140  mapAccountBalances[strSentAccount] -= nFee;
1141  BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent)
1142  mapAccountBalances[strSentAccount] -= s.second;
1143  if (wtx.GetDepthInMainChain() >= nMinDepth)
1144  {
1145  BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived)
1146  if (pwalletMain->mapAddressBook.count(r.first))
1147  mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
1148  else
1149  mapAccountBalances[""] += r.second;
1150  }
1151  }
1152 
1153  list<CAccountingEntry> acentries;
1155  BOOST_FOREACH(const CAccountingEntry& entry, acentries)
1156  mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1157 
1158  Object ret;
1159  BOOST_FOREACH(const PAIRTYPE(string, int64)& accountBalance, mapAccountBalances) {
1160  ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1161  }
1162  return ret;
1163 }
1164 
1165 Value listsinceblock(const Array& params, bool fHelp)
1166 {
1167  if (fHelp)
1168  throw runtime_error(
1169  "listsinceblock [blockhash] [target-confirmations]\n"
1170  "Get all transactions in blocks since block [blockhash], or all transactions if omitted");
1171 
1172  CBlockIndex *pindex = NULL;
1173  int target_confirms = 1;
1174 
1175  if (params.size() > 0)
1176  {
1177  uint256 blockId = 0;
1178 
1179  blockId.SetHex(params[0].get_str());
1180  pindex = CBlockLocator(blockId).GetBlockIndex();
1181  }
1182 
1183  if (params.size() > 1)
1184  {
1185  target_confirms = params[1].get_int();
1186 
1187  if (target_confirms < 1)
1188  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
1189  }
1190 
1191  int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1;
1192 
1193  Array transactions;
1194 
1195  for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++)
1196  {
1197  CWalletTx tx = (*it).second;
1198 
1199  if (depth == -1 || tx.GetDepthInMainChain() < depth)
1200  ListTransactions(tx, "*", 0, true, transactions);
1201  }
1202 
1203  uint256 lastblock;
1204 
1205  if (target_confirms == 1)
1206  {
1207  lastblock = hashBestChain;
1208  }
1209  else
1210  {
1211  int target_height = pindexBest->nHeight + 1 - target_confirms;
1212 
1213  CBlockIndex *block;
1214  for (block = pindexBest;
1215  block && block->nHeight > target_height;
1216  block = block->pprev) { }
1217 
1218  lastblock = block ? block->GetBlockHash() : 0;
1219  }
1220 
1221  Object ret;
1222  ret.push_back(Pair("transactions", transactions));
1223  ret.push_back(Pair("lastblock", lastblock.GetHex()));
1224 
1225  return ret;
1226 }
1227 
1228 Value gettransaction(const Array& params, bool fHelp)
1229 {
1230  if (fHelp || params.size() != 1)
1231  throw runtime_error(
1232  "gettransaction <txid>\n"
1233  "Get detailed information about in-wallet transaction <txid>");
1234 
1235  uint256 hash;
1236  hash.SetHex(params[0].get_str());
1237 
1238  Object entry;
1239  if (!pwalletMain->mapWallet.count(hash))
1240  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
1241  const CWalletTx& wtx = pwalletMain->mapWallet[hash];
1242 
1243  int64 nCredit = wtx.GetCredit();
1244  int64 nDebit = wtx.GetDebit();
1245  int64 nNet = nCredit - nDebit;
1246  int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
1247 
1248  entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
1249  if (wtx.IsFromMe())
1250  entry.push_back(Pair("fee", ValueFromAmount(nFee)));
1251 
1252  WalletTxToJSON(wtx, entry);
1253 
1254  Array details;
1255  ListTransactions(wtx, "*", 0, false, details);
1256  entry.push_back(Pair("details", details));
1257 
1258  return entry;
1259 }
1260 
1261 
1262 Value backupwallet(const Array& params, bool fHelp)
1263 {
1264  if (fHelp || params.size() != 1)
1265  throw runtime_error(
1266  "backupwallet <destination>\n"
1267  "Safely copies wallet.dat to destination, which can be a directory or a path with filename.");
1268 
1269  string strDest = params[0].get_str();
1270  if (!BackupWallet(*pwalletMain, strDest))
1271  throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
1272 
1273  return Value::null;
1274 }
1275 
1276 
1277 Value keypoolrefill(const Array& params, bool fHelp)
1278 {
1279  if (fHelp || params.size() > 0)
1280  throw runtime_error(
1281  "keypoolrefill\n"
1282  "Fills the keypool."
1284 
1286 
1288 
1289  if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100))
1290  throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
1291 
1292  return Value::null;
1293 }
1294 
1295 
1296 void ThreadTopUpKeyPool(void* parg)
1297 {
1298  // Make this thread recognisable as the key-topping-up thread
1299  RenameThread("bitcoin-key-top");
1300 
1302 }
1303 
1305 {
1306  // Make this thread recognisable as the wallet relocking thread
1307  RenameThread("bitcoin-lock-wa");
1308 
1309  int64 nMyWakeTime = GetTimeMillis() + *((int64*)parg) * 1000;
1310 
1311  ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
1312 
1313  if (nWalletUnlockTime == 0)
1314  {
1315  nWalletUnlockTime = nMyWakeTime;
1316 
1317  do
1318  {
1319  if (nWalletUnlockTime==0)
1320  break;
1321  int64 nToSleep = nWalletUnlockTime - GetTimeMillis();
1322  if (nToSleep <= 0)
1323  break;
1324 
1325  LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
1326  MilliSleep(nToSleep);
1327  ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
1328 
1329  } while(1);
1330 
1331  if (nWalletUnlockTime)
1332  {
1333  nWalletUnlockTime = 0;
1334  pwalletMain->Lock();
1335  }
1336  }
1337  else
1338  {
1339  if (nWalletUnlockTime < nMyWakeTime)
1340  nWalletUnlockTime = nMyWakeTime;
1341  }
1342 
1343  LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
1344 
1345  delete (int64*)parg;
1346 }
1347 
1348 Value walletpassphrase(const Array& params, bool fHelp)
1349 {
1350  if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1351  throw runtime_error(
1352  "walletpassphrase <passphrase> <timeout>\n"
1353  "Stores the wallet decryption key in memory for <timeout> seconds.");
1354  if (fHelp)
1355  return true;
1356  if (!pwalletMain->IsCrypted())
1357  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
1358 
1359  if (!pwalletMain->IsLocked())
1360  throw JSONRPCError(RPC_WALLET_ALREADY_UNLOCKED, "Error: Wallet is already unlocked.");
1361 
1362  // Note that the walletpassphrase is stored in params[0] which is not mlock()ed
1363  SecureString strWalletPass;
1364  strWalletPass.reserve(100);
1365  // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1366  // Alternately, find a way to make params[0] mlock()'d to begin with.
1367  strWalletPass = params[0].get_str().c_str();
1368 
1369  if (strWalletPass.length() > 0)
1370  {
1371  if (!pwalletMain->Unlock(strWalletPass))
1372  throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
1373  }
1374  else
1375  throw runtime_error(
1376  "walletpassphrase <passphrase> <timeout>\n"
1377  "Stores the wallet decryption key in memory for <timeout> seconds.");
1378 
1380  int64* pnSleepTime = new int64(params[1].get_int64());
1381  NewThread(ThreadCleanWalletPassphrase, pnSleepTime);
1382 
1383  return Value::null;
1384 }
1385 
1386 
1387 Value walletpassphrasechange(const Array& params, bool fHelp)
1388 {
1389  if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1390  throw runtime_error(
1391  "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1392  "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1393  if (fHelp)
1394  return true;
1395  if (!pwalletMain->IsCrypted())
1396  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
1397 
1398  // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
1399  // Alternately, find a way to make params[0] mlock()'d to begin with.
1400  SecureString strOldWalletPass;
1401  strOldWalletPass.reserve(100);
1402  strOldWalletPass = params[0].get_str().c_str();
1403 
1404  SecureString strNewWalletPass;
1405  strNewWalletPass.reserve(100);
1406  strNewWalletPass = params[1].get_str().c_str();
1407 
1408  if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
1409  throw runtime_error(
1410  "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1411  "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1412 
1413  if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
1414  throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
1415 
1416  return Value::null;
1417 }
1418 
1419 
1420 Value walletlock(const Array& params, bool fHelp)
1421 {
1422  if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0))
1423  throw runtime_error(
1424  "walletlock\n"
1425  "Removes the wallet encryption key from memory, locking the wallet.\n"
1426  "After calling this method, you will need to call walletpassphrase again\n"
1427  "before being able to call any methods which require the wallet to be unlocked.");
1428  if (fHelp)
1429  return true;
1430  if (!pwalletMain->IsCrypted())
1431  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
1432 
1433  {
1434  LOCK(cs_nWalletUnlockTime);
1435  pwalletMain->Lock();
1436  nWalletUnlockTime = 0;
1437  }
1438 
1439  return Value::null;
1440 }
1441 
1442 
1443 Value encryptwallet(const Array& params, bool fHelp)
1444 {
1445  if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
1446  throw runtime_error(
1447  "encryptwallet <passphrase>\n"
1448  "Encrypts the wallet with <passphrase>.");
1449  if (fHelp)
1450  return true;
1451  if (pwalletMain->IsCrypted())
1452  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
1453 
1454  // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1455  // Alternately, find a way to make params[0] mlock()'d to begin with.
1456  SecureString strWalletPass;
1457  strWalletPass.reserve(100);
1458  strWalletPass = params[0].get_str().c_str();
1459 
1460  if (strWalletPass.length() < 1)
1461  throw runtime_error(
1462  "encryptwallet <passphrase>\n"
1463  "Encrypts the wallet with <passphrase>.");
1464 
1465  if (!pwalletMain->EncryptWallet(strWalletPass))
1466  throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
1467 
1468  // BDB seems to have a bad habit of writing old data into
1469  // slack space in .dat files; that is bad if the old data is
1470  // unencrypted private keys. So:
1471  StartShutdown();
1472  return "wallet encrypted; Feathercoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
1473 }
1474 
1475 class DescribeAddressVisitor : public boost::static_visitor<Object>
1476 {
1477 public:
1478  Object operator()(const CNoDestination &dest) const { return Object(); }
1479 
1480  Object operator()(const CKeyID &keyID) const {
1481  Object obj;
1482  CPubKey vchPubKey;
1483  pwalletMain->GetPubKey(keyID, vchPubKey);
1484  obj.push_back(Pair("isscript", false));
1485  obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
1486  obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
1487  return obj;
1488  }
1489 
1490  Object operator()(const CScriptID &scriptID) const {
1491  Object obj;
1492  obj.push_back(Pair("isscript", true));
1493  CScript subscript;
1494  pwalletMain->GetCScript(scriptID, subscript);
1495  std::vector<CTxDestination> addresses;
1496  txnouttype whichType;
1497  int nRequired;
1498  ExtractDestinations(subscript, whichType, addresses, nRequired);
1499  obj.push_back(Pair("script", GetTxnOutputType(whichType)));
1500  Array a;
1501  BOOST_FOREACH(const CTxDestination& addr, addresses)
1502  a.push_back(CBitcoinAddress(addr).ToString());
1503  obj.push_back(Pair("addresses", a));
1504  if (whichType == TX_MULTISIG)
1505  obj.push_back(Pair("sigsrequired", nRequired));
1506  return obj;
1507  }
1508 };
1509 
1510 Value validateaddress(const Array& params, bool fHelp)
1511 {
1512  if (fHelp || params.size() != 1)
1513  throw runtime_error(
1514  "validateaddress <feathercoinaddress>\n"
1515  "Return information about <feathercoinaddress>.");
1516 
1517  CBitcoinAddress address(params[0].get_str());
1518  bool isValid = address.IsValid();
1519 
1520  Object ret;
1521  ret.push_back(Pair("isvalid", isValid));
1522  if (isValid)
1523  {
1524  CTxDestination dest = address.Get();
1525  string currentAddress = address.ToString();
1526  ret.push_back(Pair("address", currentAddress));
1527  bool fMine = pwalletMain ? IsMine(*pwalletMain, dest) : false;
1528  ret.push_back(Pair("ismine", fMine));
1529  if (fMine) {
1530  Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
1531  ret.insert(ret.end(), detail.begin(), detail.end());
1532  }
1533  if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
1534  ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest]));
1535  }
1536  return ret;
1537 }
1538 
1539 Value lockunspent(const Array& params, bool fHelp)
1540 {
1541  if (fHelp || params.size() < 1 || params.size() > 2)
1542  throw runtime_error(
1543  "lockunspent unlock? [array-of-Objects]\n"
1544  "Updates list of temporarily unspendable outputs.");
1545 
1546  if (params.size() == 1)
1547  RPCTypeCheck(params, list_of(bool_type));
1548  else
1549  RPCTypeCheck(params, list_of(bool_type)(array_type));
1550 
1551  bool fUnlock = params[0].get_bool();
1552 
1553  if (params.size() == 1) {
1554  if (fUnlock)
1556  return true;
1557  }
1558 
1559  Array outputs = params[1].get_array();
1560  BOOST_FOREACH(Value& output, outputs)
1561  {
1562  if (output.type() != obj_type)
1563  throw JSONRPCError(-8, "Invalid parameter, expected object");
1564  const Object& o = output.get_obj();
1565 
1566  RPCTypeCheck(o, map_list_of("txid", str_type)("vout", int_type));
1567 
1568  string txid = find_value(o, "txid").get_str();
1569  if (!IsHex(txid))
1570  throw JSONRPCError(-8, "Invalid parameter, expected hex txid");
1571 
1572  int nOutput = find_value(o, "vout").get_int();
1573  if (nOutput < 0)
1574  throw JSONRPCError(-8, "Invalid parameter, vout must be positive");
1575 
1576  COutPoint outpt(uint256(txid), nOutput);
1577 
1578  if (fUnlock)
1579  pwalletMain->UnlockCoin(outpt);
1580  else
1581  pwalletMain->LockCoin(outpt);
1582  }
1583 
1584  return true;
1585 }
1586 
1587 Value listlockunspent(const Array& params, bool fHelp)
1588 {
1589  if (fHelp || params.size() > 0)
1590  throw runtime_error(
1591  "listlockunspent\n"
1592  "Returns list of temporarily unspendable outputs.");
1593 
1594  vector<COutPoint> vOutpts;
1595  pwalletMain->ListLockedCoins(vOutpts);
1596 
1597  Array ret;
1598 
1599  BOOST_FOREACH(COutPoint &outpt, vOutpts) {
1600  Object o;
1601 
1602  o.push_back(Pair("txid", outpt.hash.GetHex()));
1603  o.push_back(Pair("vout", (int)outpt.n));
1604  ret.push_back(o);
1605  }
1606 
1607  return ret;
1608 }
1609 
Value verifymessage(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:371
Value getaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:215
const Object & get_obj() const
Value sendmany(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:669
void SetHex(const char *psz)
Definition: uint256.h:306
#define PRIszu
Definition: util.h:70
bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
Definition: main.h:520
bool IsValid() const
Definition: base58.h:296
Value keypoolrefill(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1277
bool IsCrypted() const
Definition: keystore.h:120
void GetAccountAmounts(const std::string &strAccount, int64 &nReceived, int64 &nSent, int64 &nFee) const
Definition: wallet.cpp:677
Account information.
Definition: wallet.h:758
#define strprintf(format,...)
Definition: util.h:169
Value getreceivedbyaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:408
double GetDifficulty(const CBlockIndex *blockindex=NULL)
CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
Definition: rpcwallet.cpp:128
int64 GetAccountCreditDebit(const std::string &strAccount)
Definition: walletdb.cpp:56
void ListTransactions(const CWalletTx &wtx, const string &strAccount, int nMinDepth, bool fLong, Array &ret)
Definition: rpcwallet.cpp:979
std::string * value
Definition: version_set.cc:270
bool WriteAccount(const std::string &strAccount, const CAccount &account)
Definition: walletdb.cpp:41
Value getaddressesbyaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:234
CScript scriptPubKey
Definition: main.h:404
CBlockIndex * pprev
Definition: main.h:1633
Definition: util.cpp:28
void ListLockedCoins(std::vector< COutPoint > &vOutpts)
Definition: wallet.cpp:1903
#define PAIRTYPE(t1, t2)
Definition: util.h:78
CCriticalSection cs_wallet
Definition: wallet.h:83
int64 nTime
Definition: wallet.h:791
int64 GetTimeOffset()
Definition: util.cpp:1312
int nIndex
Definition: main.h:1128
std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx &wtxNew, bool fAskFee=false)
Definition: wallet.cpp:1420
Object operator()(const CScriptID &scriptID) const
Definition: rpcwallet.cpp:1490
std::string strFromAccount
Definition: wallet.h:380
Value createmultisig(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:810
int64 AmountFromValue(const Value &value)
Definition: bitcoinrpc.cpp:94
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: main.h:1968
int64 GetOldestKeyPoolTime()
Definition: wallet.cpp:1670
void StartShutdown()
Definition: init.cpp:82
uint256 hashBlock
Definition: main.h:1126
Value backupwallet(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1262
int64 nMinimumInputValue
Definition: main.cpp:85
bool IsFromMe() const
Definition: wallet.h:635
string GetWarnings(string strFor)
Definition: main.cpp:3075
uint256 GetHash() const
Definition: main.h:515
bool IsLocked() const
Definition: keystore.h:125
void ListAccountCreditDebit(const std::string &strAccount, std::list< CAccountingEntry > &acentries)
Definition: walletdb.cpp:68
const char * GetTxnOutputType(txnouttype t)
Definition: script.cpp:73
bool IsHex(const string &str)
Definition: util.cpp:490
Value getreceivedbyaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:458
unsigned int n
Definition: main.h:282
Object JSONRPCError(int code, const string &message)
Definition: bitcoinrpc.cpp:46
CTxDestination Get() const
Definition: base58.h:345
bool GetKey(const CKeyID &address, CKey &keyOut) const
Definition: keystore.cpp:142
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
Definition: keystore.cpp:166
void RenameThread(const char *name)
Definition: util.cpp:1467
const string strMessageMagic
Definition: main.cpp:78
Config::Object_type Object
int64 nTransactionFee
Definition: main.cpp:84
void EnsureWalletIsUnlocked()
Definition: rpcwallet.cpp:29
Value listlockunspent(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1587
int64 GetCredit(bool fUseCache=true) const
Definition: wallet.h:565
int GetKeyPoolSize()
Definition: wallet.h:288
bool TxnBegin()
Definition: db.h:266
Value ListReceived(const Array &params, bool fByAccounts)
Definition: rpcwallet.cpp:847
vector< CNode * > vNodes
Definition: net.cpp:56
bool SetAddressBookName(const CTxDestination &address, const std::string &strName)
Definition: wallet.cpp:1463
bool GetKeyID(CKeyID &keyID) const
Definition: base58.h:365
mapValue_t mapValue
Definition: wallet.h:374
bool NewThread(void(*pfn)(void *), void *parg)
Definition: util.cpp:1491
Value validateaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1510
void SetDestination(const CTxDestination &address)
Definition: script.cpp:1768
int64 GetTimeMillis()
Definition: util.h:340
Value listreceivedbyaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:947
void MilliSleep(int64 n)
Definition: util.h:106
void AcentryToJSON(const CAccountingEntry &acentry, const string &strAccount, Array &ret)
Definition: rpcwallet.cpp:1040
int GetBlocksToMaturity() const
Definition: main.cpp:931
std::string strComment
Definition: wallet.h:793
string EncodeBase64(const unsigned char *pch, size_t len)
Definition: util.cpp:628
Value lockunspent(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1539
Value_type type() const
void RPCTypeCheck(const Array &params, const list< Value_type > &typesExpected, bool fAllowNull)
Definition: bitcoinrpc.cpp:54
bool IsConfirmed() const
Definition: wallet.h:640
bool fTestNet
Definition: util.cpp:81
Value listreceivedbyaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:964
void LockCoin(COutPoint &output)
Definition: wallet.cpp:1881
Value walletlock(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1420
bool WriteAccountingEntry(const uint64 nAccEntryNum, const CAccountingEntry &acentry)
Definition: walletdb.cpp:46
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
Definition: wallet.cpp:114
#define LEAVE_CRITICAL_SECTION(cs)
Definition: sync.h:118
Value getaccountaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:166
void GetAccountAddresses(string strAccount, set< CTxDestination > &setAddress)
Definition: rpcwallet.cpp:447
#define LOCK(cs)
Definition: sync.h:108
Value walletpassphrase(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1348
std::vector< CTxOut > vout
Definition: main.h:485
Value sendfrom(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:629
txnouttype
Definition: script.h:40
const Object_type::value_type::Value_type & find_value(const Object_type &obj, const String_type &name)
Object operator()(const CKeyID &keyID) const
Definition: rpcwallet.cpp:1480
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Definition: key.cpp:354
int GetVersion()
Definition: wallet.h:304
CBlockIndex * GetBlockIndex()
Definition: main.h:2050
void UnlockCoin(COutPoint &output)
Definition: wallet.cpp:1886
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: allocators.h:269
An encapsulated public key.
Definition: key.h:40
bool TxnCommit()
Definition: db.h:277
Value walletpassphrasechange(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1387
int64 GetAdjustedTime()
Definition: util.cpp:1317
int64 GetDebit() const
Definition: wallet.h:554
CWallet * pwalletMain
Definition: init.cpp:31
int64 nAmount
Definition: rpcwallet.cpp:837
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey)
Definition: wallet.cpp:1338
std::string ToString() const
Definition: base58.h:229
Config::Array_type Array
Value movecmd(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:579
Value getinfo(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:62
const String_type & get_str() const
An output of a transaction.
Definition: main.h:400
std::set< std::set< CTxDestination > > GetAddressGroupings()
Definition: wallet.cpp:1721
int64 nWalletUnlockTime
Definition: rpcwallet.cpp:19
int64 GetValueOut() const
Amount of bitcoins spent by this transaction.
Definition: main.h:602
Value sendtoaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:273
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: main.h:278
int64 GetBalance() const
Definition: wallet.cpp:922
string AccountFromValue(const Value &value)
Definition: rpcwallet.cpp:54
Object operator()(const CNoDestination &dest) const
Definition: rpcwallet.cpp:1478
std::string GetHex() const
Definition: uint256.h:298
Value addmultisigaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:786
Access to the wallet database (wallet.dat)
Definition: walletdb.h:27
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:367
std::string strWalletFile
Definition: wallet.h:86
CPubKey vchPubKey
Definition: wallet.h:761
int64 GetTxTime() const
Definition: wallet.cpp:592
void ThreadCleanWalletPassphrase(void *parg)
Definition: rpcwallet.cpp:1304
void ThreadTopUpKeyPool(void *parg)
Definition: rpcwallet.cpp:1296
bool IsCompressed() const
Definition: key.h:147
#define ENTER_CRITICAL_SECTION(cs)
Definition: sync.h:112
uint256 GetHash()
Definition: hash.h:49
256-bit unsigned integer
Definition: uint256.h:537
uint256 hashBestChain
Definition: main.cpp:44
Value signmessage(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:336
Value ValueFromAmount(int64 amount)
Definition: bitcoinrpc.cpp:105
bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet, vector< CTxDestination > &addressRet, int &nRequiredRet)
Definition: script.cpp:1448
bool EncryptWallet(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:222
A key allocated from the key pool.
Definition: wallet.h:318
int64 nValue
Definition: main.h:403
bool SignCompact(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Definition: key.cpp:329
void GetAmounts(std::list< std::pair< CTxDestination, int64 > > &listReceived, std::list< std::pair< CTxDestination, int64 > > &listSent, int64 &nFee, std::string &strSentAccount) const
Definition: wallet.cpp:637
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: main.h:1626
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:244
Value getnewaddress(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:99
vector< uint256 > txids
Definition: rpcwallet.cpp:839
Value setmininput(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:256
void SetMultisig(int nRequired, const std::vector< CPubKey > &keys)
Definition: script.cpp:1773
bool IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: script.cpp:1378
A reference to a CKey: the Hash160 of its serialized public key.
Definition: key.h:24
Internal transfers.
Definition: wallet.h:786
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Definition: script.cpp:1422
bool GetKeyFromPool(CPubKey &key, bool fAllowReuse=true)
Definition: wallet.cpp:1646
bool Unlock(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:91
bool IsFullyValid() const
Definition: key.cpp:379
CScriptID GetID() const
Definition: script.h:589
void WalletTxToJSON(const CWalletTx &wtx, Object &entry)
Definition: rpcwallet.cpp:35
bool IsValid() const
Definition: key.h:139
int GetDepthInMainChain(CBlockIndex *&pindexRet) const
Definition: main.cpp:905
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const
Definition: keystore.cpp:42
std::string HelpRequiringPassphrase()
Definition: rpcwallet.cpp:22
bool TopUpKeyPool()
Definition: wallet.cpp:1557
std::pair< CService, int > proxyType
Definition: netbase.h:134
bool BackupWallet(const CWallet &wallet, const std::string &strDest)
void UnlockAllCoins()
Definition: wallet.cpp:1891
std::map< CTxDestination, std::string > mapAddressBook
Definition: wallet.h:119
Value listaccounts(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1115
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:115
Value gettransaction(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1228
Value listaddressgroupings(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:305
bool IsCoinBase() const
Definition: main.h:566
signed long long int64_t
Definition: stdint.h:18
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: key.h:32
int64 nOrderPos
Definition: wallet.h:795
CBlockIndex * pindexBest
Definition: main.cpp:45
bool AddCScript(const CScript &redeemScript)
Definition: wallet.cpp:82
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:432
Value listtransactions(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1057
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Definition: util.cpp:586
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: script.h:62
std::map< CTxDestination, int64 > GetAddressBalances()
Definition: wallet.cpp:1681
unsigned int nTimeReceived
Definition: wallet.h:377
An encapsulated private key.
Definition: key.h:172
int nHeight
Definition: main.h:1639
vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
Definition: util.cpp:679
int64 nCreditDebit
Definition: wallet.h:790
Value listsinceblock(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1165
int nBestHeight
Definition: main.cpp:41
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
Definition: util.h:292
Value setaccount(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:185
Value getbalance(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:528
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end)
CKeyID GetID() const
Definition: key.h:129
Value encryptwallet(const Array &params, bool fHelp)
Definition: rpcwallet.cpp:1443
Config::Pair_type Pair
std::string strOtherAccount
Definition: wallet.h:792
map< uint256, CBlockIndex * > mapBlockIndex
Definition: main.cpp:37
vector< unsigned char > ParseHex(const char *psz)
Definition: util.cpp:500
uint32_t hash
Definition: cache.cc:34
std::multimap< int64, TxPair > TxItems
Definition: wallet.h:163
bool ReadAccount(const std::string &strAccount, CAccount &account)
Definition: walletdb.cpp:35
int64 IncOrderPosNext(CWalletDB *pwalletdb=NULL)
Increment the next transaction order id.
Definition: wallet.cpp:303
bool CreateTransaction(const std::vector< std::pair< CScript, int64 > > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, int64 &nFeeRet, std::string &strFailReason, const CCoinControl *coinControl=NULL)
uint256 GetBlockHash() const
Definition: main.h:1744
TxItems OrderedTxItems(std::list< CAccountingEntry > &acentries, std::string strAccount="")
Get the wallet's activity log.
Definition: wallet.cpp:314
uint256 hash
Definition: main.h:281
long long int64
Definition: serialize.h:25
std::string strAccount
Definition: wallet.h:789
int64 GetAccountBalance(CWalletDB &walletdb, const string &strAccount, int nMinDepth)
Definition: rpcwallet.cpp:496