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