8f981356172a9943096f4f41dae722a1ccb35cb4
[novacoin.git] / src / bitcoinrpc.cpp
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "headers.h"
7 #include "db.h"
8 #include "net.h"
9 #include "init.h"
10 #undef printf
11 #include <boost/asio.hpp>
12 #include <boost/filesystem.hpp>
13 #include <boost/iostreams/concepts.hpp>
14 #include <boost/iostreams/stream.hpp>
15 #include <boost/algorithm/string.hpp>
16 #include <boost/lexical_cast.hpp>
17 #ifdef USE_SSL
18 #include <boost/asio/ssl.hpp> 
19 #include <boost/filesystem.hpp>
20 #include <boost/filesystem/fstream.hpp>
21 typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
22 #endif
23 #include "json/json_spirit_reader_template.h"
24 #include "json/json_spirit_writer_template.h"
25 #include "json/json_spirit_utils.h"
26 #define printf OutputDebugStringF
27 // MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are
28 // precompiled in headers.h.  The problem might be when the pch file goes over
29 // a certain size around 145MB.  If we need access to json_spirit outside this
30 // file, we could use the compiled json_spirit option.
31
32 using namespace std;
33 using namespace boost;
34 using namespace boost::asio;
35 using namespace json_spirit;
36
37 void ThreadRPCServer2(void* parg);
38 typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
39 extern map<string, rpcfn_type> mapCallTable;
40
41 static std::string strRPCUserColonPass;
42
43 static int64 nWalletUnlockTime;
44 static CCriticalSection cs_nWalletUnlockTime;
45
46 extern Value dumpprivkey(const Array& params, bool fHelp);
47 extern Value importprivkey(const Array& params, bool fHelp);
48
49 Object JSONRPCError(int code, const string& message)
50 {
51     Object error;
52     error.push_back(Pair("code", code));
53     error.push_back(Pair("message", message));
54     return error;
55 }
56
57
58 void PrintConsole(const std::string &format, ...)
59 {
60     char buffer[50000];
61     int limit = sizeof(buffer);
62     va_list arg_ptr;
63     va_start(arg_ptr, format);
64     int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr);
65     va_end(arg_ptr);
66     if (ret < 0 || ret >= limit)
67     {
68         ret = limit - 1;
69         buffer[limit-1] = 0;
70     }
71     printf("%s", buffer);
72     fprintf(stdout, "%s", buffer);
73 }
74
75 double GetDifficulty(const CBlockIndex* blockindex = NULL)
76 {
77     // Floating point number that is a multiple of the minimum difficulty,
78     // minimum difficulty = 1.0.
79     if (blockindex == NULL)
80     {
81         if (pindexBest == NULL)
82             return 1.0;
83         else
84             blockindex = pindexBest;
85     }
86
87     int nShift = (blockindex->nBits >> 24) & 0xff;
88
89     double dDiff =
90         (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
91
92     while (nShift < 29)
93     {
94         dDiff *= 256.0;
95         nShift++;
96     }
97     while (nShift > 29)
98     {
99         dDiff /= 256.0;
100         nShift--;
101     }
102
103     return dDiff;
104 }
105
106
107 int64 AmountFromValue(const Value& value)
108 {
109     double dAmount = value.get_real();
110     if (dAmount <= 0.0 || dAmount > 21000000.0)
111         throw JSONRPCError(-3, "Invalid amount");
112     int64 nAmount = roundint64(dAmount * COIN);
113     if (!MoneyRange(nAmount))
114         throw JSONRPCError(-3, "Invalid amount");
115     return nAmount;
116 }
117
118 Value ValueFromAmount(int64 amount)
119 {
120     return (double)amount / (double)COIN;
121 }
122
123 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     ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
1543
1544     if (nWalletUnlockTime == 0)
1545     {
1546         nWalletUnlockTime = nMyWakeTime;
1547
1548         while (GetTime() < nWalletUnlockTime)
1549         {
1550             int64 nToSleep = GetTime() - nWalletUnlockTime;
1551
1552             LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
1553             Sleep(nToSleep);
1554             ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
1555         }
1556
1557         nWalletUnlockTime = 0;
1558         pwalletMain->Lock();
1559     }
1560     else
1561     {
1562         if (nWalletUnlockTime < nMyWakeTime)
1563             nWalletUnlockTime = nMyWakeTime;
1564     }
1565
1566     LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
1567
1568     delete (int*)parg;
1569 }
1570
1571 Value walletpassphrase(const Array& params, bool fHelp)
1572 {
1573     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1574         throw runtime_error(
1575             "walletpassphrase <passphrase> <timeout>\n"
1576             "Stores the wallet decryption key in memory for <timeout> seconds.");
1577     if (fHelp)
1578         return true;
1579     if (!pwalletMain->IsCrypted())
1580         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
1581
1582     if (!pwalletMain->IsLocked())
1583         throw JSONRPCError(-17, "Error: Wallet is already unlocked.");
1584
1585     // Note that the walletpassphrase is stored in params[0] which is not mlock()ed
1586     SecureString strWalletPass;
1587     strWalletPass.reserve(100);
1588     // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1589     // Alternately, find a way to make params[0] mlock()'d to begin with.
1590     strWalletPass = params[0].get_str().c_str();
1591
1592     if (strWalletPass.length() > 0)
1593     {
1594         if (!pwalletMain->Unlock(strWalletPass))
1595             throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
1596     }
1597     else
1598         throw runtime_error(
1599             "walletpassphrase <passphrase> <timeout>\n"
1600             "Stores the wallet decryption key in memory for <timeout> seconds.");
1601
1602     CreateThread(ThreadTopUpKeyPool, NULL);
1603     int* pnSleepTime = new int(params[1].get_int());
1604     CreateThread(ThreadCleanWalletPassphrase, pnSleepTime);
1605
1606     return Value::null;
1607 }
1608
1609
1610 Value walletpassphrasechange(const Array& params, bool fHelp)
1611 {
1612     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1613         throw runtime_error(
1614             "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1615             "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1616     if (fHelp)
1617         return true;
1618     if (!pwalletMain->IsCrypted())
1619         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
1620
1621     // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
1622     // Alternately, find a way to make params[0] mlock()'d to begin with.
1623     SecureString strOldWalletPass;
1624     strOldWalletPass.reserve(100);
1625     strOldWalletPass = params[0].get_str().c_str();
1626
1627     SecureString strNewWalletPass;
1628     strNewWalletPass.reserve(100);
1629     strNewWalletPass = params[1].get_str().c_str();
1630
1631     if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
1632         throw runtime_error(
1633             "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1634             "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1635
1636     if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
1637         throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
1638
1639     return Value::null;
1640 }
1641
1642
1643 Value walletlock(const Array& params, bool fHelp)
1644 {
1645     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0))
1646         throw runtime_error(
1647             "walletlock\n"
1648             "Removes the wallet encryption key from memory, locking the wallet.\n"
1649             "After calling this method, you will need to call walletpassphrase again\n"
1650             "before being able to call any methods which require the wallet to be unlocked.");
1651     if (fHelp)
1652         return true;
1653     if (!pwalletMain->IsCrypted())
1654         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
1655
1656     pwalletMain->Lock();
1657     CRITICAL_BLOCK(cs_nWalletUnlockTime)
1658     {
1659         nWalletUnlockTime = 0;
1660     }
1661
1662     return Value::null;
1663 }
1664
1665
1666 Value encryptwallet(const Array& params, bool fHelp)
1667 {
1668     if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
1669         throw runtime_error(
1670             "encryptwallet <passphrase>\n"
1671             "Encrypts the wallet with <passphrase>.");
1672     if (fHelp)
1673         return true;
1674     if (pwalletMain->IsCrypted())
1675         throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called.");
1676
1677 #ifdef QT_GUI
1678     // shutting down via RPC while the GUI is running does not work (yet):
1679     throw runtime_error("Not Yet Implemented: use GUI to encrypt wallet, not RPC command");
1680 #endif
1681
1682     // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1683     // Alternately, find a way to make params[0] mlock()'d to begin with.
1684     SecureString strWalletPass;
1685     strWalletPass.reserve(100);
1686     strWalletPass = params[0].get_str().c_str();
1687
1688     if (strWalletPass.length() < 1)
1689         throw runtime_error(
1690             "encryptwallet <passphrase>\n"
1691             "Encrypts the wallet with <passphrase>.");
1692
1693     if (!pwalletMain->EncryptWallet(strWalletPass))
1694         throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
1695
1696     // BDB seems to have a bad habit of writing old data into
1697     // slack space in .dat files; that is bad if the old data is
1698     // unencrypted private keys.  So:
1699     CreateThread(Shutdown, NULL);
1700     return "wallet encrypted; bitcoin server stopping, restart to run with encrypted wallet";
1701 }
1702
1703
1704 Value validateaddress(const Array& params, bool fHelp)
1705 {
1706     if (fHelp || params.size() != 1)
1707         throw runtime_error(
1708             "validateaddress <bitcoinaddress>\n"
1709             "Return information about <bitcoinaddress>.");
1710
1711     CBitcoinAddress address(params[0].get_str());
1712     bool isValid = address.IsValid();
1713
1714     Object ret;
1715     ret.push_back(Pair("isvalid", isValid));
1716     if (isValid)
1717     {
1718         // Call Hash160ToAddress() so we always return current ADDRESSVERSION
1719         // version of the address:
1720         string currentAddress = address.ToString();
1721         ret.push_back(Pair("address", currentAddress));
1722         if (pwalletMain->HaveKey(address))
1723         {
1724             ret.push_back(Pair("ismine", true));
1725             std::vector<unsigned char> vchPubKey;
1726             pwalletMain->GetPubKey(address, vchPubKey);
1727             ret.push_back(Pair("pubkey", HexStr(vchPubKey)));
1728             CKey key;
1729             key.SetPubKey(vchPubKey);
1730             ret.push_back(Pair("iscompressed", key.IsCompressed()));
1731         }
1732         else if (pwalletMain->HaveCScript(address.GetHash160()))
1733         {
1734             ret.push_back(Pair("isscript", true));
1735             CScript subscript;
1736             pwalletMain->GetCScript(address.GetHash160(), subscript);
1737             ret.push_back(Pair("ismine", ::IsMine(*pwalletMain, subscript)));
1738             std::vector<CBitcoinAddress> addresses;
1739             txnouttype whichType;
1740             int nRequired;
1741             ExtractAddresses(subscript, whichType, addresses, nRequired);
1742             ret.push_back(Pair("script", GetTxnOutputType(whichType)));
1743             Array a;
1744             BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
1745                 a.push_back(addr.ToString());
1746             ret.push_back(Pair("addresses", a));
1747             if (whichType == TX_MULTISIG)
1748                 ret.push_back(Pair("sigsrequired", nRequired));
1749         }
1750         else
1751             ret.push_back(Pair("ismine", false));
1752         if (pwalletMain->mapAddressBook.count(address))
1753             ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
1754     }
1755     return ret;
1756 }
1757
1758 Value getwork(const Array& params, bool fHelp)
1759 {
1760     if (fHelp || params.size() > 1)
1761         throw runtime_error(
1762             "getwork [data]\n"
1763             "If [data] is not specified, returns formatted hash data to work on:\n"
1764             "  \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
1765             "  \"data\" : block data\n"
1766             "  \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
1767             "  \"target\" : little endian hash target\n"
1768             "If [data] is specified, tries to solve the block and returns true if it was successful.");
1769
1770     if (vNodes.empty())
1771         throw JSONRPCError(-9, "Bitcoin is not connected!");
1772
1773     if (IsInitialBlockDownload())
1774         throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
1775
1776     typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
1777     static mapNewBlock_t mapNewBlock;
1778     static vector<CBlock*> vNewBlock;
1779     static CReserveKey reservekey(pwalletMain);
1780
1781     if (params.size() == 0)
1782     {
1783         // Update block
1784         static unsigned int nTransactionsUpdatedLast;
1785         static CBlockIndex* pindexPrev;
1786         static int64 nStart;
1787         static CBlock* pblock;
1788         if (pindexPrev != pindexBest ||
1789             (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
1790         {
1791             if (pindexPrev != pindexBest)
1792             {
1793                 // Deallocate old blocks since they're obsolete now
1794                 mapNewBlock.clear();
1795                 BOOST_FOREACH(CBlock* pblock, vNewBlock)
1796                     delete pblock;
1797                 vNewBlock.clear();
1798             }
1799             nTransactionsUpdatedLast = nTransactionsUpdated;
1800             pindexPrev = pindexBest;
1801             nStart = GetTime();
1802
1803             // Create new block
1804             pblock = CreateNewBlock(reservekey);
1805             if (!pblock)
1806                 throw JSONRPCError(-7, "Out of memory");
1807             vNewBlock.push_back(pblock);
1808         }
1809
1810         // Update nTime
1811         pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
1812         pblock->nNonce = 0;
1813
1814         // Update nExtraNonce
1815         static unsigned int nExtraNonce = 0;
1816         IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
1817
1818         // Save
1819         mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
1820
1821         // Prebuild hash buffers
1822         char pmidstate[32];
1823         char pdata[128];
1824         char phash1[64];
1825         FormatHashBuffers(pblock, pmidstate, pdata, phash1);
1826
1827         uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
1828
1829         Object result;
1830         result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
1831         result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
1832         result.push_back(Pair("hash1",    HexStr(BEGIN(phash1), END(phash1)))); // deprecated
1833         result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));
1834         return result;
1835     }
1836     else
1837     {
1838         // Parse parameters
1839         vector<unsigned char> vchData = ParseHex(params[0].get_str());
1840         if (vchData.size() != 128)
1841             throw JSONRPCError(-8, "Invalid parameter");
1842         CBlock* pdata = (CBlock*)&vchData[0];
1843
1844         // Byte reverse
1845         for (int i = 0; i < 128/4; i++)
1846             ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
1847
1848         // Get saved block
1849         if (!mapNewBlock.count(pdata->hashMerkleRoot))
1850             return false;
1851         CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
1852
1853         pblock->nTime = pdata->nTime;
1854         pblock->nNonce = pdata->nNonce;
1855         pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
1856         pblock->hashMerkleRoot = pblock->BuildMerkleTree();
1857
1858         return CheckWork(pblock, *pwalletMain, reservekey);
1859     }
1860 }
1861
1862
1863 Value getmemorypool(const Array& params, bool fHelp)
1864 {
1865     if (fHelp || params.size() > 1)
1866         throw runtime_error(
1867             "getmemorypool [data]\n"
1868             "If [data] is not specified, returns data needed to construct a block to work on:\n"
1869             "  \"version\" : block version\n"
1870             "  \"previousblockhash\" : hash of current highest block\n"
1871             "  \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n"
1872             "  \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n"
1873             "  \"coinbaseflags\" : data that should be included in coinbase so support for new features can be judged\n"
1874             "  \"time\" : timestamp appropriate for next block\n"
1875             "  \"mintime\" : minimum timestamp appropriate for next block\n"
1876             "  \"curtime\" : current timestamp\n"
1877             "  \"bits\" : compressed target of next block\n"
1878             "If [data] is specified, tries to solve the block and returns true if it was successful.");
1879
1880     if (params.size() == 0)
1881     {
1882         if (vNodes.empty())
1883             throw JSONRPCError(-9, "Bitcoin is not connected!");
1884
1885         if (IsInitialBlockDownload())
1886             throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
1887
1888         static CReserveKey reservekey(pwalletMain);
1889
1890         // Update block
1891         static unsigned int nTransactionsUpdatedLast;
1892         static CBlockIndex* pindexPrev;
1893         static int64 nStart;
1894         static CBlock* pblock;
1895         if (pindexPrev != pindexBest ||
1896             (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5))
1897         {
1898             nTransactionsUpdatedLast = nTransactionsUpdated;
1899             pindexPrev = pindexBest;
1900             nStart = GetTime();
1901
1902             // Create new block
1903             if(pblock)
1904                 delete pblock;
1905             pblock = CreateNewBlock(reservekey);
1906             if (!pblock)
1907                 throw JSONRPCError(-7, "Out of memory");
1908         }
1909
1910         // Update nTime
1911         pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
1912         pblock->nNonce = 0;
1913
1914         Array transactions;
1915         BOOST_FOREACH(CTransaction tx, pblock->vtx) {
1916             if(tx.IsCoinBase())
1917                 continue;
1918
1919             CDataStream ssTx;
1920             ssTx << tx;
1921
1922             transactions.push_back(HexStr(ssTx.begin(), ssTx.end()));
1923         }
1924
1925         Object result;
1926         result.push_back(Pair("version", pblock->nVersion));
1927         result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
1928         result.push_back(Pair("transactions", transactions));
1929         result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
1930         result.push_back(Pair("coinbaseflags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
1931         result.push_back(Pair("time", (int64_t)pblock->nTime));
1932         result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
1933         result.push_back(Pair("curtime", (int64_t)GetAdjustedTime()));
1934
1935         union {
1936             int32_t nBits;
1937             char cBits[4];
1938         } uBits;
1939         uBits.nBits = htonl((int32_t)pblock->nBits);
1940         result.push_back(Pair("bits", HexStr(BEGIN(uBits.cBits), END(uBits.cBits))));
1941
1942         return result;
1943     }
1944     else
1945     {
1946         // Parse parameters
1947         CDataStream ssBlock(ParseHex(params[0].get_str()));
1948         CBlock pblock;
1949         ssBlock >> pblock;
1950
1951         return ProcessBlock(NULL, &pblock);
1952     }
1953 }
1954
1955 Value getblockhash(const Array& params, bool fHelp)
1956 {
1957     if (fHelp || params.size() != 1)
1958         throw runtime_error(
1959             "getblockhash <index>\n"
1960             "Returns hash of block in best-block-chain at <index>.");
1961
1962     int nHeight = params[0].get_int();
1963     if (nHeight < 0 || nHeight > nBestHeight)
1964         throw runtime_error("Block number out of range.");
1965
1966     CBlock block;
1967     CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
1968     while (pblockindex->nHeight > nHeight)
1969         pblockindex = pblockindex->pprev;
1970     return pblockindex->phashBlock->GetHex();
1971 }
1972
1973 Value getblock(const Array& params, bool fHelp)
1974 {
1975     if (fHelp || params.size() != 1)
1976         throw runtime_error(
1977             "getblock <hash>\n"
1978             "Returns details of a block with given block-hash.");
1979
1980     std::string strHash = params[0].get_str();
1981     uint256 hash(strHash);
1982
1983     if (mapBlockIndex.count(hash) == 0)
1984         throw JSONRPCError(-5, "Block not found");
1985
1986     CBlock block;
1987     CBlockIndex* pblockindex = mapBlockIndex[hash];
1988     block.ReadFromDisk(pblockindex, true);
1989
1990     return blockToJSON(block, pblockindex);
1991 }
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003 //
2004 // Call Table
2005 //
2006
2007 pair<string, rpcfn_type> pCallTable[] =
2008 {
2009     make_pair("help",                   &help),
2010     make_pair("stop",                   &stop),
2011     make_pair("getblockcount",          &getblockcount),
2012     make_pair("getblocknumber",         &getblocknumber),
2013     make_pair("getconnectioncount",     &getconnectioncount),
2014     make_pair("getdifficulty",          &getdifficulty),
2015     make_pair("getgenerate",            &getgenerate),
2016     make_pair("setgenerate",            &setgenerate),
2017     make_pair("gethashespersec",        &gethashespersec),
2018     make_pair("getinfo",                &getinfo),
2019     make_pair("getmininginfo",          &getmininginfo),
2020     make_pair("getnewaddress",          &getnewaddress),
2021     make_pair("getaccountaddress",      &getaccountaddress),
2022     make_pair("setaccount",             &setaccount),
2023     make_pair("getaccount",             &getaccount),
2024     make_pair("getaddressesbyaccount",  &getaddressesbyaccount),
2025     make_pair("sendtoaddress",          &sendtoaddress),
2026     make_pair("getreceivedbyaddress",   &getreceivedbyaddress),
2027     make_pair("getreceivedbyaccount",   &getreceivedbyaccount),
2028     make_pair("listreceivedbyaddress",  &listreceivedbyaddress),
2029     make_pair("listreceivedbyaccount",  &listreceivedbyaccount),
2030     make_pair("backupwallet",           &backupwallet),
2031     make_pair("keypoolrefill",          &keypoolrefill),
2032     make_pair("walletpassphrase",       &walletpassphrase),
2033     make_pair("walletpassphrasechange", &walletpassphrasechange),
2034     make_pair("walletlock",             &walletlock),
2035     make_pair("encryptwallet",          &encryptwallet),
2036     make_pair("validateaddress",        &validateaddress),
2037     make_pair("getbalance",             &getbalance),
2038     make_pair("move",                   &movecmd),
2039     make_pair("sendfrom",               &sendfrom),
2040     make_pair("sendmany",               &sendmany),
2041     make_pair("addmultisigaddress",     &addmultisigaddress),
2042     make_pair("getblock",               &getblock),
2043     make_pair("getblockhash",           &getblockhash),
2044     make_pair("gettransaction",         &gettransaction),
2045     make_pair("listtransactions",       &listtransactions),
2046     make_pair("signmessage",            &signmessage),
2047     make_pair("verifymessage",          &verifymessage),
2048     make_pair("getwork",                &getwork),
2049     make_pair("listaccounts",           &listaccounts),
2050     make_pair("settxfee",               &settxfee),
2051     make_pair("getmemorypool",          &getmemorypool),
2052     make_pair("listsinceblock",         &listsinceblock),
2053     make_pair("dumpprivkey",            &dumpprivkey),
2054     make_pair("importprivkey",          &importprivkey)
2055 };
2056 map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
2057
2058 string pAllowInSafeMode[] =
2059 {
2060     "help",
2061     "stop",
2062     "getblockcount",
2063     "getblocknumber",  // deprecated
2064     "getconnectioncount",
2065     "getdifficulty",
2066     "getgenerate",
2067     "setgenerate",
2068     "gethashespersec",
2069     "getinfo",
2070     "getmininginfo",
2071     "getnewaddress",
2072     "getaccountaddress",
2073     "getaccount",
2074     "getaddressesbyaccount",
2075     "backupwallet",
2076     "keypoolrefill",
2077     "walletpassphrase",
2078     "walletlock",
2079     "validateaddress",
2080     "getwork",
2081     "getmemorypool",
2082 };
2083 set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
2084
2085
2086
2087
2088 //
2089 // HTTP protocol
2090 //
2091 // This ain't Apache.  We're just using HTTP header for the length field
2092 // and to be compatible with other JSON-RPC implementations.
2093 //
2094
2095 string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders)
2096 {
2097     ostringstream s;
2098     s << "POST / HTTP/1.1\r\n"
2099       << "User-Agent: bitcoin-json-rpc/" << FormatFullVersion() << "\r\n"
2100       << "Host: 127.0.0.1\r\n"
2101       << "Content-Type: application/json\r\n"
2102       << "Content-Length: " << strMsg.size() << "\r\n"
2103       << "Connection: close\r\n"
2104       << "Accept: application/json\r\n";
2105     BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders)
2106         s << item.first << ": " << item.second << "\r\n";
2107     s << "\r\n" << strMsg;
2108
2109     return s.str();
2110 }
2111
2112 string rfc1123Time()
2113 {
2114     char buffer[64];
2115     time_t now;
2116     time(&now);
2117     struct tm* now_gmt = gmtime(&now);
2118     string locale(setlocale(LC_TIME, NULL));
2119     setlocale(LC_TIME, "C"); // we want posix (aka "C") weekday/month strings
2120     strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt);
2121     setlocale(LC_TIME, locale.c_str());
2122     return string(buffer);
2123 }
2124
2125 static string HTTPReply(int nStatus, const string& strMsg)
2126 {
2127     if (nStatus == 401)
2128         return strprintf("HTTP/1.0 401 Authorization Required\r\n"
2129             "Date: %s\r\n"
2130             "Server: bitcoin-json-rpc/%s\r\n"
2131             "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
2132             "Content-Type: text/html\r\n"
2133             "Content-Length: 296\r\n"
2134             "\r\n"
2135             "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
2136             "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
2137             "<HTML>\r\n"
2138             "<HEAD>\r\n"
2139             "<TITLE>Error</TITLE>\r\n"
2140             "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
2141             "</HEAD>\r\n"
2142             "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
2143             "</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
2144     const char *cStatus;
2145          if (nStatus == 200) cStatus = "OK";
2146     else if (nStatus == 400) cStatus = "Bad Request";
2147     else if (nStatus == 403) cStatus = "Forbidden";
2148     else if (nStatus == 404) cStatus = "Not Found";
2149     else if (nStatus == 500) cStatus = "Internal Server Error";
2150     else cStatus = "";
2151     return strprintf(
2152             "HTTP/1.1 %d %s\r\n"
2153             "Date: %s\r\n"
2154             "Connection: close\r\n"
2155             "Content-Length: %d\r\n"
2156             "Content-Type: application/json\r\n"
2157             "Server: bitcoin-json-rpc/%s\r\n"
2158             "\r\n"
2159             "%s",
2160         nStatus,
2161         cStatus,
2162         rfc1123Time().c_str(),
2163         strMsg.size(),
2164         FormatFullVersion().c_str(),
2165         strMsg.c_str());
2166 }
2167
2168 int ReadHTTPStatus(std::basic_istream<char>& stream)
2169 {
2170     string str;
2171     getline(stream, str);
2172     vector<string> vWords;
2173     boost::split(vWords, str, boost::is_any_of(" "));
2174     if (vWords.size() < 2)
2175         return 500;
2176     return atoi(vWords[1].c_str());
2177 }
2178
2179 int ReadHTTPHeader(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
2180 {
2181     int nLen = 0;
2182     loop
2183     {
2184         string str;
2185         std::getline(stream, str);
2186         if (str.empty() || str == "\r")
2187             break;
2188         string::size_type nColon = str.find(":");
2189         if (nColon != string::npos)
2190         {
2191             string strHeader = str.substr(0, nColon);
2192             boost::trim(strHeader);
2193             boost::to_lower(strHeader);
2194             string strValue = str.substr(nColon+1);
2195             boost::trim(strValue);
2196             mapHeadersRet[strHeader] = strValue;
2197             if (strHeader == "content-length")
2198                 nLen = atoi(strValue.c_str());
2199         }
2200     }
2201     return nLen;
2202 }
2203
2204 int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
2205 {
2206     mapHeadersRet.clear();
2207     strMessageRet = "";
2208
2209     // Read status
2210     int nStatus = ReadHTTPStatus(stream);
2211
2212     // Read header
2213     int nLen = ReadHTTPHeader(stream, mapHeadersRet);
2214     if (nLen < 0 || nLen > MAX_SIZE)
2215         return 500;
2216
2217     // Read message
2218     if (nLen > 0)
2219     {
2220         vector<char> vch(nLen);
2221         stream.read(&vch[0], nLen);
2222         strMessageRet = string(vch.begin(), vch.end());
2223     }
2224
2225     return nStatus;
2226 }
2227
2228 bool HTTPAuthorized(map<string, string>& mapHeaders)
2229 {
2230     string strAuth = mapHeaders["authorization"];
2231     if (strAuth.substr(0,6) != "Basic ")
2232         return false;
2233     string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
2234     string strUserPass = DecodeBase64(strUserPass64);
2235     return strUserPass == strRPCUserColonPass;
2236 }
2237
2238 //
2239 // JSON-RPC protocol.  Bitcoin speaks version 1.0 for maximum compatibility,
2240 // but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
2241 // unspecified (HTTP errors and contents of 'error').
2242 //
2243 // 1.0 spec: http://json-rpc.org/wiki/specification
2244 // 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http
2245 // http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
2246 //
2247
2248 string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
2249 {
2250     Object request;
2251     request.push_back(Pair("method", strMethod));
2252     request.push_back(Pair("params", params));
2253     request.push_back(Pair("id", id));
2254     return write_string(Value(request), false) + "\n";
2255 }
2256
2257 string JSONRPCReply(const Value& result, const Value& error, const Value& id)
2258 {
2259     Object reply;
2260     if (error.type() != null_type)
2261         reply.push_back(Pair("result", Value::null));
2262     else
2263         reply.push_back(Pair("result", result));
2264     reply.push_back(Pair("error", error));
2265     reply.push_back(Pair("id", id));
2266     return write_string(Value(reply), false) + "\n";
2267 }
2268
2269 void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
2270 {
2271     // Send error reply from json-rpc error object
2272     int nStatus = 500;
2273     int code = find_value(objError, "code").get_int();
2274     if (code == -32600) nStatus = 400;
2275     else if (code == -32601) nStatus = 404;
2276     string strReply = JSONRPCReply(Value::null, objError, id);
2277     stream << HTTPReply(nStatus, strReply) << std::flush;
2278 }
2279
2280 bool ClientAllowed(const string& strAddress)
2281 {
2282     if (strAddress == asio::ip::address_v4::loopback().to_string())
2283         return true;
2284     const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
2285     BOOST_FOREACH(string strAllow, vAllow)
2286         if (WildcardMatch(strAddress, strAllow))
2287             return true;
2288     return false;
2289 }
2290
2291 #ifdef USE_SSL
2292 //
2293 // IOStream device that speaks SSL but can also speak non-SSL
2294 //
2295 class SSLIOStreamDevice : public iostreams::device<iostreams::bidirectional> {
2296 public:
2297     SSLIOStreamDevice(SSLStream &streamIn, bool fUseSSLIn) : stream(streamIn)
2298     {
2299         fUseSSL = fUseSSLIn;
2300         fNeedHandshake = fUseSSLIn;
2301     }
2302
2303     void handshake(ssl::stream_base::handshake_type role)
2304     {
2305         if (!fNeedHandshake) return;
2306         fNeedHandshake = false;
2307         stream.handshake(role);
2308     }
2309     std::streamsize read(char* s, std::streamsize n)
2310     {
2311         handshake(ssl::stream_base::server); // HTTPS servers read first
2312         if (fUseSSL) return stream.read_some(asio::buffer(s, n));
2313         return stream.next_layer().read_some(asio::buffer(s, n));
2314     }
2315     std::streamsize write(const char* s, std::streamsize n)
2316     {
2317         handshake(ssl::stream_base::client); // HTTPS clients write first
2318         if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
2319         return asio::write(stream.next_layer(), asio::buffer(s, n));
2320     }
2321     bool connect(const std::string& server, const std::string& port)
2322     {
2323         ip::tcp::resolver resolver(stream.get_io_service());
2324         ip::tcp::resolver::query query(server.c_str(), port.c_str());
2325         ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
2326         ip::tcp::resolver::iterator end;
2327         boost::system::error_code error = asio::error::host_not_found;
2328         while (error && endpoint_iterator != end)
2329         {
2330             stream.lowest_layer().close();
2331             stream.lowest_layer().connect(*endpoint_iterator++, error);
2332         }
2333         if (error)
2334             return false;
2335         return true;
2336     }
2337
2338 private:
2339     bool fNeedHandshake;
2340     bool fUseSSL;
2341     SSLStream& stream;
2342 };
2343 #endif
2344
2345 void ThreadRPCServer(void* parg)
2346 {
2347     IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
2348     try
2349     {
2350         vnThreadsRunning[4]++;
2351         ThreadRPCServer2(parg);
2352         vnThreadsRunning[4]--;
2353     }
2354     catch (std::exception& e) {
2355         vnThreadsRunning[4]--;
2356         PrintException(&e, "ThreadRPCServer()");
2357     } catch (...) {
2358         vnThreadsRunning[4]--;
2359         PrintException(NULL, "ThreadRPCServer()");
2360     }
2361     printf("ThreadRPCServer exiting\n");
2362 }
2363
2364 void ThreadRPCServer2(void* parg)
2365 {
2366     printf("ThreadRPCServer started\n");
2367
2368     strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
2369     if (mapArgs["-rpcpassword"] == "")
2370     {
2371         unsigned char rand_pwd[32];
2372         RAND_bytes(rand_pwd, 32);
2373         string strWhatAmI = "To use bitcoind";
2374         if (mapArgs.count("-server"))
2375             strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
2376         else if (mapArgs.count("-daemon"))
2377             strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
2378         PrintConsole(
2379             _("Error: %s, you must set a rpcpassword in the configuration file:\n %s\n"
2380               "It is recommended you use the following random password:\n"
2381               "rpcuser=bitcoinrpc\n"
2382               "rpcpassword=%s\n"
2383               "(you do not need to remember this password)\n"
2384               "If the file does not exist, create it with owner-readable-only file permissions.\n"),
2385                 strWhatAmI.c_str(),
2386                 GetConfigFile().c_str(),
2387                 EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str());
2388 #ifndef QT_GUI
2389         CreateThread(Shutdown, NULL);
2390 #endif
2391         return;
2392     }
2393
2394     bool fUseSSL = GetBoolArg("-rpcssl");
2395     asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback();
2396
2397     asio::io_service io_service;
2398     ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
2399     ip::tcp::acceptor acceptor(io_service, endpoint);
2400
2401     acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
2402
2403 #ifdef USE_SSL
2404     ssl::context context(io_service, ssl::context::sslv23);
2405     if (fUseSSL)
2406     {
2407         context.set_options(ssl::context::no_sslv2);
2408         filesystem::path certfile = GetArg("-rpcsslcertificatechainfile", "server.cert");
2409         if (!certfile.is_complete()) certfile = filesystem::path(GetDataDir()) / certfile;
2410         if (filesystem::exists(certfile)) context.use_certificate_chain_file(certfile.string().c_str());
2411         else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", certfile.string().c_str());
2412         filesystem::path pkfile = GetArg("-rpcsslprivatekeyfile", "server.pem");
2413         if (!pkfile.is_complete()) pkfile = filesystem::path(GetDataDir()) / pkfile;
2414         if (filesystem::exists(pkfile)) context.use_private_key_file(pkfile.string().c_str(), ssl::context::pem);
2415         else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pkfile.string().c_str());
2416
2417         string ciphers = GetArg("-rpcsslciphers",
2418                                          "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
2419         SSL_CTX_set_cipher_list(context.impl(), ciphers.c_str());
2420     }
2421 #else
2422     if (fUseSSL)
2423         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2424 #endif
2425
2426     loop
2427     {
2428         // Accept connection
2429 #ifdef USE_SSL
2430         SSLStream sslStream(io_service, context);
2431         SSLIOStreamDevice d(sslStream, fUseSSL);
2432         iostreams::stream<SSLIOStreamDevice> stream(d);
2433 #else
2434         ip::tcp::iostream stream;
2435 #endif
2436
2437         ip::tcp::endpoint peer;
2438         vnThreadsRunning[4]--;
2439 #ifdef USE_SSL
2440         acceptor.accept(sslStream.lowest_layer(), peer);
2441 #else
2442         acceptor.accept(*stream.rdbuf(), peer);
2443 #endif
2444         vnThreadsRunning[4]++;
2445         if (fShutdown)
2446             return;
2447
2448         // Restrict callers by IP
2449         if (!ClientAllowed(peer.address().to_string()))
2450         {
2451             // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
2452             if (!fUseSSL)
2453                 stream << HTTPReply(403, "") << std::flush;
2454             continue;
2455         }
2456
2457         map<string, string> mapHeaders;
2458         string strRequest;
2459
2460         boost::thread api_caller(ReadHTTP, boost::ref(stream), boost::ref(mapHeaders), boost::ref(strRequest));
2461         if (!api_caller.timed_join(boost::posix_time::seconds(GetArg("-rpctimeout", 30))))
2462         {   // Timed out:
2463             acceptor.cancel();
2464             printf("ThreadRPCServer ReadHTTP timeout\n");
2465             continue;
2466         }
2467
2468         // Check authorization
2469         if (mapHeaders.count("authorization") == 0)
2470         {
2471             stream << HTTPReply(401, "") << std::flush;
2472             continue;
2473         }
2474         if (!HTTPAuthorized(mapHeaders))
2475         {
2476             printf("ThreadRPCServer incorrect password attempt from %s\n",peer.address().to_string().c_str());
2477             /* Deter brute-forcing short passwords.
2478                If this results in a DOS the user really
2479                shouldn't have their RPC port exposed.*/
2480             if (mapArgs["-rpcpassword"].size() < 20)
2481                 Sleep(250);
2482
2483             stream << HTTPReply(401, "") << std::flush;
2484             continue;
2485         }
2486
2487         Value id = Value::null;
2488         try
2489         {
2490             // Parse request
2491             Value valRequest;
2492             if (!read_string(strRequest, valRequest) || valRequest.type() != obj_type)
2493                 throw JSONRPCError(-32700, "Parse error");
2494             const Object& request = valRequest.get_obj();
2495
2496             // Parse id now so errors from here on will have the id
2497             id = find_value(request, "id");
2498
2499             // Parse method
2500             Value valMethod = find_value(request, "method");
2501             if (valMethod.type() == null_type)
2502                 throw JSONRPCError(-32600, "Missing method");
2503             if (valMethod.type() != str_type)
2504                 throw JSONRPCError(-32600, "Method must be a string");
2505             string strMethod = valMethod.get_str();
2506             if (strMethod != "getwork" && strMethod != "getmemorypool")
2507                 printf("ThreadRPCServer method=%s\n", strMethod.c_str());
2508
2509             // Parse params
2510             Value valParams = find_value(request, "params");
2511             Array params;
2512             if (valParams.type() == array_type)
2513                 params = valParams.get_array();
2514             else if (valParams.type() == null_type)
2515                 params = Array();
2516             else
2517                 throw JSONRPCError(-32600, "Params must be an array");
2518
2519             // Find method
2520             map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
2521             if (mi == mapCallTable.end())
2522                 throw JSONRPCError(-32601, "Method not found");
2523
2524             // Observe safe mode
2525             string strWarning = GetWarnings("rpc");
2526             if (strWarning != "" && !GetBoolArg("-disablesafemode") && !setAllowInSafeMode.count(strMethod))
2527                 throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
2528
2529             try
2530             {
2531                 // Execute
2532                 Value result;
2533                 CRITICAL_BLOCK(cs_main)
2534                 CRITICAL_BLOCK(pwalletMain->cs_wallet)
2535                     result = (*(*mi).second)(params, false);
2536
2537                 // Send reply
2538                 string strReply = JSONRPCReply(result, Value::null, id);
2539                 stream << HTTPReply(200, strReply) << std::flush;
2540             }
2541             catch (std::exception& e)
2542             {
2543                 ErrorReply(stream, JSONRPCError(-1, e.what()), id);
2544             }
2545         }
2546         catch (Object& objError)
2547         {
2548             ErrorReply(stream, objError, id);
2549         }
2550         catch (std::exception& e)
2551         {
2552             ErrorReply(stream, JSONRPCError(-32700, e.what()), id);
2553         }
2554     }
2555 }
2556
2557
2558
2559
2560 Object CallRPC(const string& strMethod, const Array& params)
2561 {
2562     if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
2563         throw runtime_error(strprintf(
2564             _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
2565               "If the file does not exist, create it with owner-readable-only file permissions."),
2566                 GetConfigFile().c_str()));
2567
2568     // Connect to localhost
2569     bool fUseSSL = GetBoolArg("-rpcssl");
2570 #ifdef USE_SSL
2571     asio::io_service io_service;
2572     ssl::context context(io_service, ssl::context::sslv23);
2573     context.set_options(ssl::context::no_sslv2);
2574     SSLStream sslStream(io_service, context);
2575     SSLIOStreamDevice d(sslStream, fUseSSL);
2576     iostreams::stream<SSLIOStreamDevice> stream(d);
2577     if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332")))
2578         throw runtime_error("couldn't connect to server");
2579 #else
2580     if (fUseSSL)
2581         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2582
2583     ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332"));
2584     if (stream.fail())
2585         throw runtime_error("couldn't connect to server");
2586 #endif
2587
2588
2589     // HTTP basic authentication
2590     string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
2591     map<string, string> mapRequestHeaders;
2592     mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
2593
2594     // Send request
2595     string strRequest = JSONRPCRequest(strMethod, params, 1);
2596     string strPost = HTTPPost(strRequest, mapRequestHeaders);
2597     stream << strPost << std::flush;
2598
2599     // Receive reply
2600     map<string, string> mapHeaders;
2601     string strReply;
2602     int nStatus = ReadHTTP(stream, mapHeaders, strReply);
2603     if (nStatus == 401)
2604         throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
2605     else if (nStatus >= 400 && nStatus != 400 && nStatus != 404 && nStatus != 500)
2606         throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
2607     else if (strReply.empty())
2608         throw runtime_error("no response from server");
2609
2610     // Parse reply
2611     Value valReply;
2612     if (!read_string(strReply, valReply))
2613         throw runtime_error("couldn't parse reply from server");
2614     const Object& reply = valReply.get_obj();
2615     if (reply.empty())
2616         throw runtime_error("expected reply to have result, error and id properties");
2617
2618     return reply;
2619 }
2620
2621
2622
2623
2624 template<typename T>
2625 void ConvertTo(Value& value)
2626 {
2627     if (value.type() == str_type)
2628     {
2629         // reinterpret string as unquoted json value
2630         Value value2;
2631         if (!read_string(value.get_str(), value2))
2632             throw runtime_error("type mismatch");
2633         value = value2.get_value<T>();
2634     }
2635     else
2636     {
2637         value = value.get_value<T>();
2638     }
2639 }
2640
2641 int CommandLineRPC(int argc, char *argv[])
2642 {
2643     string strPrint;
2644     int nRet = 0;
2645     try
2646     {
2647         // Skip switches
2648         while (argc > 1 && IsSwitchChar(argv[1][0]))
2649         {
2650             argc--;
2651             argv++;
2652         }
2653
2654         // Method
2655         if (argc < 2)
2656             throw runtime_error("too few parameters");
2657         string strMethod = argv[1];
2658
2659         // Parameters default to strings
2660         Array params;
2661         for (int i = 2; i < argc; i++)
2662             params.push_back(argv[i]);
2663         int n = params.size();
2664
2665         //
2666         // Special case non-string parameter types
2667         //
2668         if (strMethod == "setgenerate"            && n > 0) ConvertTo<bool>(params[0]);
2669         if (strMethod == "setgenerate"            && n > 1) ConvertTo<boost::int64_t>(params[1]);
2670         if (strMethod == "sendtoaddress"          && n > 1) ConvertTo<double>(params[1]);
2671         if (strMethod == "settxfee"               && n > 0) ConvertTo<double>(params[0]);
2672         if (strMethod == "getreceivedbyaddress"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2673         if (strMethod == "getreceivedbyaccount"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2674         if (strMethod == "listreceivedbyaddress"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2675         if (strMethod == "listreceivedbyaddress"  && n > 1) ConvertTo<bool>(params[1]);
2676         if (strMethod == "listreceivedbyaccount"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2677         if (strMethod == "listreceivedbyaccount"  && n > 1) ConvertTo<bool>(params[1]);
2678         if (strMethod == "getbalance"             && n > 1) ConvertTo<boost::int64_t>(params[1]);
2679         if (strMethod == "getblockhash"           && n > 0) ConvertTo<boost::int64_t>(params[0]);
2680         if (strMethod == "move"                   && n > 2) ConvertTo<double>(params[2]);
2681         if (strMethod == "move"                   && n > 3) ConvertTo<boost::int64_t>(params[3]);
2682         if (strMethod == "sendfrom"               && n > 2) ConvertTo<double>(params[2]);
2683         if (strMethod == "sendfrom"               && n > 3) ConvertTo<boost::int64_t>(params[3]);
2684         if (strMethod == "listtransactions"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2685         if (strMethod == "listtransactions"       && n > 2) ConvertTo<boost::int64_t>(params[2]);
2686         if (strMethod == "listaccounts"           && n > 0) ConvertTo<boost::int64_t>(params[0]);
2687         if (strMethod == "walletpassphrase"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2688         if (strMethod == "listsinceblock"         && n > 1) ConvertTo<boost::int64_t>(params[1]);
2689         if (strMethod == "sendmany"               && n > 1)
2690         {
2691             string s = params[1].get_str();
2692             Value v;
2693             if (!read_string(s, v) || v.type() != obj_type)
2694                 throw runtime_error("type mismatch");
2695             params[1] = v.get_obj();
2696         }
2697         if (strMethod == "sendmany"                && n > 2) ConvertTo<boost::int64_t>(params[2]);
2698         if (strMethod == "addmultisigaddress"      && n > 0) ConvertTo<boost::int64_t>(params[0]);
2699         if (strMethod == "addmultisigaddress"      && n > 1)
2700         {
2701             string s = params[1].get_str();
2702             Value v;
2703             if (!read_string(s, v) || v.type() != array_type)
2704                 throw runtime_error("type mismatch "+s);
2705             params[1] = v.get_array();
2706         }
2707
2708         // Execute
2709         Object reply = CallRPC(strMethod, params);
2710
2711         // Parse reply
2712         const Value& result = find_value(reply, "result");
2713         const Value& error  = find_value(reply, "error");
2714
2715         if (error.type() != null_type)
2716         {
2717             // Error
2718             strPrint = "error: " + write_string(error, false);
2719             int code = find_value(error.get_obj(), "code").get_int();
2720             nRet = abs(code);
2721         }
2722         else
2723         {
2724             // Result
2725             if (result.type() == null_type)
2726                 strPrint = "";
2727             else if (result.type() == str_type)
2728                 strPrint = result.get_str();
2729             else
2730                 strPrint = write_string(result, true);
2731         }
2732     }
2733     catch (std::exception& e)
2734     {
2735         strPrint = string("error: ") + e.what();
2736         nRet = 87;
2737     }
2738     catch (...)
2739     {
2740         PrintException(NULL, "CommandLineRPC()");
2741     }
2742
2743     if (strPrint != "")
2744     {
2745         fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
2746     }
2747     return nRet;
2748 }
2749
2750
2751
2752
2753 #ifdef TEST
2754 int main(int argc, char *argv[])
2755 {
2756 #ifdef _MSC_VER
2757     // Turn off microsoft heap dump noise
2758     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
2759     _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
2760 #endif
2761     setbuf(stdin, NULL);
2762     setbuf(stdout, NULL);
2763     setbuf(stderr, NULL);
2764
2765     try
2766     {
2767         if (argc >= 2 && string(argv[1]) == "-server")
2768         {
2769             printf("server ready\n");
2770             ThreadRPCServer(NULL);
2771         }
2772         else
2773         {
2774             return CommandLineRPC(argc, argv);
2775         }
2776     }
2777     catch (std::exception& e) {
2778         PrintException(&e, "main()");
2779     } catch (...) {
2780         PrintException(NULL, "main()");
2781     }
2782     return 0;
2783 }
2784 #endif