Merge branch '0.5.x' into 0.6.0.x
[novacoin.git] / src / bitcoinrpc.cpp
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 license.txt or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "headers.h"
7 #include "db.h"
8 #include "net.h"
9 #include "init.h"
10 #undef printf
11 #include <boost/asio.hpp>
12 #include <boost/filesystem.hpp>
13 #include <boost/iostreams/concepts.hpp>
14 #include <boost/iostreams/stream.hpp>
15 #include <boost/algorithm/string.hpp>
16 #include <boost/lexical_cast.hpp>
17 #ifdef USE_SSL
18 #include <boost/asio/ssl.hpp> 
19 #include <boost/filesystem.hpp>
20 #include <boost/filesystem/fstream.hpp>
21 typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
22 #endif
23 #include "json/json_spirit_reader_template.h"
24 #include "json/json_spirit_writer_template.h"
25 #include "json/json_spirit_utils.h"
26 #define printf OutputDebugStringF
27 // MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are
28 // precompiled in headers.h.  The problem might be when the pch file goes over
29 // a certain size around 145MB.  If we need access to json_spirit outside this
30 // file, we could use the compiled json_spirit option.
31
32 using namespace std;
33 using namespace boost;
34 using namespace boost::asio;
35 using namespace json_spirit;
36
37 void ThreadRPCServer2(void* parg);
38 typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
39 extern map<string, rpcfn_type> mapCallTable;
40
41 static std::string strRPCUserColonPass;
42
43 static int64 nWalletUnlockTime;
44 static CCriticalSection cs_nWalletUnlockTime;
45
46 extern Value dumpprivkey(const Array& params, bool fHelp);
47 extern Value importprivkey(const Array& params, bool fHelp);
48
49 Object JSONRPCError(int code, const string& message)
50 {
51     Object error;
52     error.push_back(Pair("code", code));
53     error.push_back(Pair("message", message));
54     return error;
55 }
56
57 double GetDifficulty(const CBlockIndex* blockindex = NULL)
58 {
59     // Floating point number that is a multiple of the minimum difficulty,
60     // minimum difficulty = 1.0.
61     if (blockindex == NULL)
62     {
63         if (pindexBest == NULL)
64             return 1.0;
65         else
66             blockindex = pindexBest;
67     }
68
69     int nShift = (blockindex->nBits >> 24) & 0xff;
70
71     double dDiff =
72         (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
73
74     while (nShift < 29)
75     {
76         dDiff *= 256.0;
77         nShift++;
78     }
79     while (nShift > 29)
80     {
81         dDiff /= 256.0;
82         nShift--;
83     }
84
85     return dDiff;
86 }
87
88
89 int64 AmountFromValue(const Value& value)
90 {
91     double dAmount = value.get_real();
92     if (dAmount <= 0.0 || dAmount > 21000000.0)
93         throw JSONRPCError(-3, "Invalid amount");
94     int64 nAmount = roundint64(dAmount * COIN);
95     if (!MoneyRange(nAmount))
96         throw JSONRPCError(-3, "Invalid amount");
97     return nAmount;
98 }
99
100 Value ValueFromAmount(int64 amount)
101 {
102     return (double)amount / (double)COIN;
103 }
104
105 std::string
106 HexBits(unsigned int nBits)
107 {
108     union {
109         int32_t nBits;
110         char cBits[4];
111     } uBits;
112     uBits.nBits = htonl((int32_t)nBits);
113     return HexStr(BEGIN(uBits.cBits), END(uBits.cBits));
114 }
115
116 void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
117 {
118     int confirms = wtx.GetDepthInMainChain();
119     entry.push_back(Pair("confirmations", confirms));
120     if (confirms)
121     {
122         entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
123         entry.push_back(Pair("blockindex", wtx.nIndex));
124     }
125     entry.push_back(Pair("txid", wtx.GetHash().GetHex()));
126     entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime()));
127     BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
128         entry.push_back(Pair(item.first, item.second));
129 }
130
131 string AccountFromValue(const Value& value)
132 {
133     string strAccount = value.get_str();
134     if (strAccount == "*")
135         throw JSONRPCError(-11, "Invalid account name");
136     return strAccount;
137 }
138
139 Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
140 {
141     Object result;
142     result.push_back(Pair("hash", block.GetHash().GetHex()));
143     result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK)));
144     result.push_back(Pair("height", blockindex->nHeight));
145     result.push_back(Pair("version", block.nVersion));
146     result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
147     result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime()));
148     result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce));
149     result.push_back(Pair("bits", HexBits(block.nBits)));
150     result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
151     Array txhashes;
152     BOOST_FOREACH (const CTransaction&tx, block.vtx)
153         txhashes.push_back(tx.GetHash().GetHex());
154     result.push_back(Pair("tx", txhashes));
155
156     if (blockindex->pprev)
157         result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
158     if (blockindex->pnext)
159         result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex()));
160     return result;
161 }
162
163
164
165 ///
166 /// Note: This interface may still be subject to change.
167 ///
168
169
170 Value help(const Array& params, bool fHelp)
171 {
172     if (fHelp || params.size() > 1)
173         throw runtime_error(
174             "help [command]\n"
175             "List commands, or get help for a command.");
176
177     string strCommand;
178     if (params.size() > 0)
179         strCommand = params[0].get_str();
180
181     string strRet;
182     set<rpcfn_type> setDone;
183     for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
184     {
185         string strMethod = (*mi).first;
186         // We already filter duplicates, but these deprecated screw up the sort order
187         if (strMethod == "getamountreceived" ||
188             strMethod == "getallreceived" ||
189             strMethod == "getblocknumber" || // deprecated
190             (strMethod.find("label") != string::npos))
191             continue;
192         if (strCommand != "" && strMethod != strCommand)
193             continue;
194         try
195         {
196             Array params;
197             rpcfn_type pfn = (*mi).second;
198             if (setDone.insert(pfn).second)
199                 (*pfn)(params, true);
200         }
201         catch (std::exception& e)
202         {
203             // Help text is returned in an exception
204             string strHelp = string(e.what());
205             if (strCommand == "")
206                 if (strHelp.find('\n') != string::npos)
207                     strHelp = strHelp.substr(0, strHelp.find('\n'));
208             strRet += strHelp + "\n";
209         }
210     }
211     if (strRet == "")
212         strRet = strprintf("help: unknown command: %s\n", strCommand.c_str());
213     strRet = strRet.substr(0,strRet.size()-1);
214     return strRet;
215 }
216
217
218 Value stop(const Array& params, bool fHelp)
219 {
220     if (fHelp || params.size() != 0)
221         throw runtime_error(
222             "stop\n"
223             "Stop bitcoin server.");
224 #ifndef QT_GUI
225     // Shutdown will take long enough that the response should get back
226     CreateThread(Shutdown, NULL);
227     return "bitcoin server stopping";
228 #else
229     throw runtime_error("NYI: cannot shut down GUI with RPC command");
230 #endif
231 }
232
233
234 Value getblockcount(const Array& params, bool fHelp)
235 {
236     if (fHelp || params.size() != 0)
237         throw runtime_error(
238             "getblockcount\n"
239             "Returns the number of blocks in the longest block chain.");
240
241     return nBestHeight;
242 }
243
244
245 // deprecated
246 Value getblocknumber(const Array& params, bool fHelp)
247 {
248     if (fHelp || params.size() != 0)
249         throw runtime_error(
250             "getblocknumber\n"
251             "Deprecated.  Use getblockcount.");
252
253     return nBestHeight;
254 }
255
256
257 Value getconnectioncount(const Array& params, bool fHelp)
258 {
259     if (fHelp || params.size() != 0)
260         throw runtime_error(
261             "getconnectioncount\n"
262             "Returns the number of connections to other nodes.");
263
264     return (int)vNodes.size();
265 }
266
267
268 Value getdifficulty(const Array& params, bool fHelp)
269 {
270     if (fHelp || params.size() != 0)
271         throw runtime_error(
272             "getdifficulty\n"
273             "Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");
274
275     return GetDifficulty();
276 }
277
278
279 Value getgenerate(const Array& params, bool fHelp)
280 {
281     if (fHelp || params.size() != 0)
282         throw runtime_error(
283             "getgenerate\n"
284             "Returns true or false.");
285
286     return GetBoolArg("-gen");
287 }
288
289
290 Value setgenerate(const Array& params, bool fHelp)
291 {
292     if (fHelp || params.size() < 1 || params.size() > 2)
293         throw runtime_error(
294             "setgenerate <generate> [genproclimit]\n"
295             "<generate> is true or false to turn generation on or off.\n"
296             "Generation is limited to [genproclimit] processors, -1 is unlimited.");
297
298     bool fGenerate = true;
299     if (params.size() > 0)
300         fGenerate = params[0].get_bool();
301
302     if (params.size() > 1)
303     {
304         int nGenProcLimit = params[1].get_int();
305         mapArgs["-genproclimit"] = itostr(nGenProcLimit);
306         if (nGenProcLimit == 0)
307             fGenerate = false;
308     }
309     mapArgs["-gen"] = (fGenerate ? "1" : "0");
310
311     GenerateBitcoins(fGenerate, pwalletMain);
312     return Value::null;
313 }
314
315
316 Value gethashespersec(const Array& params, bool fHelp)
317 {
318     if (fHelp || params.size() != 0)
319         throw runtime_error(
320             "gethashespersec\n"
321             "Returns a recent hashes per second performance measurement while generating.");
322
323     if (GetTimeMillis() - nHPSTimerStart > 8000)
324         return (boost::int64_t)0;
325     return (boost::int64_t)dHashesPerSec;
326 }
327
328
329 Value getinfo(const Array& params, bool fHelp)
330 {
331     if (fHelp || params.size() != 0)
332         throw runtime_error(
333             "getinfo\n"
334             "Returns an object containing various state info.");
335
336     Object obj;
337     obj.push_back(Pair("version",       (int)CLIENT_VERSION));
338     obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
339     obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
340     obj.push_back(Pair("balance",       ValueFromAmount(pwalletMain->GetBalance())));
341     obj.push_back(Pair("blocks",        (int)nBestHeight));
342     obj.push_back(Pair("connections",   (int)vNodes.size()));
343     obj.push_back(Pair("proxy",         (fUseProxy ? addrProxy.ToStringIPPort() : string())));
344     obj.push_back(Pair("difficulty",    (double)GetDifficulty()));
345     obj.push_back(Pair("testnet",       fTestNet));
346     obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
347     obj.push_back(Pair("keypoolsize",   pwalletMain->GetKeyPoolSize()));
348     obj.push_back(Pair("paytxfee",      ValueFromAmount(nTransactionFee)));
349     if (pwalletMain->IsCrypted())
350         obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000));
351     obj.push_back(Pair("errors",        GetWarnings("statusbar")));
352     return obj;
353 }
354
355
356 Value getmininginfo(const Array& params, bool fHelp)
357 {
358     if (fHelp || params.size() != 0)
359         throw runtime_error(
360             "getmininginfo\n"
361             "Returns an object containing mining-related information.");
362
363     Object obj;
364     obj.push_back(Pair("blocks",        (int)nBestHeight));
365     obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize));
366     obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx));
367     obj.push_back(Pair("difficulty",    (double)GetDifficulty()));
368     obj.push_back(Pair("errors",        GetWarnings("statusbar")));
369     obj.push_back(Pair("generate",      GetBoolArg("-gen")));
370     obj.push_back(Pair("genproclimit",  (int)GetArg("-genproclimit", -1)));
371     obj.push_back(Pair("hashespersec",  gethashespersec(params, false)));
372     obj.push_back(Pair("pooledtx",      (uint64_t)nPooledTx));
373     obj.push_back(Pair("testnet",       fTestNet));
374     return obj;
375 }
376
377
378 Value getnewaddress(const Array& params, bool fHelp)
379 {
380     if (fHelp || params.size() > 1)
381         throw runtime_error(
382             "getnewaddress [account]\n"
383             "Returns a new bitcoin address for receiving payments.  "
384             "If [account] is specified (recommended), it is added to the address book "
385             "so payments received with the address will be credited to [account].");
386
387     // Parse the account first so we don't generate a key if there's an error
388     string strAccount;
389     if (params.size() > 0)
390         strAccount = AccountFromValue(params[0]);
391
392     if (!pwalletMain->IsLocked())
393         pwalletMain->TopUpKeyPool();
394
395     // Generate a new key that is added to wallet
396     std::vector<unsigned char> newKey;
397     if (!pwalletMain->GetKeyFromPool(newKey, false))
398         throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
399     CBitcoinAddress address(newKey);
400
401     pwalletMain->SetAddressBookName(address, strAccount);
402
403     return address.ToString();
404 }
405
406
407 CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
408 {
409     CWalletDB walletdb(pwalletMain->strWalletFile);
410
411     CAccount account;
412     walletdb.ReadAccount(strAccount, account);
413
414     bool bKeyUsed = false;
415
416     // Check if the current key has been used
417     if (!account.vchPubKey.empty())
418     {
419         CScript scriptPubKey;
420         scriptPubKey.SetBitcoinAddress(account.vchPubKey);
421         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
422              it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
423              ++it)
424         {
425             const CWalletTx& wtx = (*it).second;
426             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
427                 if (txout.scriptPubKey == scriptPubKey)
428                     bKeyUsed = true;
429         }
430     }
431
432     // Generate a new key
433     if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
434     {
435         if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
436             throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
437
438         pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
439         walletdb.WriteAccount(strAccount, account);
440     }
441
442     return CBitcoinAddress(account.vchPubKey);
443 }
444
445 Value getaccountaddress(const Array& params, bool fHelp)
446 {
447     if (fHelp || params.size() != 1)
448         throw runtime_error(
449             "getaccountaddress <account>\n"
450             "Returns the current bitcoin address for receiving payments to this account.");
451
452     // Parse the account first so we don't generate a key if there's an error
453     string strAccount = AccountFromValue(params[0]);
454
455     Value ret;
456
457     ret = GetAccountAddress(strAccount).ToString();
458
459     return ret;
460 }
461
462
463
464 Value setaccount(const Array& params, bool fHelp)
465 {
466     if (fHelp || params.size() < 1 || params.size() > 2)
467         throw runtime_error(
468             "setaccount <bitcoinaddress> <account>\n"
469             "Sets the account associated with the given address.");
470
471     CBitcoinAddress address(params[0].get_str());
472     if (!address.IsValid())
473         throw JSONRPCError(-5, "Invalid bitcoin address");
474
475
476     string strAccount;
477     if (params.size() > 1)
478         strAccount = AccountFromValue(params[1]);
479
480     // Detect when changing the account of an address that is the 'unused current key' of another account:
481     if (pwalletMain->mapAddressBook.count(address))
482     {
483         string strOldAccount = pwalletMain->mapAddressBook[address];
484         if (address == GetAccountAddress(strOldAccount))
485             GetAccountAddress(strOldAccount, true);
486     }
487
488     pwalletMain->SetAddressBookName(address, strAccount);
489
490     return Value::null;
491 }
492
493
494 Value getaccount(const Array& params, bool fHelp)
495 {
496     if (fHelp || params.size() != 1)
497         throw runtime_error(
498             "getaccount <bitcoinaddress>\n"
499             "Returns the account associated with the given address.");
500
501     CBitcoinAddress address(params[0].get_str());
502     if (!address.IsValid())
503         throw JSONRPCError(-5, "Invalid bitcoin address");
504
505     string strAccount;
506     map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
507     if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
508         strAccount = (*mi).second;
509     return strAccount;
510 }
511
512
513 Value getaddressesbyaccount(const Array& params, bool fHelp)
514 {
515     if (fHelp || params.size() != 1)
516         throw runtime_error(
517             "getaddressesbyaccount <account>\n"
518             "Returns the list of addresses for the given account.");
519
520     string strAccount = AccountFromValue(params[0]);
521
522     // Find all addresses that have the given account
523     Array ret;
524     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
525     {
526         const CBitcoinAddress& address = item.first;
527         const string& strName = item.second;
528         if (strName == strAccount)
529             ret.push_back(address.ToString());
530     }
531     return ret;
532 }
533
534 Value settxfee(const Array& params, bool fHelp)
535 {
536     if (fHelp || params.size() < 1 || params.size() > 1)
537         throw runtime_error(
538             "settxfee <amount>\n"
539             "<amount> is a real and is rounded to the nearest 0.00000001");
540
541     // Amount
542     int64 nAmount = 0;
543     if (params[0].get_real() != 0.0)
544         nAmount = AmountFromValue(params[0]);        // rejects 0.0 amounts
545
546     nTransactionFee = nAmount;
547     return true;
548 }
549
550 Value sendtoaddress(const Array& params, bool fHelp)
551 {
552     if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
553         throw runtime_error(
554             "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
555             "<amount> is a real and is rounded to the nearest 0.00000001\n"
556             "requires wallet passphrase to be set with walletpassphrase first");
557     if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
558         throw runtime_error(
559             "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
560             "<amount> is a real and is rounded to the nearest 0.00000001");
561
562     CBitcoinAddress address(params[0].get_str());
563     if (!address.IsValid())
564         throw JSONRPCError(-5, "Invalid bitcoin address");
565
566     // Amount
567     int64 nAmount = AmountFromValue(params[1]);
568
569     // Wallet comments
570     CWalletTx wtx;
571     if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty())
572         wtx.mapValue["comment"] = params[2].get_str();
573     if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
574         wtx.mapValue["to"]      = params[3].get_str();
575
576     if (pwalletMain->IsLocked())
577         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
578
579     string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
580     if (strError != "")
581         throw JSONRPCError(-4, strError);
582
583     return wtx.GetHash().GetHex();
584 }
585
586 Value signmessage(const Array& params, bool fHelp)
587 {
588     if (fHelp || params.size() != 2)
589         throw runtime_error(
590             "signmessage <bitcoinaddress> <message>\n"
591             "Sign a message with the private key of an address");
592
593     if (pwalletMain->IsLocked())
594         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
595
596     string strAddress = params[0].get_str();
597     string strMessage = params[1].get_str();
598
599     CBitcoinAddress addr(strAddress);
600     if (!addr.IsValid())
601         throw JSONRPCError(-3, "Invalid address");
602
603     CKey key;
604     if (!pwalletMain->GetKey(addr, key))
605         throw JSONRPCError(-4, "Private key not available");
606
607     CDataStream ss(SER_GETHASH);
608     ss << strMessageMagic;
609     ss << strMessage;
610
611     vector<unsigned char> vchSig;
612     if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig))
613         throw JSONRPCError(-5, "Sign failed");
614
615     return EncodeBase64(&vchSig[0], vchSig.size());
616 }
617
618 Value verifymessage(const Array& params, bool fHelp)
619 {
620     if (fHelp || params.size() != 3)
621         throw runtime_error(
622             "verifymessage <bitcoinaddress> <signature> <message>\n"
623             "Verify a signed message");
624
625     string strAddress  = params[0].get_str();
626     string strSign     = params[1].get_str();
627     string strMessage  = params[2].get_str();
628
629     CBitcoinAddress addr(strAddress);
630     if (!addr.IsValid())
631         throw JSONRPCError(-3, "Invalid address");
632
633     bool fInvalid = false;
634     vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
635
636     if (fInvalid)
637         throw JSONRPCError(-5, "Malformed base64 encoding");
638
639     CDataStream ss(SER_GETHASH);
640     ss << strMessageMagic;
641     ss << strMessage;
642
643     CKey key;
644     if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
645         return false;
646
647     return (CBitcoinAddress(key.GetPubKey()) == addr);
648 }
649
650
651 Value getreceivedbyaddress(const Array& params, bool fHelp)
652 {
653     if (fHelp || params.size() < 1 || params.size() > 2)
654         throw runtime_error(
655             "getreceivedbyaddress <bitcoinaddress> [minconf=1]\n"
656             "Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations.");
657
658     // Bitcoin address
659     CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
660     CScript scriptPubKey;
661     if (!address.IsValid())
662         throw JSONRPCError(-5, "Invalid bitcoin address");
663     scriptPubKey.SetBitcoinAddress(address);
664     if (!IsMine(*pwalletMain,scriptPubKey))
665         return (double)0.0;
666
667     // Minimum confirmations
668     int nMinDepth = 1;
669     if (params.size() > 1)
670         nMinDepth = params[1].get_int();
671
672     // Tally
673     int64 nAmount = 0;
674     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
675     {
676         const CWalletTx& wtx = (*it).second;
677         if (wtx.IsCoinBase() || !wtx.IsFinal())
678             continue;
679
680         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
681             if (txout.scriptPubKey == scriptPubKey)
682                 if (wtx.GetDepthInMainChain() >= nMinDepth)
683                     nAmount += txout.nValue;
684     }
685
686     return  ValueFromAmount(nAmount);
687 }
688
689
690 void GetAccountAddresses(string strAccount, set<CBitcoinAddress>& setAddress)
691 {
692     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
693     {
694         const CBitcoinAddress& address = item.first;
695         const string& strName = item.second;
696         if (strName == strAccount)
697             setAddress.insert(address);
698     }
699 }
700
701
702 Value getreceivedbyaccount(const Array& params, bool fHelp)
703 {
704     if (fHelp || params.size() < 1 || params.size() > 2)
705         throw runtime_error(
706             "getreceivedbyaccount <account> [minconf=1]\n"
707             "Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.");
708
709     // Minimum confirmations
710     int nMinDepth = 1;
711     if (params.size() > 1)
712         nMinDepth = params[1].get_int();
713
714     // Get the set of pub keys assigned to account
715     string strAccount = AccountFromValue(params[0]);
716     set<CBitcoinAddress> setAddress;
717     GetAccountAddresses(strAccount, setAddress);
718
719     // Tally
720     int64 nAmount = 0;
721     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
722     {
723         const CWalletTx& wtx = (*it).second;
724         if (wtx.IsCoinBase() || !wtx.IsFinal())
725             continue;
726
727         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
728         {
729             CBitcoinAddress address;
730             if (ExtractAddress(txout.scriptPubKey, address) && pwalletMain->HaveKey(address) && setAddress.count(address))
731                 if (wtx.GetDepthInMainChain() >= nMinDepth)
732                     nAmount += txout.nValue;
733         }
734     }
735
736     return (double)nAmount / (double)COIN;
737 }
738
739
740 int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
741 {
742     int64 nBalance = 0;
743
744     // Tally wallet transactions
745     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
746     {
747         const CWalletTx& wtx = (*it).second;
748         if (!wtx.IsFinal())
749             continue;
750
751         int64 nGenerated, nReceived, nSent, nFee;
752         wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee);
753
754         if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
755             nBalance += nReceived;
756         nBalance += nGenerated - nSent - nFee;
757     }
758
759     // Tally internal accounting entries
760     nBalance += walletdb.GetAccountCreditDebit(strAccount);
761
762     return nBalance;
763 }
764
765 int64 GetAccountBalance(const string& strAccount, int nMinDepth)
766 {
767     CWalletDB walletdb(pwalletMain->strWalletFile);
768     return GetAccountBalance(walletdb, strAccount, nMinDepth);
769 }
770
771
772 Value getbalance(const Array& params, bool fHelp)
773 {
774     if (fHelp || params.size() > 2)
775         throw runtime_error(
776             "getbalance [account] [minconf=1]\n"
777             "If [account] is not specified, returns the server's total available balance.\n"
778             "If [account] is specified, returns the balance in the account.");
779
780     if (params.size() == 0)
781         return  ValueFromAmount(pwalletMain->GetBalance());
782
783     int nMinDepth = 1;
784     if (params.size() > 1)
785         nMinDepth = params[1].get_int();
786
787     if (params[0].get_str() == "*") {
788         // Calculate total balance a different way from GetBalance()
789         // (GetBalance() sums up all unspent TxOuts)
790         // getbalance and getbalance '*' should always return the same number.
791         int64 nBalance = 0;
792         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
793         {
794             const CWalletTx& wtx = (*it).second;
795             if (!wtx.IsFinal())
796                 continue;
797
798             int64 allGeneratedImmature, allGeneratedMature, allFee;
799             allGeneratedImmature = allGeneratedMature = allFee = 0;
800             string strSentAccount;
801             list<pair<CBitcoinAddress, int64> > listReceived;
802             list<pair<CBitcoinAddress, int64> > listSent;
803             wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
804             if (wtx.GetDepthInMainChain() >= nMinDepth)
805             {
806                 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
807                     nBalance += r.second;
808             }
809             BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent)
810                 nBalance -= r.second;
811             nBalance -= allFee;
812             nBalance += allGeneratedMature;
813         }
814         return  ValueFromAmount(nBalance);
815     }
816
817     string strAccount = AccountFromValue(params[0]);
818
819     int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
820
821     return ValueFromAmount(nBalance);
822 }
823
824
825 Value movecmd(const Array& params, bool fHelp)
826 {
827     if (fHelp || params.size() < 3 || params.size() > 5)
828         throw runtime_error(
829             "move <fromaccount> <toaccount> <amount> [minconf=1] [comment]\n"
830             "Move from one account in your wallet to another.");
831
832     string strFrom = AccountFromValue(params[0]);
833     string strTo = AccountFromValue(params[1]);
834     int64 nAmount = AmountFromValue(params[2]);
835     if (params.size() > 3)
836         // unused parameter, used to be nMinDepth, keep type-checking it though
837         (void)params[3].get_int();
838     string strComment;
839     if (params.size() > 4)
840         strComment = params[4].get_str();
841
842     CWalletDB walletdb(pwalletMain->strWalletFile);
843     walletdb.TxnBegin();
844
845     int64 nNow = GetAdjustedTime();
846
847     // Debit
848     CAccountingEntry debit;
849     debit.strAccount = strFrom;
850     debit.nCreditDebit = -nAmount;
851     debit.nTime = nNow;
852     debit.strOtherAccount = strTo;
853     debit.strComment = strComment;
854     walletdb.WriteAccountingEntry(debit);
855
856     // Credit
857     CAccountingEntry credit;
858     credit.strAccount = strTo;
859     credit.nCreditDebit = nAmount;
860     credit.nTime = nNow;
861     credit.strOtherAccount = strFrom;
862     credit.strComment = strComment;
863     walletdb.WriteAccountingEntry(credit);
864
865     walletdb.TxnCommit();
866
867     return true;
868 }
869
870
871 Value sendfrom(const Array& params, bool fHelp)
872 {
873     if (pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6))
874         throw runtime_error(
875             "sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
876             "<amount> is a real and is rounded to the nearest 0.00000001\n"
877             "requires wallet passphrase to be set with walletpassphrase first");
878     if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6))
879         throw runtime_error(
880             "sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
881             "<amount> is a real and is rounded to the nearest 0.00000001");
882
883     string strAccount = AccountFromValue(params[0]);
884     CBitcoinAddress address(params[1].get_str());
885     if (!address.IsValid())
886         throw JSONRPCError(-5, "Invalid bitcoin address");
887     int64 nAmount = AmountFromValue(params[2]);
888     int nMinDepth = 1;
889     if (params.size() > 3)
890         nMinDepth = params[3].get_int();
891
892     CWalletTx wtx;
893     wtx.strFromAccount = strAccount;
894     if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty())
895         wtx.mapValue["comment"] = params[4].get_str();
896     if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty())
897         wtx.mapValue["to"]      = params[5].get_str();
898
899     if (pwalletMain->IsLocked())
900         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
901
902     // Check funds
903     int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
904     if (nAmount > nBalance)
905         throw JSONRPCError(-6, "Account has insufficient funds");
906
907     // Send
908     string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
909     if (strError != "")
910         throw JSONRPCError(-4, strError);
911
912     return wtx.GetHash().GetHex();
913 }
914
915
916 Value sendmany(const Array& params, bool fHelp)
917 {
918     if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
919         throw runtime_error(
920             "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
921             "amounts are double-precision floating point numbers\n"
922             "requires wallet passphrase to be set with walletpassphrase first");
923     if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
924         throw runtime_error(
925             "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
926             "amounts are double-precision floating point numbers");
927
928     string strAccount = AccountFromValue(params[0]);
929     Object sendTo = params[1].get_obj();
930     int nMinDepth = 1;
931     if (params.size() > 2)
932         nMinDepth = params[2].get_int();
933
934     CWalletTx wtx;
935     wtx.strFromAccount = strAccount;
936     if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
937         wtx.mapValue["comment"] = params[3].get_str();
938
939     set<CBitcoinAddress> setAddress;
940     vector<pair<CScript, int64> > vecSend;
941
942     int64 totalAmount = 0;
943     BOOST_FOREACH(const Pair& s, sendTo)
944     {
945         CBitcoinAddress address(s.name_);
946         if (!address.IsValid())
947             throw JSONRPCError(-5, string("Invalid bitcoin address:")+s.name_);
948
949         if (setAddress.count(address))
950             throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_);
951         setAddress.insert(address);
952
953         CScript scriptPubKey;
954         scriptPubKey.SetBitcoinAddress(address);
955         int64 nAmount = AmountFromValue(s.value_); 
956         totalAmount += nAmount;
957
958         vecSend.push_back(make_pair(scriptPubKey, nAmount));
959     }
960
961     if (pwalletMain->IsLocked())
962         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
963
964     // Check funds
965     int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
966     if (totalAmount > nBalance)
967         throw JSONRPCError(-6, "Account has insufficient funds");
968
969     // Send
970     CReserveKey keyChange(pwalletMain);
971     int64 nFeeRequired = 0;
972     bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
973     if (!fCreated)
974     {
975         if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
976             throw JSONRPCError(-6, "Insufficient funds");
977         throw JSONRPCError(-4, "Transaction creation failed");
978     }
979     if (!pwalletMain->CommitTransaction(wtx, keyChange))
980         throw JSONRPCError(-4, "Transaction commit failed");
981
982     return wtx.GetHash().GetHex();
983 }
984
985 Value addmultisigaddress(const Array& params, bool fHelp)
986 {
987     if (fHelp || params.size() < 2 || params.size() > 3)
988     {
989         string msg = "addmultisigaddress <nrequired> <'[\"key\",\"key\"]'> [account]\n"
990             "Add a nrequired-to-sign multisignature address to the wallet\"\n"
991             "each key is a bitcoin address or hex-encoded public key\n"
992             "If [account] is specified, assign address to [account].";
993         throw runtime_error(msg);
994     }
995     if (!fTestNet)
996         throw runtime_error("addmultisigaddress available only when running -testnet\n");
997
998     int nRequired = params[0].get_int();
999     const Array& keys = params[1].get_array();
1000     string strAccount;
1001     if (params.size() > 2)
1002         strAccount = AccountFromValue(params[2]);
1003
1004     // Gather public keys
1005     if (nRequired < 1 || keys.size() < nRequired)
1006         throw runtime_error(
1007             strprintf("wrong number of keys"
1008                       "(got %d, need at least %d)", keys.size(), nRequired));
1009     std::vector<CKey> pubkeys;
1010     pubkeys.resize(keys.size());
1011     for (unsigned int i = 0; i < keys.size(); i++)
1012     {
1013         const std::string& ks = keys[i].get_str();
1014
1015         // Case 1: bitcoin address and we have full public key:
1016         CBitcoinAddress address(ks);
1017         if (address.IsValid())
1018         {
1019             if (address.IsScript())
1020                 throw runtime_error(
1021                     strprintf("%s is a pay-to-script address",ks.c_str()));
1022             std::vector<unsigned char> vchPubKey;
1023             if (!pwalletMain->GetPubKey(address, vchPubKey))
1024                 throw runtime_error(
1025                     strprintf("no full public key for address %s",ks.c_str()));
1026             if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey))
1027                 throw runtime_error(" Invalid public key: "+ks);
1028         }
1029
1030         // Case 2: hex public key
1031         else if (IsHex(ks))
1032         {
1033             vector<unsigned char> vchPubKey = ParseHex(ks);
1034             if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey))
1035                 throw runtime_error(" Invalid public key: "+ks);
1036         }
1037         else
1038         {
1039             throw runtime_error(" Invalid public key: "+ks);
1040         }
1041     }
1042
1043     // Construct using pay-to-script-hash:
1044     CScript inner;
1045     inner.SetMultisig(nRequired, pubkeys);
1046
1047     uint160 scriptHash = Hash160(inner);
1048     CScript scriptPubKey;
1049     scriptPubKey.SetPayToScriptHash(inner);
1050     pwalletMain->AddCScript(inner);
1051     CBitcoinAddress address;
1052     address.SetScriptHash160(scriptHash);
1053
1054     pwalletMain->SetAddressBookName(address, strAccount);
1055     return address.ToString();
1056 }
1057
1058
1059 struct tallyitem
1060 {
1061     int64 nAmount;
1062     int nConf;
1063     tallyitem()
1064     {
1065         nAmount = 0;
1066         nConf = std::numeric_limits<int>::max();
1067     }
1068 };
1069
1070 Value ListReceived(const Array& params, bool fByAccounts)
1071 {
1072     // Minimum confirmations
1073     int nMinDepth = 1;
1074     if (params.size() > 0)
1075         nMinDepth = params[0].get_int();
1076
1077     // Whether to include empty accounts
1078     bool fIncludeEmpty = false;
1079     if (params.size() > 1)
1080         fIncludeEmpty = params[1].get_bool();
1081
1082     // Tally
1083     map<CBitcoinAddress, tallyitem> mapTally;
1084     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1085     {
1086         const CWalletTx& wtx = (*it).second;
1087
1088         if (wtx.IsCoinBase() || !wtx.IsFinal())
1089             continue;
1090
1091         int nDepth = wtx.GetDepthInMainChain();
1092         if (nDepth < nMinDepth)
1093             continue;
1094
1095         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
1096         {
1097             CBitcoinAddress address;
1098             if (!ExtractAddress(txout.scriptPubKey, address) || !pwalletMain->HaveKey(address) || !address.IsValid())
1099                 continue;
1100
1101             tallyitem& item = mapTally[address];
1102             item.nAmount += txout.nValue;
1103             item.nConf = min(item.nConf, nDepth);
1104         }
1105     }
1106
1107     // Reply
1108     Array ret;
1109     map<string, tallyitem> mapAccountTally;
1110     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
1111     {
1112         const CBitcoinAddress& address = item.first;
1113         const string& strAccount = item.second;
1114         map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
1115         if (it == mapTally.end() && !fIncludeEmpty)
1116             continue;
1117
1118         int64 nAmount = 0;
1119         int nConf = std::numeric_limits<int>::max();
1120         if (it != mapTally.end())
1121         {
1122             nAmount = (*it).second.nAmount;
1123             nConf = (*it).second.nConf;
1124         }
1125
1126         if (fByAccounts)
1127         {
1128             tallyitem& item = mapAccountTally[strAccount];
1129             item.nAmount += nAmount;
1130             item.nConf = min(item.nConf, nConf);
1131         }
1132         else
1133         {
1134             Object obj;
1135             obj.push_back(Pair("address",       address.ToString()));
1136             obj.push_back(Pair("account",       strAccount));
1137             obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
1138             obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1139             ret.push_back(obj);
1140         }
1141     }
1142
1143     if (fByAccounts)
1144     {
1145         for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
1146         {
1147             int64 nAmount = (*it).second.nAmount;
1148             int nConf = (*it).second.nConf;
1149             Object obj;
1150             obj.push_back(Pair("account",       (*it).first));
1151             obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
1152             obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1153             ret.push_back(obj);
1154         }
1155     }
1156
1157     return ret;
1158 }
1159
1160 Value listreceivedbyaddress(const Array& params, bool fHelp)
1161 {
1162     if (fHelp || params.size() > 2)
1163         throw runtime_error(
1164             "listreceivedbyaddress [minconf=1] [includeempty=false]\n"
1165             "[minconf] is the minimum number of confirmations before payments are included.\n"
1166             "[includeempty] whether to include addresses that haven't received any payments.\n"
1167             "Returns an array of objects containing:\n"
1168             "  \"address\" : receiving address\n"
1169             "  \"account\" : the account of the receiving address\n"
1170             "  \"amount\" : total amount received by the address\n"
1171             "  \"confirmations\" : number of confirmations of the most recent transaction included");
1172
1173     return ListReceived(params, false);
1174 }
1175
1176 Value listreceivedbyaccount(const Array& params, bool fHelp)
1177 {
1178     if (fHelp || params.size() > 2)
1179         throw runtime_error(
1180             "listreceivedbyaccount [minconf=1] [includeempty=false]\n"
1181             "[minconf] is the minimum number of confirmations before payments are included.\n"
1182             "[includeempty] whether to include accounts that haven't received any payments.\n"
1183             "Returns an array of objects containing:\n"
1184             "  \"account\" : the account of the receiving addresses\n"
1185             "  \"amount\" : total amount received by addresses with this account\n"
1186             "  \"confirmations\" : number of confirmations of the most recent transaction included");
1187
1188     return ListReceived(params, true);
1189 }
1190
1191 void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
1192 {
1193     int64 nGeneratedImmature, nGeneratedMature, nFee;
1194     string strSentAccount;
1195     list<pair<CBitcoinAddress, int64> > listReceived;
1196     list<pair<CBitcoinAddress, int64> > listSent;
1197
1198     wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
1199
1200     bool fAllAccounts = (strAccount == string("*"));
1201
1202     // Generated blocks assigned to account ""
1203     if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount == ""))
1204     {
1205         Object entry;
1206         entry.push_back(Pair("account", string("")));
1207         if (nGeneratedImmature)
1208         {
1209             entry.push_back(Pair("category", wtx.GetDepthInMainChain() ? "immature" : "orphan"));
1210             entry.push_back(Pair("amount", ValueFromAmount(nGeneratedImmature)));
1211         }
1212         else
1213         {
1214             entry.push_back(Pair("category", "generate"));
1215             entry.push_back(Pair("amount", ValueFromAmount(nGeneratedMature)));
1216         }
1217         if (fLong)
1218             WalletTxToJSON(wtx, entry);
1219         ret.push_back(entry);
1220     }
1221
1222     // Sent
1223     if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1224     {
1225         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
1226         {
1227             Object entry;
1228             entry.push_back(Pair("account", strSentAccount));
1229             entry.push_back(Pair("address", s.first.ToString()));
1230             entry.push_back(Pair("category", "send"));
1231             entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
1232             entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1233             if (fLong)
1234                 WalletTxToJSON(wtx, entry);
1235             ret.push_back(entry);
1236         }
1237     }
1238
1239     // Received
1240     if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1241     {
1242         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
1243         {
1244             string account;
1245             if (pwalletMain->mapAddressBook.count(r.first))
1246                 account = pwalletMain->mapAddressBook[r.first];
1247             if (fAllAccounts || (account == strAccount))
1248             {
1249                 Object entry;
1250                 entry.push_back(Pair("account", account));
1251                 entry.push_back(Pair("address", r.first.ToString()));
1252                 entry.push_back(Pair("category", "receive"));
1253                 entry.push_back(Pair("amount", ValueFromAmount(r.second)));
1254                 if (fLong)
1255                     WalletTxToJSON(wtx, entry);
1256                 ret.push_back(entry);
1257             }
1258         }
1259     }
1260 }
1261
1262 void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret)
1263 {
1264     bool fAllAccounts = (strAccount == string("*"));
1265
1266     if (fAllAccounts || acentry.strAccount == strAccount)
1267     {
1268         Object entry;
1269         entry.push_back(Pair("account", acentry.strAccount));
1270         entry.push_back(Pair("category", "move"));
1271         entry.push_back(Pair("time", (boost::int64_t)acentry.nTime));
1272         entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1273         entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1274         entry.push_back(Pair("comment", acentry.strComment));
1275         ret.push_back(entry);
1276     }
1277 }
1278
1279 Value listtransactions(const Array& params, bool fHelp)
1280 {
1281     if (fHelp || params.size() > 3)
1282         throw runtime_error(
1283             "listtransactions [account] [count=10] [from=0]\n"
1284             "Returns up to [count] most recent transactions skipping the first [from] transactions for account [account].");
1285
1286     string strAccount = "*";
1287     if (params.size() > 0)
1288         strAccount = params[0].get_str();
1289     int nCount = 10;
1290     if (params.size() > 1)
1291         nCount = params[1].get_int();
1292     int nFrom = 0;
1293     if (params.size() > 2)
1294         nFrom = params[2].get_int();
1295
1296     if (nCount < 0)
1297         throw JSONRPCError(-8, "Negative count");
1298     if (nFrom < 0)
1299         throw JSONRPCError(-8, "Negative from");
1300
1301     Array ret;
1302     CWalletDB walletdb(pwalletMain->strWalletFile);
1303
1304     // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap.
1305     typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
1306     typedef multimap<int64, TxPair > TxItems;
1307     TxItems txByTime;
1308
1309     // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
1310     // would make this much faster for applications that do this a lot.
1311     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1312     {
1313         CWalletTx* wtx = &((*it).second);
1314         txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
1315     }
1316     list<CAccountingEntry> acentries;
1317     walletdb.ListAccountCreditDebit(strAccount, acentries);
1318     BOOST_FOREACH(CAccountingEntry& entry, acentries)
1319     {
1320         txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry)));
1321     }
1322
1323     // iterate backwards until we have nCount items to return:
1324     for (TxItems::reverse_iterator it = txByTime.rbegin(); it != txByTime.rend(); ++it)
1325     {
1326         CWalletTx *const pwtx = (*it).second.first;
1327         if (pwtx != 0)
1328             ListTransactions(*pwtx, strAccount, 0, true, ret);
1329         CAccountingEntry *const pacentry = (*it).second.second;
1330         if (pacentry != 0)
1331             AcentryToJSON(*pacentry, strAccount, ret);
1332
1333         if (ret.size() >= (nCount+nFrom)) break;
1334     }
1335     // ret is newest to oldest
1336     
1337     if (nFrom > ret.size()) nFrom = ret.size();
1338     if (nFrom+nCount > ret.size()) nCount = ret.size()-nFrom;
1339     Array::iterator first = ret.begin();
1340     std::advance(first, nFrom);
1341     Array::iterator last = ret.begin();
1342     std::advance(last, nFrom+nCount);
1343
1344     if (last != ret.end()) ret.erase(last, ret.end());
1345     if (first != ret.begin()) ret.erase(ret.begin(), first);
1346
1347     std::reverse(ret.begin(), ret.end()); // Return oldest to newest
1348
1349     return ret;
1350 }
1351
1352 Value listaccounts(const Array& params, bool fHelp)
1353 {
1354     if (fHelp || params.size() > 1)
1355         throw runtime_error(
1356             "listaccounts [minconf=1]\n"
1357             "Returns Object that has account names as keys, account balances as values.");
1358
1359     int nMinDepth = 1;
1360     if (params.size() > 0)
1361         nMinDepth = params[0].get_int();
1362
1363     map<string, int64> mapAccountBalances;
1364     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
1365         if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
1366             mapAccountBalances[entry.second] = 0;
1367     }
1368
1369     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1370     {
1371         const CWalletTx& wtx = (*it).second;
1372         int64 nGeneratedImmature, nGeneratedMature, nFee;
1373         string strSentAccount;
1374         list<pair<CBitcoinAddress, int64> > listReceived;
1375         list<pair<CBitcoinAddress, int64> > listSent;
1376         wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
1377         mapAccountBalances[strSentAccount] -= nFee;
1378         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
1379             mapAccountBalances[strSentAccount] -= s.second;
1380         if (wtx.GetDepthInMainChain() >= nMinDepth)
1381         {
1382             mapAccountBalances[""] += nGeneratedMature;
1383             BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
1384                 if (pwalletMain->mapAddressBook.count(r.first))
1385                     mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
1386                 else
1387                     mapAccountBalances[""] += r.second;
1388         }
1389     }
1390
1391     list<CAccountingEntry> acentries;
1392     CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries);
1393     BOOST_FOREACH(const CAccountingEntry& entry, acentries)
1394         mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1395
1396     Object ret;
1397     BOOST_FOREACH(const PAIRTYPE(string, int64)& accountBalance, mapAccountBalances) {
1398         ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1399     }
1400     return ret;
1401 }
1402
1403 Value listsinceblock(const Array& params, bool fHelp)
1404 {
1405     if (fHelp)
1406         throw runtime_error(
1407             "listsinceblock [blockid] [target-confirmations]\n"
1408             "Get all transactions in blocks since block [blockid], or all transactions if omitted");
1409
1410     CBlockIndex *pindex = NULL;
1411     int target_confirms = 1;
1412
1413     if (params.size() > 0)
1414     {
1415         uint256 blockId = 0;
1416
1417         blockId.SetHex(params[0].get_str());
1418         pindex = CBlockLocator(blockId).GetBlockIndex();
1419     }
1420
1421     if (params.size() > 1)
1422     {
1423         target_confirms = params[1].get_int();
1424
1425         if (target_confirms < 1)
1426             throw JSONRPCError(-8, "Invalid parameter");
1427     }
1428
1429     int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1;
1430
1431     Array transactions;
1432
1433     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++)
1434     {
1435         CWalletTx tx = (*it).second;
1436
1437         if (depth == -1 || tx.GetDepthInMainChain() < depth)
1438             ListTransactions(tx, "*", 0, true, transactions);
1439     }
1440
1441     uint256 lastblock;
1442
1443     if (target_confirms == 1)
1444     {
1445         printf("oops!\n");
1446         lastblock = hashBestChain;
1447     }
1448     else
1449     {
1450         int target_height = pindexBest->nHeight + 1 - target_confirms;
1451
1452         CBlockIndex *block;
1453         for (block = pindexBest;
1454              block && block->nHeight > target_height;
1455              block = block->pprev)  { }
1456
1457         lastblock = block ? block->GetBlockHash() : 0;
1458     }
1459
1460     Object ret;
1461     ret.push_back(Pair("transactions", transactions));
1462     ret.push_back(Pair("lastblock", lastblock.GetHex()));
1463
1464     return ret;
1465 }
1466
1467 Value gettransaction(const Array& params, bool fHelp)
1468 {
1469     if (fHelp || params.size() != 1)
1470         throw runtime_error(
1471             "gettransaction <txid>\n"
1472             "Get detailed information about <txid>");
1473
1474     uint256 hash;
1475     hash.SetHex(params[0].get_str());
1476
1477     Object entry;
1478
1479     if (!pwalletMain->mapWallet.count(hash))
1480         throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
1481     const CWalletTx& wtx = pwalletMain->mapWallet[hash];
1482
1483     int64 nCredit = wtx.GetCredit();
1484     int64 nDebit = wtx.GetDebit();
1485     int64 nNet = nCredit - nDebit;
1486     int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
1487
1488     entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
1489     if (wtx.IsFromMe())
1490         entry.push_back(Pair("fee", ValueFromAmount(nFee)));
1491
1492     WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
1493
1494     Array details;
1495     ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
1496     entry.push_back(Pair("details", details));
1497
1498     return entry;
1499 }
1500
1501
1502 Value backupwallet(const Array& params, bool fHelp)
1503 {
1504     if (fHelp || params.size() != 1)
1505         throw runtime_error(
1506             "backupwallet <destination>\n"
1507             "Safely copies wallet.dat to destination, which can be a directory or a path with filename.");
1508
1509     string strDest = params[0].get_str();
1510     BackupWallet(*pwalletMain, strDest);
1511
1512     return Value::null;
1513 }
1514
1515
1516 Value keypoolrefill(const Array& params, bool fHelp)
1517 {
1518     if (pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
1519         throw runtime_error(
1520             "keypoolrefill\n"
1521             "Fills the keypool, requires wallet passphrase to be set.");
1522     if (!pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
1523         throw runtime_error(
1524             "keypoolrefill\n"
1525             "Fills the keypool.");
1526
1527     if (pwalletMain->IsLocked())
1528         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
1529
1530     pwalletMain->TopUpKeyPool();
1531
1532     if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100))
1533         throw JSONRPCError(-4, "Error refreshing keypool.");
1534
1535     return Value::null;
1536 }
1537
1538
1539 void ThreadTopUpKeyPool(void* parg)
1540 {
1541     pwalletMain->TopUpKeyPool();
1542 }
1543
1544 void ThreadCleanWalletPassphrase(void* parg)
1545 {
1546     int64 nMyWakeTime = GetTimeMillis() + *((int64*)parg) * 1000;
1547
1548     ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
1549
1550     if (nWalletUnlockTime == 0)
1551     {
1552         nWalletUnlockTime = nMyWakeTime;
1553
1554         do
1555         {
1556             if (nWalletUnlockTime==0)
1557                 break;
1558             int64 nToSleep = nWalletUnlockTime - GetTimeMillis();
1559             if (nToSleep <= 0)
1560                 break;
1561
1562             LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
1563             Sleep(nToSleep);
1564             ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
1565
1566         } while(1);
1567
1568         if (nWalletUnlockTime)
1569         {
1570             nWalletUnlockTime = 0;
1571             pwalletMain->Lock();
1572         }
1573     }
1574     else
1575     {
1576         if (nWalletUnlockTime < nMyWakeTime)
1577             nWalletUnlockTime = nMyWakeTime;
1578     }
1579
1580     LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
1581
1582     delete (int64*)parg;
1583 }
1584
1585 Value walletpassphrase(const Array& params, bool fHelp)
1586 {
1587     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1588         throw runtime_error(
1589             "walletpassphrase <passphrase> <timeout>\n"
1590             "Stores the wallet decryption key in memory for <timeout> seconds.");
1591     if (fHelp)
1592         return true;
1593     if (!pwalletMain->IsCrypted())
1594         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
1595
1596     if (!pwalletMain->IsLocked())
1597         throw JSONRPCError(-17, "Error: Wallet is already unlocked.");
1598
1599     // Note that the walletpassphrase is stored in params[0] which is not mlock()ed
1600     SecureString strWalletPass;
1601     strWalletPass.reserve(100);
1602     // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1603     // Alternately, find a way to make params[0] mlock()'d to begin with.
1604     strWalletPass = params[0].get_str().c_str();
1605
1606     if (strWalletPass.length() > 0)
1607     {
1608         if (!pwalletMain->Unlock(strWalletPass))
1609             throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
1610     }
1611     else
1612         throw runtime_error(
1613             "walletpassphrase <passphrase> <timeout>\n"
1614             "Stores the wallet decryption key in memory for <timeout> seconds.");
1615
1616     CreateThread(ThreadTopUpKeyPool, NULL);
1617     int64* pnSleepTime = new int64(params[1].get_int64());
1618     CreateThread(ThreadCleanWalletPassphrase, pnSleepTime);
1619
1620     return Value::null;
1621 }
1622
1623
1624 Value walletpassphrasechange(const Array& params, bool fHelp)
1625 {
1626     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1627         throw runtime_error(
1628             "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1629             "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1630     if (fHelp)
1631         return true;
1632     if (!pwalletMain->IsCrypted())
1633         throw JSONRPCError(-15, "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(-14, "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             "Removes 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.");
1665     if (fHelp)
1666         return true;
1667     if (!pwalletMain->IsCrypted())
1668         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
1669
1670     CRITICAL_BLOCK(cs_nWalletUnlockTime)
1671     {
1672         pwalletMain->Lock();
1673         nWalletUnlockTime = 0;
1674     }
1675
1676     return Value::null;
1677 }
1678
1679
1680 Value encryptwallet(const Array& params, bool fHelp)
1681 {
1682     if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
1683         throw runtime_error(
1684             "encryptwallet <passphrase>\n"
1685             "Encrypts the wallet with <passphrase>.");
1686     if (fHelp)
1687         return true;
1688     if (pwalletMain->IsCrypted())
1689         throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called.");
1690
1691 #ifdef QT_GUI
1692     // shutting down via RPC while the GUI is running does not work (yet):
1693     throw runtime_error("Not Yet Implemented: use GUI to encrypt wallet, not RPC command");
1694 #endif
1695
1696     // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1697     // Alternately, find a way to make params[0] mlock()'d to begin with.
1698     SecureString strWalletPass;
1699     strWalletPass.reserve(100);
1700     strWalletPass = params[0].get_str().c_str();
1701
1702     if (strWalletPass.length() < 1)
1703         throw runtime_error(
1704             "encryptwallet <passphrase>\n"
1705             "Encrypts the wallet with <passphrase>.");
1706
1707     if (!pwalletMain->EncryptWallet(strWalletPass))
1708         throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
1709
1710     // BDB seems to have a bad habit of writing old data into
1711     // slack space in .dat files; that is bad if the old data is
1712     // unencrypted private keys.  So:
1713     CreateThread(Shutdown, NULL);
1714     return "wallet encrypted; bitcoin server stopping, restart to run with encrypted wallet";
1715 }
1716
1717
1718 Value validateaddress(const Array& params, bool fHelp)
1719 {
1720     if (fHelp || params.size() != 1)
1721         throw runtime_error(
1722             "validateaddress <bitcoinaddress>\n"
1723             "Return information about <bitcoinaddress>.");
1724
1725     CBitcoinAddress address(params[0].get_str());
1726     bool isValid = address.IsValid();
1727
1728     Object ret;
1729     ret.push_back(Pair("isvalid", isValid));
1730     if (isValid)
1731     {
1732         // Call Hash160ToAddress() so we always return current ADDRESSVERSION
1733         // version of the address:
1734         string currentAddress = address.ToString();
1735         ret.push_back(Pair("address", currentAddress));
1736         if (pwalletMain->HaveKey(address))
1737         {
1738             ret.push_back(Pair("ismine", true));
1739             std::vector<unsigned char> vchPubKey;
1740             pwalletMain->GetPubKey(address, vchPubKey);
1741             ret.push_back(Pair("pubkey", HexStr(vchPubKey)));
1742             CKey key;
1743             key.SetPubKey(vchPubKey);
1744             ret.push_back(Pair("iscompressed", key.IsCompressed()));
1745         }
1746         else if (pwalletMain->HaveCScript(address.GetHash160()))
1747         {
1748             ret.push_back(Pair("isscript", true));
1749             CScript subscript;
1750             pwalletMain->GetCScript(address.GetHash160(), subscript);
1751             ret.push_back(Pair("ismine", ::IsMine(*pwalletMain, subscript)));
1752             std::vector<CBitcoinAddress> addresses;
1753             txnouttype whichType;
1754             int nRequired;
1755             ExtractAddresses(subscript, whichType, addresses, nRequired);
1756             ret.push_back(Pair("script", GetTxnOutputType(whichType)));
1757             Array a;
1758             BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
1759                 a.push_back(addr.ToString());
1760             ret.push_back(Pair("addresses", a));
1761             if (whichType == TX_MULTISIG)
1762                 ret.push_back(Pair("sigsrequired", nRequired));
1763         }
1764         else
1765             ret.push_back(Pair("ismine", false));
1766         if (pwalletMain->mapAddressBook.count(address))
1767             ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
1768     }
1769     return ret;
1770 }
1771
1772 Value getwork(const Array& params, bool fHelp)
1773 {
1774     if (fHelp || params.size() > 1)
1775         throw runtime_error(
1776             "getwork [data]\n"
1777             "If [data] is not specified, returns formatted hash data to work on:\n"
1778             "  \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
1779             "  \"data\" : block data\n"
1780             "  \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
1781             "  \"target\" : little endian hash target\n"
1782             "If [data] is specified, tries to solve the block and returns true if it was successful.");
1783
1784     if (vNodes.empty())
1785         throw JSONRPCError(-9, "Bitcoin is not connected!");
1786
1787     if (IsInitialBlockDownload())
1788         throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
1789
1790     typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
1791     static mapNewBlock_t mapNewBlock;
1792     static vector<CBlock*> vNewBlock;
1793     static CReserveKey reservekey(pwalletMain);
1794
1795     if (params.size() == 0)
1796     {
1797         // Update block
1798         static unsigned int nTransactionsUpdatedLast;
1799         static CBlockIndex* pindexPrev;
1800         static int64 nStart;
1801         static CBlock* pblock;
1802         if (pindexPrev != pindexBest ||
1803             (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
1804         {
1805             if (pindexPrev != pindexBest)
1806             {
1807                 // Deallocate old blocks since they're obsolete now
1808                 mapNewBlock.clear();
1809                 BOOST_FOREACH(CBlock* pblock, vNewBlock)
1810                     delete pblock;
1811                 vNewBlock.clear();
1812             }
1813             nTransactionsUpdatedLast = nTransactionsUpdated;
1814             pindexPrev = pindexBest;
1815             nStart = GetTime();
1816
1817             // Create new block
1818             pblock = CreateNewBlock(reservekey);
1819             if (!pblock)
1820                 throw JSONRPCError(-7, "Out of memory");
1821             vNewBlock.push_back(pblock);
1822         }
1823
1824         // Update nTime
1825         pblock->UpdateTime(pindexPrev);
1826         pblock->nNonce = 0;
1827
1828         // Update nExtraNonce
1829         static unsigned int nExtraNonce = 0;
1830         IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
1831
1832         // Save
1833         mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
1834
1835         // Prebuild hash buffers
1836         char pmidstate[32];
1837         char pdata[128];
1838         char phash1[64];
1839         FormatHashBuffers(pblock, pmidstate, pdata, phash1);
1840
1841         uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
1842
1843         Object result;
1844         result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
1845         result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
1846         result.push_back(Pair("hash1",    HexStr(BEGIN(phash1), END(phash1)))); // deprecated
1847         result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));
1848         return result;
1849     }
1850     else
1851     {
1852         // Parse parameters
1853         vector<unsigned char> vchData = ParseHex(params[0].get_str());
1854         if (vchData.size() != 128)
1855             throw JSONRPCError(-8, "Invalid parameter");
1856         CBlock* pdata = (CBlock*)&vchData[0];
1857
1858         // Byte reverse
1859         for (int i = 0; i < 128/4; i++)
1860             ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
1861
1862         // Get saved block
1863         if (!mapNewBlock.count(pdata->hashMerkleRoot))
1864             return false;
1865         CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
1866
1867         pblock->nTime = pdata->nTime;
1868         pblock->nNonce = pdata->nNonce;
1869         pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
1870         pblock->hashMerkleRoot = pblock->BuildMerkleTree();
1871
1872         return CheckWork(pblock, *pwalletMain, reservekey);
1873     }
1874 }
1875
1876
1877 Value getmemorypool(const Array& params, bool fHelp)
1878 {
1879     if (fHelp || params.size() > 1)
1880         throw runtime_error(
1881             "getmemorypool [data]\n"
1882             "If [data] is not specified, returns data needed to construct a block to work on:\n"
1883             "  \"version\" : block version\n"
1884             "  \"previousblockhash\" : hash of current highest block\n"
1885             "  \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n"
1886             "  \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n"
1887             "  \"coinbaseflags\" : data that should be included in coinbase so support for new features can be judged\n"
1888             "  \"time\" : timestamp appropriate for next block\n"
1889             "  \"mintime\" : minimum timestamp appropriate for next block\n"
1890             "  \"curtime\" : current timestamp\n"
1891             "  \"bits\" : compressed target of next block\n"
1892             "If [data] is specified, tries to solve the block and returns true if it was successful.");
1893
1894     if (params.size() == 0)
1895     {
1896         if (vNodes.empty())
1897             throw JSONRPCError(-9, "Bitcoin is not connected!");
1898
1899         if (IsInitialBlockDownload())
1900             throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
1901
1902         static CReserveKey reservekey(pwalletMain);
1903
1904         // Update block
1905         static unsigned int nTransactionsUpdatedLast;
1906         static CBlockIndex* pindexPrev;
1907         static int64 nStart;
1908         static CBlock* pblock;
1909         if (pindexPrev != pindexBest ||
1910             (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5))
1911         {
1912             nTransactionsUpdatedLast = nTransactionsUpdated;
1913             pindexPrev = pindexBest;
1914             nStart = GetTime();
1915
1916             // Create new block
1917             if(pblock)
1918                 delete pblock;
1919             pblock = CreateNewBlock(reservekey);
1920             if (!pblock)
1921                 throw JSONRPCError(-7, "Out of memory");
1922         }
1923
1924         // Update nTime
1925         pblock->UpdateTime(pindexPrev);
1926         pblock->nNonce = 0;
1927
1928         Array transactions;
1929         BOOST_FOREACH(CTransaction tx, pblock->vtx) {
1930             if(tx.IsCoinBase())
1931                 continue;
1932
1933             CDataStream ssTx;
1934             ssTx << tx;
1935
1936             transactions.push_back(HexStr(ssTx.begin(), ssTx.end()));
1937         }
1938
1939         Object result;
1940         result.push_back(Pair("version", pblock->nVersion));
1941         result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
1942         result.push_back(Pair("transactions", transactions));
1943         result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
1944         result.push_back(Pair("coinbaseflags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
1945         result.push_back(Pair("time", (int64_t)pblock->nTime));
1946         result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
1947         result.push_back(Pair("curtime", (int64_t)GetAdjustedTime()));
1948         result.push_back(Pair("bits", HexBits(pblock->nBits)));
1949
1950         return result;
1951     }
1952     else
1953     {
1954         // Parse parameters
1955         CDataStream ssBlock(ParseHex(params[0].get_str()));
1956         CBlock pblock;
1957         ssBlock >> pblock;
1958
1959         return ProcessBlock(NULL, &pblock);
1960     }
1961 }
1962
1963 Value getblockhash(const Array& params, bool fHelp)
1964 {
1965     if (fHelp || params.size() != 1)
1966         throw runtime_error(
1967             "getblockhash <index>\n"
1968             "Returns hash of block in best-block-chain at <index>.");
1969
1970     int nHeight = params[0].get_int();
1971     if (nHeight < 0 || nHeight > nBestHeight)
1972         throw runtime_error("Block number out of range.");
1973
1974     CBlock block;
1975     CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
1976     while (pblockindex->nHeight > nHeight)
1977         pblockindex = pblockindex->pprev;
1978     return pblockindex->phashBlock->GetHex();
1979 }
1980
1981 Value getblock(const Array& params, bool fHelp)
1982 {
1983     if (fHelp || params.size() != 1)
1984         throw runtime_error(
1985             "getblock <hash>\n"
1986             "Returns details of a block with given block-hash.");
1987
1988     std::string strHash = params[0].get_str();
1989     uint256 hash(strHash);
1990
1991     if (mapBlockIndex.count(hash) == 0)
1992         throw JSONRPCError(-5, "Block not found");
1993
1994     CBlock block;
1995     CBlockIndex* pblockindex = mapBlockIndex[hash];
1996     block.ReadFromDisk(pblockindex, true);
1997
1998     return blockToJSON(block, pblockindex);
1999 }
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011 //
2012 // Call Table
2013 //
2014
2015 pair<string, rpcfn_type> pCallTable[] =
2016 {
2017     make_pair("help",                   &help),
2018     make_pair("stop",                   &stop),
2019     make_pair("getblockcount",          &getblockcount),
2020     make_pair("getblocknumber",         &getblocknumber),
2021     make_pair("getconnectioncount",     &getconnectioncount),
2022     make_pair("getdifficulty",          &getdifficulty),
2023     make_pair("getgenerate",            &getgenerate),
2024     make_pair("setgenerate",            &setgenerate),
2025     make_pair("gethashespersec",        &gethashespersec),
2026     make_pair("getinfo",                &getinfo),
2027     make_pair("getmininginfo",          &getmininginfo),
2028     make_pair("getnewaddress",          &getnewaddress),
2029     make_pair("getaccountaddress",      &getaccountaddress),
2030     make_pair("setaccount",             &setaccount),
2031     make_pair("getaccount",             &getaccount),
2032     make_pair("getaddressesbyaccount",  &getaddressesbyaccount),
2033     make_pair("sendtoaddress",          &sendtoaddress),
2034     make_pair("getreceivedbyaddress",   &getreceivedbyaddress),
2035     make_pair("getreceivedbyaccount",   &getreceivedbyaccount),
2036     make_pair("listreceivedbyaddress",  &listreceivedbyaddress),
2037     make_pair("listreceivedbyaccount",  &listreceivedbyaccount),
2038     make_pair("backupwallet",           &backupwallet),
2039     make_pair("keypoolrefill",          &keypoolrefill),
2040     make_pair("walletpassphrase",       &walletpassphrase),
2041     make_pair("walletpassphrasechange", &walletpassphrasechange),
2042     make_pair("walletlock",             &walletlock),
2043     make_pair("encryptwallet",          &encryptwallet),
2044     make_pair("validateaddress",        &validateaddress),
2045     make_pair("getbalance",             &getbalance),
2046     make_pair("move",                   &movecmd),
2047     make_pair("sendfrom",               &sendfrom),
2048     make_pair("sendmany",               &sendmany),
2049     make_pair("addmultisigaddress",     &addmultisigaddress),
2050     make_pair("getblock",               &getblock),
2051     make_pair("getblockhash",           &getblockhash),
2052     make_pair("gettransaction",         &gettransaction),
2053     make_pair("listtransactions",       &listtransactions),
2054     make_pair("signmessage",            &signmessage),
2055     make_pair("verifymessage",          &verifymessage),
2056     make_pair("getwork",                &getwork),
2057     make_pair("listaccounts",           &listaccounts),
2058     make_pair("settxfee",               &settxfee),
2059     make_pair("getmemorypool",          &getmemorypool),
2060     make_pair("listsinceblock",         &listsinceblock),
2061     make_pair("dumpprivkey",            &dumpprivkey),
2062     make_pair("importprivkey",          &importprivkey)
2063 };
2064 map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
2065
2066 string pAllowInSafeMode[] =
2067 {
2068     "help",
2069     "stop",
2070     "getblockcount",
2071     "getblocknumber",  // deprecated
2072     "getconnectioncount",
2073     "getdifficulty",
2074     "getgenerate",
2075     "setgenerate",
2076     "gethashespersec",
2077     "getinfo",
2078     "getmininginfo",
2079     "getnewaddress",
2080     "getaccountaddress",
2081     "getaccount",
2082     "getaddressesbyaccount",
2083     "backupwallet",
2084     "keypoolrefill",
2085     "walletpassphrase",
2086     "walletlock",
2087     "validateaddress",
2088     "getwork",
2089     "getmemorypool",
2090 };
2091 set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
2092
2093
2094
2095
2096 //
2097 // HTTP protocol
2098 //
2099 // This ain't Apache.  We're just using HTTP header for the length field
2100 // and to be compatible with other JSON-RPC implementations.
2101 //
2102
2103 string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders)
2104 {
2105     ostringstream s;
2106     s << "POST / HTTP/1.1\r\n"
2107       << "User-Agent: bitcoin-json-rpc/" << FormatFullVersion() << "\r\n"
2108       << "Host: 127.0.0.1\r\n"
2109       << "Content-Type: application/json\r\n"
2110       << "Content-Length: " << strMsg.size() << "\r\n"
2111       << "Connection: close\r\n"
2112       << "Accept: application/json\r\n";
2113     BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders)
2114         s << item.first << ": " << item.second << "\r\n";
2115     s << "\r\n" << strMsg;
2116
2117     return s.str();
2118 }
2119
2120 string rfc1123Time()
2121 {
2122     char buffer[64];
2123     time_t now;
2124     time(&now);
2125     struct tm* now_gmt = gmtime(&now);
2126     string locale(setlocale(LC_TIME, NULL));
2127     setlocale(LC_TIME, "C"); // we want posix (aka "C") weekday/month strings
2128     strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt);
2129     setlocale(LC_TIME, locale.c_str());
2130     return string(buffer);
2131 }
2132
2133 static string HTTPReply(int nStatus, const string& strMsg)
2134 {
2135     if (nStatus == 401)
2136         return strprintf("HTTP/1.0 401 Authorization Required\r\n"
2137             "Date: %s\r\n"
2138             "Server: bitcoin-json-rpc/%s\r\n"
2139             "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
2140             "Content-Type: text/html\r\n"
2141             "Content-Length: 296\r\n"
2142             "\r\n"
2143             "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
2144             "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
2145             "<HTML>\r\n"
2146             "<HEAD>\r\n"
2147             "<TITLE>Error</TITLE>\r\n"
2148             "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
2149             "</HEAD>\r\n"
2150             "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
2151             "</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
2152     const char *cStatus;
2153          if (nStatus == 200) cStatus = "OK";
2154     else if (nStatus == 400) cStatus = "Bad Request";
2155     else if (nStatus == 403) cStatus = "Forbidden";
2156     else if (nStatus == 404) cStatus = "Not Found";
2157     else if (nStatus == 500) cStatus = "Internal Server Error";
2158     else cStatus = "";
2159     return strprintf(
2160             "HTTP/1.1 %d %s\r\n"
2161             "Date: %s\r\n"
2162             "Connection: close\r\n"
2163             "Content-Length: %d\r\n"
2164             "Content-Type: application/json\r\n"
2165             "Server: bitcoin-json-rpc/%s\r\n"
2166             "\r\n"
2167             "%s",
2168         nStatus,
2169         cStatus,
2170         rfc1123Time().c_str(),
2171         strMsg.size(),
2172         FormatFullVersion().c_str(),
2173         strMsg.c_str());
2174 }
2175
2176 int ReadHTTPStatus(std::basic_istream<char>& stream)
2177 {
2178     string str;
2179     getline(stream, str);
2180     vector<string> vWords;
2181     boost::split(vWords, str, boost::is_any_of(" "));
2182     if (vWords.size() < 2)
2183         return 500;
2184     return atoi(vWords[1].c_str());
2185 }
2186
2187 int ReadHTTPHeader(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
2188 {
2189     int nLen = 0;
2190     loop
2191     {
2192         string str;
2193         std::getline(stream, str);
2194         if (str.empty() || str == "\r")
2195             break;
2196         string::size_type nColon = str.find(":");
2197         if (nColon != string::npos)
2198         {
2199             string strHeader = str.substr(0, nColon);
2200             boost::trim(strHeader);
2201             boost::to_lower(strHeader);
2202             string strValue = str.substr(nColon+1);
2203             boost::trim(strValue);
2204             mapHeadersRet[strHeader] = strValue;
2205             if (strHeader == "content-length")
2206                 nLen = atoi(strValue.c_str());
2207         }
2208     }
2209     return nLen;
2210 }
2211
2212 int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
2213 {
2214     mapHeadersRet.clear();
2215     strMessageRet = "";
2216
2217     // Read status
2218     int nStatus = ReadHTTPStatus(stream);
2219
2220     // Read header
2221     int nLen = ReadHTTPHeader(stream, mapHeadersRet);
2222     if (nLen < 0 || nLen > MAX_SIZE)
2223         return 500;
2224
2225     // Read message
2226     if (nLen > 0)
2227     {
2228         vector<char> vch(nLen);
2229         stream.read(&vch[0], nLen);
2230         strMessageRet = string(vch.begin(), vch.end());
2231     }
2232
2233     return nStatus;
2234 }
2235
2236 bool HTTPAuthorized(map<string, string>& mapHeaders)
2237 {
2238     string strAuth = mapHeaders["authorization"];
2239     if (strAuth.substr(0,6) != "Basic ")
2240         return false;
2241     string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
2242     string strUserPass = DecodeBase64(strUserPass64);
2243     return strUserPass == strRPCUserColonPass;
2244 }
2245
2246 //
2247 // JSON-RPC protocol.  Bitcoin speaks version 1.0 for maximum compatibility,
2248 // but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
2249 // unspecified (HTTP errors and contents of 'error').
2250 //
2251 // 1.0 spec: http://json-rpc.org/wiki/specification
2252 // 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http
2253 // http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
2254 //
2255
2256 string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
2257 {
2258     Object request;
2259     request.push_back(Pair("method", strMethod));
2260     request.push_back(Pair("params", params));
2261     request.push_back(Pair("id", id));
2262     return write_string(Value(request), false) + "\n";
2263 }
2264
2265 string JSONRPCReply(const Value& result, const Value& error, const Value& id)
2266 {
2267     Object reply;
2268     if (error.type() != null_type)
2269         reply.push_back(Pair("result", Value::null));
2270     else
2271         reply.push_back(Pair("result", result));
2272     reply.push_back(Pair("error", error));
2273     reply.push_back(Pair("id", id));
2274     return write_string(Value(reply), false) + "\n";
2275 }
2276
2277 void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
2278 {
2279     // Send error reply from json-rpc error object
2280     int nStatus = 500;
2281     int code = find_value(objError, "code").get_int();
2282     if (code == -32600) nStatus = 400;
2283     else if (code == -32601) nStatus = 404;
2284     string strReply = JSONRPCReply(Value::null, objError, id);
2285     stream << HTTPReply(nStatus, strReply) << std::flush;
2286 }
2287
2288 bool ClientAllowed(const string& strAddress)
2289 {
2290     if (strAddress == asio::ip::address_v4::loopback().to_string())
2291         return true;
2292     const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
2293     BOOST_FOREACH(string strAllow, vAllow)
2294         if (WildcardMatch(strAddress, strAllow))
2295             return true;
2296     return false;
2297 }
2298
2299 #ifdef USE_SSL
2300 //
2301 // IOStream device that speaks SSL but can also speak non-SSL
2302 //
2303 class SSLIOStreamDevice : public iostreams::device<iostreams::bidirectional> {
2304 public:
2305     SSLIOStreamDevice(SSLStream &streamIn, bool fUseSSLIn) : stream(streamIn)
2306     {
2307         fUseSSL = fUseSSLIn;
2308         fNeedHandshake = fUseSSLIn;
2309     }
2310
2311     void handshake(ssl::stream_base::handshake_type role)
2312     {
2313         if (!fNeedHandshake) return;
2314         fNeedHandshake = false;
2315         stream.handshake(role);
2316     }
2317     std::streamsize read(char* s, std::streamsize n)
2318     {
2319         handshake(ssl::stream_base::server); // HTTPS servers read first
2320         if (fUseSSL) return stream.read_some(asio::buffer(s, n));
2321         return stream.next_layer().read_some(asio::buffer(s, n));
2322     }
2323     std::streamsize write(const char* s, std::streamsize n)
2324     {
2325         handshake(ssl::stream_base::client); // HTTPS clients write first
2326         if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
2327         return asio::write(stream.next_layer(), asio::buffer(s, n));
2328     }
2329     bool connect(const std::string& server, const std::string& port)
2330     {
2331         ip::tcp::resolver resolver(stream.get_io_service());
2332         ip::tcp::resolver::query query(server.c_str(), port.c_str());
2333         ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
2334         ip::tcp::resolver::iterator end;
2335         boost::system::error_code error = asio::error::host_not_found;
2336         while (error && endpoint_iterator != end)
2337         {
2338             stream.lowest_layer().close();
2339             stream.lowest_layer().connect(*endpoint_iterator++, error);
2340         }
2341         if (error)
2342             return false;
2343         return true;
2344     }
2345
2346 private:
2347     bool fNeedHandshake;
2348     bool fUseSSL;
2349     SSLStream& stream;
2350 };
2351 #endif
2352
2353 void ThreadRPCServer(void* parg)
2354 {
2355     IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
2356     try
2357     {
2358         vnThreadsRunning[THREAD_RPCSERVER]++;
2359         ThreadRPCServer2(parg);
2360         vnThreadsRunning[THREAD_RPCSERVER]--;
2361     }
2362     catch (std::exception& e) {
2363         vnThreadsRunning[THREAD_RPCSERVER]--;
2364         PrintException(&e, "ThreadRPCServer()");
2365     } catch (...) {
2366         vnThreadsRunning[THREAD_RPCSERVER]--;
2367         PrintException(NULL, "ThreadRPCServer()");
2368     }
2369     printf("ThreadRPCServer exiting\n");
2370 }
2371
2372 #ifdef QT_GUI
2373 extern bool HACK_SHUTDOWN;
2374 #endif
2375
2376 void ThreadRPCServer2(void* parg)
2377 {
2378     printf("ThreadRPCServer started\n");
2379
2380     strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
2381     if (mapArgs["-rpcpassword"] == "")
2382     {
2383         unsigned char rand_pwd[32];
2384         RAND_bytes(rand_pwd, 32);
2385         string strWhatAmI = "To use bitcoind";
2386         if (mapArgs.count("-server"))
2387             strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
2388         else if (mapArgs.count("-daemon"))
2389             strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
2390         ThreadSafeMessageBox(strprintf(
2391             _("%s, you must set a rpcpassword in the configuration file:\n %s\n"
2392               "It is recommended you use the following random password:\n"
2393               "rpcuser=bitcoinrpc\n"
2394               "rpcpassword=%s\n"
2395               "(you do not need to remember this password)\n"
2396               "If the file does not exist, create it with owner-readable-only file permissions.\n"),
2397                 strWhatAmI.c_str(),
2398                 GetConfigFile().c_str(),
2399                 EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
2400             _("Error"), wxOK | wxMODAL);
2401 #ifndef QT_GUI
2402         CreateThread(Shutdown, NULL);
2403 #endif
2404         return;
2405     }
2406
2407     bool fUseSSL = GetBoolArg("-rpcssl");
2408     asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback();
2409
2410     asio::io_service io_service;
2411     ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
2412 #ifndef QT_GUI
2413     ip::tcp::acceptor acceptor(io_service, endpoint);
2414
2415     acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
2416 #else
2417     ip::tcp::acceptor acceptor(io_service);
2418     try
2419     {
2420         acceptor.open(endpoint.protocol());
2421         acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
2422         acceptor.bind(endpoint);
2423         acceptor.listen(socket_base::max_connections);
2424     }
2425     catch(system::system_error &e)
2426     {
2427         HACK_SHUTDOWN = true;
2428         ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
2429                              _("Error"), wxOK | wxMODAL);
2430         return;
2431     }
2432 #endif
2433
2434 #ifdef USE_SSL
2435     ssl::context context(io_service, ssl::context::sslv23);
2436     if (fUseSSL)
2437     {
2438         context.set_options(ssl::context::no_sslv2);
2439         filesystem::path certfile = GetArg("-rpcsslcertificatechainfile", "server.cert");
2440         if (!certfile.is_complete()) certfile = filesystem::path(GetDataDir()) / certfile;
2441         if (filesystem::exists(certfile)) context.use_certificate_chain_file(certfile.string().c_str());
2442         else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", certfile.string().c_str());
2443         filesystem::path pkfile = GetArg("-rpcsslprivatekeyfile", "server.pem");
2444         if (!pkfile.is_complete()) pkfile = filesystem::path(GetDataDir()) / pkfile;
2445         if (filesystem::exists(pkfile)) context.use_private_key_file(pkfile.string().c_str(), ssl::context::pem);
2446         else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pkfile.string().c_str());
2447
2448         string ciphers = GetArg("-rpcsslciphers",
2449                                          "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
2450         SSL_CTX_set_cipher_list(context.impl(), ciphers.c_str());
2451     }
2452 #else
2453     if (fUseSSL)
2454         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2455 #endif
2456
2457     loop
2458     {
2459         // Accept connection
2460 #ifdef USE_SSL
2461         SSLStream sslStream(io_service, context);
2462         SSLIOStreamDevice d(sslStream, fUseSSL);
2463         iostreams::stream<SSLIOStreamDevice> stream(d);
2464 #else
2465         ip::tcp::iostream stream;
2466 #endif
2467
2468         ip::tcp::endpoint peer;
2469         vnThreadsRunning[THREAD_RPCSERVER]--;
2470 #ifdef USE_SSL
2471         acceptor.accept(sslStream.lowest_layer(), peer);
2472 #else
2473         acceptor.accept(*stream.rdbuf(), peer);
2474 #endif
2475         vnThreadsRunning[4]++;
2476         if (fShutdown)
2477             return;
2478
2479         // Restrict callers by IP
2480         if (!ClientAllowed(peer.address().to_string()))
2481         {
2482             // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
2483             if (!fUseSSL)
2484                 stream << HTTPReply(403, "") << std::flush;
2485             continue;
2486         }
2487
2488         map<string, string> mapHeaders;
2489         string strRequest;
2490
2491         boost::thread api_caller(ReadHTTP, boost::ref(stream), boost::ref(mapHeaders), boost::ref(strRequest));
2492         if (!api_caller.timed_join(boost::posix_time::seconds(GetArg("-rpctimeout", 30))))
2493         {   // Timed out:
2494             acceptor.cancel();
2495             printf("ThreadRPCServer ReadHTTP timeout\n");
2496             continue;
2497         }
2498
2499         // Check authorization
2500         if (mapHeaders.count("authorization") == 0)
2501         {
2502             stream << HTTPReply(401, "") << std::flush;
2503             continue;
2504         }
2505         if (!HTTPAuthorized(mapHeaders))
2506         {
2507             printf("ThreadRPCServer incorrect password attempt from %s\n",peer.address().to_string().c_str());
2508             /* Deter brute-forcing short passwords.
2509                If this results in a DOS the user really
2510                shouldn't have their RPC port exposed.*/
2511             if (mapArgs["-rpcpassword"].size() < 20)
2512                 Sleep(250);
2513
2514             stream << HTTPReply(401, "") << std::flush;
2515             continue;
2516         }
2517
2518         Value id = Value::null;
2519         try
2520         {
2521             // Parse request
2522             Value valRequest;
2523             if (!read_string(strRequest, valRequest) || valRequest.type() != obj_type)
2524                 throw JSONRPCError(-32700, "Parse error");
2525             const Object& request = valRequest.get_obj();
2526
2527             // Parse id now so errors from here on will have the id
2528             id = find_value(request, "id");
2529
2530             // Parse method
2531             Value valMethod = find_value(request, "method");
2532             if (valMethod.type() == null_type)
2533                 throw JSONRPCError(-32600, "Missing method");
2534             if (valMethod.type() != str_type)
2535                 throw JSONRPCError(-32600, "Method must be a string");
2536             string strMethod = valMethod.get_str();
2537             if (strMethod != "getwork" && strMethod != "getmemorypool")
2538                 printf("ThreadRPCServer method=%s\n", strMethod.c_str());
2539
2540             // Parse params
2541             Value valParams = find_value(request, "params");
2542             Array params;
2543             if (valParams.type() == array_type)
2544                 params = valParams.get_array();
2545             else if (valParams.type() == null_type)
2546                 params = Array();
2547             else
2548                 throw JSONRPCError(-32600, "Params must be an array");
2549
2550             // Find method
2551             map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
2552             if (mi == mapCallTable.end())
2553                 throw JSONRPCError(-32601, "Method not found");
2554
2555             // Observe safe mode
2556             string strWarning = GetWarnings("rpc");
2557             if (strWarning != "" && !GetBoolArg("-disablesafemode") && !setAllowInSafeMode.count(strMethod))
2558                 throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
2559
2560             try
2561             {
2562                 // Execute
2563                 Value result;
2564                 CRITICAL_BLOCK(cs_main)
2565                 CRITICAL_BLOCK(pwalletMain->cs_wallet)
2566                     result = (*(*mi).second)(params, false);
2567
2568                 // Send reply
2569                 string strReply = JSONRPCReply(result, Value::null, id);
2570                 stream << HTTPReply(200, strReply) << std::flush;
2571             }
2572             catch (std::exception& e)
2573             {
2574                 ErrorReply(stream, JSONRPCError(-1, e.what()), id);
2575             }
2576         }
2577         catch (Object& objError)
2578         {
2579             ErrorReply(stream, objError, id);
2580         }
2581         catch (std::exception& e)
2582         {
2583             ErrorReply(stream, JSONRPCError(-32700, e.what()), id);
2584         }
2585     }
2586 }
2587
2588
2589
2590
2591 Object CallRPC(const string& strMethod, const Array& params)
2592 {
2593     if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
2594         throw runtime_error(strprintf(
2595             _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
2596               "If the file does not exist, create it with owner-readable-only file permissions."),
2597                 GetConfigFile().c_str()));
2598
2599     // Connect to localhost
2600     bool fUseSSL = GetBoolArg("-rpcssl");
2601 #ifdef USE_SSL
2602     asio::io_service io_service;
2603     ssl::context context(io_service, ssl::context::sslv23);
2604     context.set_options(ssl::context::no_sslv2);
2605     SSLStream sslStream(io_service, context);
2606     SSLIOStreamDevice d(sslStream, fUseSSL);
2607     iostreams::stream<SSLIOStreamDevice> stream(d);
2608     if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332")))
2609         throw runtime_error("couldn't connect to server");
2610 #else
2611     if (fUseSSL)
2612         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2613
2614     ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332"));
2615     if (stream.fail())
2616         throw runtime_error("couldn't connect to server");
2617 #endif
2618
2619
2620     // HTTP basic authentication
2621     string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
2622     map<string, string> mapRequestHeaders;
2623     mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
2624
2625     // Send request
2626     string strRequest = JSONRPCRequest(strMethod, params, 1);
2627     string strPost = HTTPPost(strRequest, mapRequestHeaders);
2628     stream << strPost << std::flush;
2629
2630     // Receive reply
2631     map<string, string> mapHeaders;
2632     string strReply;
2633     int nStatus = ReadHTTP(stream, mapHeaders, strReply);
2634     if (nStatus == 401)
2635         throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
2636     else if (nStatus >= 400 && nStatus != 400 && nStatus != 404 && nStatus != 500)
2637         throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
2638     else if (strReply.empty())
2639         throw runtime_error("no response from server");
2640
2641     // Parse reply
2642     Value valReply;
2643     if (!read_string(strReply, valReply))
2644         throw runtime_error("couldn't parse reply from server");
2645     const Object& reply = valReply.get_obj();
2646     if (reply.empty())
2647         throw runtime_error("expected reply to have result, error and id properties");
2648
2649     return reply;
2650 }
2651
2652
2653
2654
2655 template<typename T>
2656 void ConvertTo(Value& value)
2657 {
2658     if (value.type() == str_type)
2659     {
2660         // reinterpret string as unquoted json value
2661         Value value2;
2662         if (!read_string(value.get_str(), value2))
2663             throw runtime_error("type mismatch");
2664         value = value2.get_value<T>();
2665     }
2666     else
2667     {
2668         value = value.get_value<T>();
2669     }
2670 }
2671
2672 int CommandLineRPC(int argc, char *argv[])
2673 {
2674     string strPrint;
2675     int nRet = 0;
2676     try
2677     {
2678         // Skip switches
2679         while (argc > 1 && IsSwitchChar(argv[1][0]))
2680         {
2681             argc--;
2682             argv++;
2683         }
2684
2685         // Method
2686         if (argc < 2)
2687             throw runtime_error("too few parameters");
2688         string strMethod = argv[1];
2689
2690         // Parameters default to strings
2691         Array params;
2692         for (int i = 2; i < argc; i++)
2693             params.push_back(argv[i]);
2694         int n = params.size();
2695
2696         //
2697         // Special case non-string parameter types
2698         //
2699         if (strMethod == "setgenerate"            && n > 0) ConvertTo<bool>(params[0]);
2700         if (strMethod == "setgenerate"            && n > 1) ConvertTo<boost::int64_t>(params[1]);
2701         if (strMethod == "sendtoaddress"          && n > 1) ConvertTo<double>(params[1]);
2702         if (strMethod == "settxfee"               && n > 0) ConvertTo<double>(params[0]);
2703         if (strMethod == "getreceivedbyaddress"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2704         if (strMethod == "getreceivedbyaccount"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2705         if (strMethod == "listreceivedbyaddress"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2706         if (strMethod == "listreceivedbyaddress"  && n > 1) ConvertTo<bool>(params[1]);
2707         if (strMethod == "listreceivedbyaccount"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2708         if (strMethod == "listreceivedbyaccount"  && n > 1) ConvertTo<bool>(params[1]);
2709         if (strMethod == "getbalance"             && n > 1) ConvertTo<boost::int64_t>(params[1]);
2710         if (strMethod == "getblockhash"           && n > 0) ConvertTo<boost::int64_t>(params[0]);
2711         if (strMethod == "move"                   && n > 2) ConvertTo<double>(params[2]);
2712         if (strMethod == "move"                   && n > 3) ConvertTo<boost::int64_t>(params[3]);
2713         if (strMethod == "sendfrom"               && n > 2) ConvertTo<double>(params[2]);
2714         if (strMethod == "sendfrom"               && n > 3) ConvertTo<boost::int64_t>(params[3]);
2715         if (strMethod == "listtransactions"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2716         if (strMethod == "listtransactions"       && n > 2) ConvertTo<boost::int64_t>(params[2]);
2717         if (strMethod == "listaccounts"           && n > 0) ConvertTo<boost::int64_t>(params[0]);
2718         if (strMethod == "walletpassphrase"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2719         if (strMethod == "listsinceblock"         && n > 1) ConvertTo<boost::int64_t>(params[1]);
2720         if (strMethod == "sendmany"               && n > 1)
2721         {
2722             string s = params[1].get_str();
2723             Value v;
2724             if (!read_string(s, v) || v.type() != obj_type)
2725                 throw runtime_error("type mismatch");
2726             params[1] = v.get_obj();
2727         }
2728         if (strMethod == "sendmany"                && n > 2) ConvertTo<boost::int64_t>(params[2]);
2729         if (strMethod == "addmultisigaddress"      && n > 0) ConvertTo<boost::int64_t>(params[0]);
2730         if (strMethod == "addmultisigaddress"      && n > 1)
2731         {
2732             string s = params[1].get_str();
2733             Value v;
2734             if (!read_string(s, v) || v.type() != array_type)
2735                 throw runtime_error("type mismatch "+s);
2736             params[1] = v.get_array();
2737         }
2738
2739         // Execute
2740         Object reply = CallRPC(strMethod, params);
2741
2742         // Parse reply
2743         const Value& result = find_value(reply, "result");
2744         const Value& error  = find_value(reply, "error");
2745
2746         if (error.type() != null_type)
2747         {
2748             // Error
2749             strPrint = "error: " + write_string(error, false);
2750             int code = find_value(error.get_obj(), "code").get_int();
2751             nRet = abs(code);
2752         }
2753         else
2754         {
2755             // Result
2756             if (result.type() == null_type)
2757                 strPrint = "";
2758             else if (result.type() == str_type)
2759                 strPrint = result.get_str();
2760             else
2761                 strPrint = write_string(result, true);
2762         }
2763     }
2764     catch (std::exception& e)
2765     {
2766         strPrint = string("error: ") + e.what();
2767         nRet = 87;
2768     }
2769     catch (...)
2770     {
2771         PrintException(NULL, "CommandLineRPC()");
2772     }
2773
2774     if (strPrint != "")
2775     {
2776         fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
2777     }
2778     return nRet;
2779 }
2780
2781
2782
2783
2784 #ifdef TEST
2785 int main(int argc, char *argv[])
2786 {
2787 #ifdef _MSC_VER
2788     // Turn off microsoft heap dump noise
2789     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
2790     _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
2791 #endif
2792     setbuf(stdin, NULL);
2793     setbuf(stdout, NULL);
2794     setbuf(stderr, NULL);
2795
2796     try
2797     {
2798         if (argc >= 2 && string(argv[1]) == "-server")
2799         {
2800             printf("server ready\n");
2801             ThreadRPCServer(NULL);
2802         }
2803         else
2804         {
2805             return CommandLineRPC(argc, argv);
2806         }
2807     }
2808     catch (std::exception& e) {
2809         PrintException(&e, "main()");
2810     } catch (...) {
2811         PrintException(NULL, "main()");
2812     }
2813     return 0;
2814 }
2815 #endif