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