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