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