Fixed addmultisigaddress if looking up public keys from locked wallets.
[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 or hex-encoded 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             std::vector<unsigned char> vchPubKey;
1029             if (!pwalletMain->GetPubKey(address, vchPubKey))
1030                 throw runtime_error(
1031                     strprintf("no full public key for address %s",ks.c_str()));
1032             if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey))
1033                 throw runtime_error(" Invalid public key: "+ks);
1034         }
1035
1036         // Case 2: hex public key
1037         else if (IsHex(ks))
1038         {
1039             vector<unsigned char> vchPubKey = ParseHex(ks);
1040             if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey))
1041                 throw runtime_error(" Invalid public key: "+ks);
1042         }
1043         else
1044         {
1045             throw runtime_error(" Invalid public key: "+ks);
1046         }
1047     }
1048
1049     // Construct using pay-to-script-hash:
1050     CScript inner;
1051     inner.SetMultisig(nRequired, pubkeys);
1052
1053     uint160 scriptHash = Hash160(inner);
1054     CScript scriptPubKey;
1055     scriptPubKey.SetPayToScriptHash(inner);
1056     pwalletMain->AddCScript(inner);
1057     CBitcoinAddress address;
1058     address.SetScriptHash160(scriptHash);
1059
1060     pwalletMain->SetAddressBookName(address, strAccount);
1061     return address.ToString();
1062 }
1063
1064
1065 struct tallyitem
1066 {
1067     int64 nAmount;
1068     int nConf;
1069     tallyitem()
1070     {
1071         nAmount = 0;
1072         nConf = std::numeric_limits<int>::max();
1073     }
1074 };
1075
1076 Value ListReceived(const Array& params, bool fByAccounts)
1077 {
1078     // Minimum confirmations
1079     int nMinDepth = 1;
1080     if (params.size() > 0)
1081         nMinDepth = params[0].get_int();
1082
1083     // Whether to include empty accounts
1084     bool fIncludeEmpty = false;
1085     if (params.size() > 1)
1086         fIncludeEmpty = params[1].get_bool();
1087
1088     // Tally
1089     map<CBitcoinAddress, tallyitem> mapTally;
1090     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1091     {
1092         const CWalletTx& wtx = (*it).second;
1093
1094         if (wtx.IsCoinBase() || !wtx.IsFinal())
1095             continue;
1096
1097         int nDepth = wtx.GetDepthInMainChain();
1098         if (nDepth < nMinDepth)
1099             continue;
1100
1101         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
1102         {
1103             CBitcoinAddress address;
1104             if (!ExtractAddress(txout.scriptPubKey, address) || !pwalletMain->HaveKey(address) || !address.IsValid())
1105                 continue;
1106
1107             tallyitem& item = mapTally[address];
1108             item.nAmount += txout.nValue;
1109             item.nConf = min(item.nConf, nDepth);
1110         }
1111     }
1112
1113     // Reply
1114     Array ret;
1115     map<string, tallyitem> mapAccountTally;
1116     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
1117     {
1118         const CBitcoinAddress& address = item.first;
1119         const string& strAccount = item.second;
1120         map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
1121         if (it == mapTally.end() && !fIncludeEmpty)
1122             continue;
1123
1124         int64 nAmount = 0;
1125         int nConf = std::numeric_limits<int>::max();
1126         if (it != mapTally.end())
1127         {
1128             nAmount = (*it).second.nAmount;
1129             nConf = (*it).second.nConf;
1130         }
1131
1132         if (fByAccounts)
1133         {
1134             tallyitem& item = mapAccountTally[strAccount];
1135             item.nAmount += nAmount;
1136             item.nConf = min(item.nConf, nConf);
1137         }
1138         else
1139         {
1140             Object obj;
1141             obj.push_back(Pair("address",       address.ToString()));
1142             obj.push_back(Pair("account",       strAccount));
1143             obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
1144             obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1145             ret.push_back(obj);
1146         }
1147     }
1148
1149     if (fByAccounts)
1150     {
1151         for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
1152         {
1153             int64 nAmount = (*it).second.nAmount;
1154             int nConf = (*it).second.nConf;
1155             Object obj;
1156             obj.push_back(Pair("account",       (*it).first));
1157             obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
1158             obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1159             ret.push_back(obj);
1160         }
1161     }
1162
1163     return ret;
1164 }
1165
1166 Value listreceivedbyaddress(const Array& params, bool fHelp)
1167 {
1168     if (fHelp || params.size() > 2)
1169         throw runtime_error(
1170             "listreceivedbyaddress [minconf=1] [includeempty=false]\n"
1171             "[minconf] is the minimum number of confirmations before payments are included.\n"
1172             "[includeempty] whether to include addresses that haven't received any payments.\n"
1173             "Returns an array of objects containing:\n"
1174             "  \"address\" : receiving address\n"
1175             "  \"account\" : the account of the receiving address\n"
1176             "  \"amount\" : total amount received by the address\n"
1177             "  \"confirmations\" : number of confirmations of the most recent transaction included");
1178
1179     return ListReceived(params, false);
1180 }
1181
1182 Value listreceivedbyaccount(const Array& params, bool fHelp)
1183 {
1184     if (fHelp || params.size() > 2)
1185         throw runtime_error(
1186             "listreceivedbyaccount [minconf=1] [includeempty=false]\n"
1187             "[minconf] is the minimum number of confirmations before payments are included.\n"
1188             "[includeempty] whether to include accounts that haven't received any payments.\n"
1189             "Returns an array of objects containing:\n"
1190             "  \"account\" : the account of the receiving addresses\n"
1191             "  \"amount\" : total amount received by addresses with this account\n"
1192             "  \"confirmations\" : number of confirmations of the most recent transaction included");
1193
1194     return ListReceived(params, true);
1195 }
1196
1197 void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
1198 {
1199     int64 nGeneratedImmature, nGeneratedMature, nFee;
1200     string strSentAccount;
1201     list<pair<CBitcoinAddress, int64> > listReceived;
1202     list<pair<CBitcoinAddress, int64> > listSent;
1203
1204     wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
1205
1206     bool fAllAccounts = (strAccount == string("*"));
1207
1208     // Generated blocks assigned to account ""
1209     if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount == ""))
1210     {
1211         Object entry;
1212         entry.push_back(Pair("account", string("")));
1213         if (nGeneratedImmature)
1214         {
1215             entry.push_back(Pair("category", wtx.GetDepthInMainChain() ? "immature" : "orphan"));
1216             entry.push_back(Pair("amount", ValueFromAmount(nGeneratedImmature)));
1217         }
1218         else
1219         {
1220             entry.push_back(Pair("category", "generate"));
1221             entry.push_back(Pair("amount", ValueFromAmount(nGeneratedMature)));
1222         }
1223         if (fLong)
1224             WalletTxToJSON(wtx, entry);
1225         ret.push_back(entry);
1226     }
1227
1228     // Sent
1229     if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1230     {
1231         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
1232         {
1233             Object entry;
1234             entry.push_back(Pair("account", strSentAccount));
1235             entry.push_back(Pair("address", s.first.ToString()));
1236             entry.push_back(Pair("category", "send"));
1237             entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
1238             entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1239             if (fLong)
1240                 WalletTxToJSON(wtx, entry);
1241             ret.push_back(entry);
1242         }
1243     }
1244
1245     // Received
1246     if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1247         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
1248         {
1249             string account;
1250             if (pwalletMain->mapAddressBook.count(r.first))
1251                 account = pwalletMain->mapAddressBook[r.first];
1252             if (fAllAccounts || (account == strAccount))
1253             {
1254                 Object entry;
1255                 entry.push_back(Pair("account", account));
1256                 entry.push_back(Pair("address", r.first.ToString()));
1257                 entry.push_back(Pair("category", "receive"));
1258                 entry.push_back(Pair("amount", ValueFromAmount(r.second)));
1259                 if (fLong)
1260                     WalletTxToJSON(wtx, entry);
1261                 ret.push_back(entry);
1262             }
1263         }
1264 }
1265
1266 void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret)
1267 {
1268     bool fAllAccounts = (strAccount == string("*"));
1269
1270     if (fAllAccounts || acentry.strAccount == strAccount)
1271     {
1272         Object entry;
1273         entry.push_back(Pair("account", acentry.strAccount));
1274         entry.push_back(Pair("category", "move"));
1275         entry.push_back(Pair("time", (boost::int64_t)acentry.nTime));
1276         entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1277         entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1278         entry.push_back(Pair("comment", acentry.strComment));
1279         ret.push_back(entry);
1280     }
1281 }
1282
1283 Value listtransactions(const Array& params, bool fHelp)
1284 {
1285     if (fHelp || params.size() > 3)
1286         throw runtime_error(
1287             "listtransactions [account] [count=10] [from=0]\n"
1288             "Returns up to [count] most recent transactions skipping the first [from] transactions for account [account].");
1289
1290     string strAccount = "*";
1291     if (params.size() > 0)
1292         strAccount = params[0].get_str();
1293     int nCount = 10;
1294     if (params.size() > 1)
1295         nCount = params[1].get_int();
1296     int nFrom = 0;
1297     if (params.size() > 2)
1298         nFrom = params[2].get_int();
1299
1300     Array ret;
1301     CWalletDB walletdb(pwalletMain->strWalletFile);
1302
1303     // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
1304     typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
1305     typedef multimap<int64, TxPair > TxItems;
1306     TxItems txByTime;
1307
1308     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1309     {
1310         CWalletTx* wtx = &((*it).second);
1311         txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
1312     }
1313     list<CAccountingEntry> acentries;
1314     walletdb.ListAccountCreditDebit(strAccount, acentries);
1315     BOOST_FOREACH(CAccountingEntry& entry, acentries)
1316     {
1317         txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry)));
1318     }
1319
1320     // Now: iterate backwards until we have nCount items to return:
1321     TxItems::reverse_iterator it = txByTime.rbegin();
1322     if (txByTime.size() > nFrom) std::advance(it, nFrom);
1323     for (; it != txByTime.rend(); ++it)
1324     {
1325         CWalletTx *const pwtx = (*it).second.first;
1326         if (pwtx != 0)
1327             ListTransactions(*pwtx, strAccount, 0, true, ret);
1328         CAccountingEntry *const pacentry = (*it).second.second;
1329         if (pacentry != 0)
1330             AcentryToJSON(*pacentry, strAccount, ret);
1331
1332         if (ret.size() >= nCount) break;
1333     }
1334     // ret is now newest to oldest
1335     
1336     // Make sure we return only last nCount items (sends-to-self might give us an extra):
1337     if (ret.size() > nCount)
1338     {
1339         Array::iterator last = ret.begin();
1340         std::advance(last, nCount);
1341         ret.erase(last, ret.end());
1342     }
1343     std::reverse(ret.begin(), ret.end()); // oldest to newest
1344
1345     return ret;
1346 }
1347
1348 Value listaccounts(const Array& params, bool fHelp)
1349 {
1350     if (fHelp || params.size() > 1)
1351         throw runtime_error(
1352             "listaccounts [minconf=1]\n"
1353             "Returns Object that has account names as keys, account balances as values.");
1354
1355     int nMinDepth = 1;
1356     if (params.size() > 0)
1357         nMinDepth = params[0].get_int();
1358
1359     map<string, int64> mapAccountBalances;
1360     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
1361         if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
1362             mapAccountBalances[entry.second] = 0;
1363     }
1364
1365     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1366     {
1367         const CWalletTx& wtx = (*it).second;
1368         int64 nGeneratedImmature, nGeneratedMature, nFee;
1369         string strSentAccount;
1370         list<pair<CBitcoinAddress, int64> > listReceived;
1371         list<pair<CBitcoinAddress, int64> > listSent;
1372         wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
1373         mapAccountBalances[strSentAccount] -= nFee;
1374         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
1375             mapAccountBalances[strSentAccount] -= s.second;
1376         if (wtx.GetDepthInMainChain() >= nMinDepth)
1377         {
1378             mapAccountBalances[""] += nGeneratedMature;
1379             BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
1380                 if (pwalletMain->mapAddressBook.count(r.first))
1381                     mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
1382                 else
1383                     mapAccountBalances[""] += r.second;
1384         }
1385     }
1386
1387     list<CAccountingEntry> acentries;
1388     CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries);
1389     BOOST_FOREACH(const CAccountingEntry& entry, acentries)
1390         mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1391
1392     Object ret;
1393     BOOST_FOREACH(const PAIRTYPE(string, int64)& accountBalance, mapAccountBalances) {
1394         ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1395     }
1396     return ret;
1397 }
1398
1399 Value listsinceblock(const Array& params, bool fHelp)
1400 {
1401     if (fHelp)
1402         throw runtime_error(
1403             "listsinceblock [blockid] [target-confirmations]\n"
1404             "Get all transactions in blocks since block [blockid], or all transactions if omitted");
1405
1406     CBlockIndex *pindex = NULL;
1407     int target_confirms = 1;
1408
1409     if (params.size() > 0)
1410     {
1411         uint256 blockId = 0;
1412
1413         blockId.SetHex(params[0].get_str());
1414         pindex = CBlockLocator(blockId).GetBlockIndex();
1415     }
1416
1417     if (params.size() > 1)
1418     {
1419         target_confirms = params[1].get_int();
1420
1421         if (target_confirms < 1)
1422             throw JSONRPCError(-8, "Invalid parameter");
1423     }
1424
1425     int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1;
1426
1427     Array transactions;
1428
1429     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++)
1430     {
1431         CWalletTx tx = (*it).second;
1432
1433         if (depth == -1 || tx.GetDepthInMainChain() < depth)
1434             ListTransactions(tx, "*", 0, true, transactions);
1435     }
1436
1437     uint256 lastblock;
1438
1439     if (target_confirms == 1)
1440     {
1441         printf("oops!\n");
1442         lastblock = hashBestChain;
1443     }
1444     else
1445     {
1446         int target_height = pindexBest->nHeight + 1 - target_confirms;
1447
1448         CBlockIndex *block;
1449         for (block = pindexBest;
1450              block && block->nHeight > target_height;
1451              block = block->pprev)  { }
1452
1453         lastblock = block ? block->GetBlockHash() : 0;
1454     }
1455
1456     Object ret;
1457     ret.push_back(Pair("transactions", transactions));
1458     ret.push_back(Pair("lastblock", lastblock.GetHex()));
1459
1460     return ret;
1461 }
1462
1463 Value gettransaction(const Array& params, bool fHelp)
1464 {
1465     if (fHelp || params.size() != 1)
1466         throw runtime_error(
1467             "gettransaction <txid>\n"
1468             "Get detailed information about <txid>");
1469
1470     uint256 hash;
1471     hash.SetHex(params[0].get_str());
1472
1473     Object entry;
1474
1475     if (!pwalletMain->mapWallet.count(hash))
1476         throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
1477     const CWalletTx& wtx = pwalletMain->mapWallet[hash];
1478
1479     int64 nCredit = wtx.GetCredit();
1480     int64 nDebit = wtx.GetDebit();
1481     int64 nNet = nCredit - nDebit;
1482     int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
1483
1484     entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
1485     if (wtx.IsFromMe())
1486         entry.push_back(Pair("fee", ValueFromAmount(nFee)));
1487
1488     WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
1489
1490     Array details;
1491     ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
1492     entry.push_back(Pair("details", details));
1493
1494     return entry;
1495 }
1496
1497
1498 Value backupwallet(const Array& params, bool fHelp)
1499 {
1500     if (fHelp || params.size() != 1)
1501         throw runtime_error(
1502             "backupwallet <destination>\n"
1503             "Safely copies wallet.dat to destination, which can be a directory or a path with filename.");
1504
1505     string strDest = params[0].get_str();
1506     BackupWallet(*pwalletMain, strDest);
1507
1508     return Value::null;
1509 }
1510
1511
1512 Value keypoolrefill(const Array& params, bool fHelp)
1513 {
1514     if (pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
1515         throw runtime_error(
1516             "keypoolrefill\n"
1517             "Fills the keypool, requires wallet passphrase to be set.");
1518     if (!pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
1519         throw runtime_error(
1520             "keypoolrefill\n"
1521             "Fills the keypool.");
1522
1523     if (pwalletMain->IsLocked())
1524         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
1525
1526     pwalletMain->TopUpKeyPool();
1527
1528     if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100))
1529         throw JSONRPCError(-4, "Error refreshing keypool.");
1530
1531     return Value::null;
1532 }
1533
1534
1535 void ThreadTopUpKeyPool(void* parg)
1536 {
1537     pwalletMain->TopUpKeyPool();
1538 }
1539
1540 void ThreadCleanWalletPassphrase(void* parg)
1541 {
1542     int64 nMyWakeTime = GetTime() + *((int*)parg);
1543
1544     if (nWalletUnlockTime == 0)
1545     {
1546         CRITICAL_BLOCK(cs_nWalletUnlockTime)
1547         {
1548             nWalletUnlockTime = nMyWakeTime;
1549         }
1550
1551         while (GetTime() < nWalletUnlockTime)
1552             Sleep(GetTime() - nWalletUnlockTime);
1553
1554         CRITICAL_BLOCK(cs_nWalletUnlockTime)
1555         {
1556             nWalletUnlockTime = 0;
1557         }
1558     }
1559     else
1560     {
1561         CRITICAL_BLOCK(cs_nWalletUnlockTime)
1562         {
1563             if (nWalletUnlockTime < nMyWakeTime)
1564                 nWalletUnlockTime = nMyWakeTime;
1565         }
1566         free(parg);
1567         return;
1568     }
1569
1570     pwalletMain->Lock();
1571
1572     delete (int*)parg;
1573 }
1574
1575 Value walletpassphrase(const Array& params, bool fHelp)
1576 {
1577     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1578         throw runtime_error(
1579             "walletpassphrase <passphrase> <timeout>\n"
1580             "Stores the wallet decryption key in memory for <timeout> seconds.");
1581     if (fHelp)
1582         return true;
1583     if (!pwalletMain->IsCrypted())
1584         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
1585
1586     if (!pwalletMain->IsLocked())
1587         throw JSONRPCError(-17, "Error: Wallet is already unlocked.");
1588
1589     // Note that the walletpassphrase is stored in params[0] which is not mlock()ed
1590     SecureString strWalletPass;
1591     strWalletPass.reserve(100);
1592     // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1593     // Alternately, find a way to make params[0] mlock()'d to begin with.
1594     strWalletPass = params[0].get_str().c_str();
1595
1596     if (strWalletPass.length() > 0)
1597     {
1598         if (!pwalletMain->Unlock(strWalletPass))
1599             throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
1600     }
1601     else
1602         throw runtime_error(
1603             "walletpassphrase <passphrase> <timeout>\n"
1604             "Stores the wallet decryption key in memory for <timeout> seconds.");
1605
1606     CreateThread(ThreadTopUpKeyPool, NULL);
1607     int* pnSleepTime = new int(params[1].get_int());
1608     CreateThread(ThreadCleanWalletPassphrase, pnSleepTime);
1609
1610     return Value::null;
1611 }
1612
1613
1614 Value walletpassphrasechange(const Array& params, bool fHelp)
1615 {
1616     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1617         throw runtime_error(
1618             "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1619             "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1620     if (fHelp)
1621         return true;
1622     if (!pwalletMain->IsCrypted())
1623         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
1624
1625     // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
1626     // Alternately, find a way to make params[0] mlock()'d to begin with.
1627     SecureString strOldWalletPass;
1628     strOldWalletPass.reserve(100);
1629     strOldWalletPass = params[0].get_str().c_str();
1630
1631     SecureString strNewWalletPass;
1632     strNewWalletPass.reserve(100);
1633     strNewWalletPass = params[1].get_str().c_str();
1634
1635     if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
1636         throw runtime_error(
1637             "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1638             "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1639
1640     if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
1641         throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
1642
1643     return Value::null;
1644 }
1645
1646
1647 Value walletlock(const Array& params, bool fHelp)
1648 {
1649     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0))
1650         throw runtime_error(
1651             "walletlock\n"
1652             "Removes the wallet encryption key from memory, locking the wallet.\n"
1653             "After calling this method, you will need to call walletpassphrase again\n"
1654             "before being able to call any methods which require the wallet to be unlocked.");
1655     if (fHelp)
1656         return true;
1657     if (!pwalletMain->IsCrypted())
1658         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
1659
1660     pwalletMain->Lock();
1661     CRITICAL_BLOCK(cs_nWalletUnlockTime)
1662     {
1663         nWalletUnlockTime = 0;
1664     }
1665
1666     return Value::null;
1667 }
1668
1669
1670 Value encryptwallet(const Array& params, bool fHelp)
1671 {
1672     if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
1673         throw runtime_error(
1674             "encryptwallet <passphrase>\n"
1675             "Encrypts the wallet with <passphrase>.");
1676     if (fHelp)
1677         return true;
1678     if (pwalletMain->IsCrypted())
1679         throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called.");
1680
1681 #ifdef QT_GUI
1682     // shutting down via RPC while the GUI is running does not work (yet):
1683     throw runtime_error("Not Yet Implemented: use GUI to encrypt wallet, not RPC command");
1684 #endif
1685
1686     // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1687     // Alternately, find a way to make params[0] mlock()'d to begin with.
1688     SecureString strWalletPass;
1689     strWalletPass.reserve(100);
1690     strWalletPass = params[0].get_str().c_str();
1691
1692     if (strWalletPass.length() < 1)
1693         throw runtime_error(
1694             "encryptwallet <passphrase>\n"
1695             "Encrypts the wallet with <passphrase>.");
1696
1697     if (!pwalletMain->EncryptWallet(strWalletPass))
1698         throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
1699
1700     // BDB seems to have a bad habit of writing old data into
1701     // slack space in .dat files; that is bad if the old data is
1702     // unencrypted private keys.  So:
1703     CreateThread(Shutdown, NULL);
1704     return "wallet encrypted; bitcoin server stopping, restart to run with encrypted wallet";
1705 }
1706
1707
1708 Value validateaddress(const Array& params, bool fHelp)
1709 {
1710     if (fHelp || params.size() != 1)
1711         throw runtime_error(
1712             "validateaddress <bitcoinaddress>\n"
1713             "Return information about <bitcoinaddress>.");
1714
1715     CBitcoinAddress address(params[0].get_str());
1716     bool isValid = address.IsValid();
1717
1718     Object ret;
1719     ret.push_back(Pair("isvalid", isValid));
1720     if (isValid)
1721     {
1722         // Call Hash160ToAddress() so we always return current ADDRESSVERSION
1723         // version of the address:
1724         string currentAddress = address.ToString();
1725         ret.push_back(Pair("address", currentAddress));
1726         if (pwalletMain->HaveKey(address))
1727         {
1728             ret.push_back(Pair("ismine", true));
1729             std::vector<unsigned char> vchPubKey;
1730             pwalletMain->GetPubKey(address, vchPubKey);
1731             ret.push_back(Pair("pubkey", HexStr(vchPubKey)));
1732             CKey key;
1733             key.SetPubKey(vchPubKey);
1734             ret.push_back(Pair("iscompressed", key.IsCompressed()));
1735         }
1736         else if (pwalletMain->HaveCScript(address.GetHash160()))
1737         {
1738             ret.push_back(Pair("isscript", true));
1739             CScript subscript;
1740             pwalletMain->GetCScript(address.GetHash160(), subscript);
1741             ret.push_back(Pair("ismine", ::IsMine(*pwalletMain, subscript)));
1742             std::vector<CBitcoinAddress> addresses;
1743             txnouttype whichType;
1744             int nRequired;
1745             ExtractAddresses(subscript, whichType, addresses, nRequired);
1746             ret.push_back(Pair("script", GetTxnOutputType(whichType)));
1747             Array a;
1748             BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
1749                 a.push_back(addr.ToString());
1750             ret.push_back(Pair("addresses", a));
1751             if (whichType == TX_MULTISIG)
1752                 ret.push_back(Pair("sigsrequired", nRequired));
1753         }
1754         else
1755             ret.push_back(Pair("ismine", false));
1756         if (pwalletMain->mapAddressBook.count(address))
1757             ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
1758     }
1759     return ret;
1760 }
1761
1762 Value getwork(const Array& params, bool fHelp)
1763 {
1764     if (fHelp || params.size() > 1)
1765         throw runtime_error(
1766             "getwork [data]\n"
1767             "If [data] is not specified, returns formatted hash data to work on:\n"
1768             "  \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
1769             "  \"data\" : block data\n"
1770             "  \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
1771             "  \"target\" : little endian hash target\n"
1772             "If [data] is specified, tries to solve the block and returns true if it was successful.");
1773
1774     if (vNodes.empty())
1775         throw JSONRPCError(-9, "Bitcoin is not connected!");
1776
1777     if (IsInitialBlockDownload())
1778         throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
1779
1780     typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
1781     static mapNewBlock_t mapNewBlock;
1782     static vector<CBlock*> vNewBlock;
1783     static CReserveKey reservekey(pwalletMain);
1784
1785     if (params.size() == 0)
1786     {
1787         // Update block
1788         static unsigned int nTransactionsUpdatedLast;
1789         static CBlockIndex* pindexPrev;
1790         static int64 nStart;
1791         static CBlock* pblock;
1792         if (pindexPrev != pindexBest ||
1793             (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
1794         {
1795             if (pindexPrev != pindexBest)
1796             {
1797                 // Deallocate old blocks since they're obsolete now
1798                 mapNewBlock.clear();
1799                 BOOST_FOREACH(CBlock* pblock, vNewBlock)
1800                     delete pblock;
1801                 vNewBlock.clear();
1802             }
1803             nTransactionsUpdatedLast = nTransactionsUpdated;
1804             pindexPrev = pindexBest;
1805             nStart = GetTime();
1806
1807             // Create new block
1808             pblock = CreateNewBlock(reservekey);
1809             if (!pblock)
1810                 throw JSONRPCError(-7, "Out of memory");
1811             vNewBlock.push_back(pblock);
1812         }
1813
1814         // Update nTime
1815         pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
1816         pblock->nNonce = 0;
1817
1818         // Update nExtraNonce
1819         static unsigned int nExtraNonce = 0;
1820         IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
1821
1822         // Save
1823         mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
1824
1825         // Prebuild hash buffers
1826         char pmidstate[32];
1827         char pdata[128];
1828         char phash1[64];
1829         FormatHashBuffers(pblock, pmidstate, pdata, phash1);
1830
1831         uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
1832
1833         Object result;
1834         result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
1835         result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
1836         result.push_back(Pair("hash1",    HexStr(BEGIN(phash1), END(phash1)))); // deprecated
1837         result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));
1838         return result;
1839     }
1840     else
1841     {
1842         // Parse parameters
1843         vector<unsigned char> vchData = ParseHex(params[0].get_str());
1844         if (vchData.size() != 128)
1845             throw JSONRPCError(-8, "Invalid parameter");
1846         CBlock* pdata = (CBlock*)&vchData[0];
1847
1848         // Byte reverse
1849         for (int i = 0; i < 128/4; i++)
1850             ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
1851
1852         // Get saved block
1853         if (!mapNewBlock.count(pdata->hashMerkleRoot))
1854             return false;
1855         CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
1856
1857         pblock->nTime = pdata->nTime;
1858         pblock->nNonce = pdata->nNonce;
1859         pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
1860         pblock->hashMerkleRoot = pblock->BuildMerkleTree();
1861
1862         return CheckWork(pblock, *pwalletMain, reservekey);
1863     }
1864 }
1865
1866
1867 Value getmemorypool(const Array& params, bool fHelp)
1868 {
1869     if (fHelp || params.size() > 1)
1870         throw runtime_error(
1871             "getmemorypool [data]\n"
1872             "If [data] is not specified, returns data needed to construct a block to work on:\n"
1873             "  \"version\" : block version\n"
1874             "  \"previousblockhash\" : hash of current highest block\n"
1875             "  \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n"
1876             "  \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n"
1877             "  \"coinbaseflags\" : data that should be included in coinbase so support for new features can be judged\n"
1878             "  \"time\" : timestamp appropriate for next block\n"
1879             "  \"mintime\" : minimum timestamp appropriate for next block\n"
1880             "  \"curtime\" : current timestamp\n"
1881             "  \"bits\" : compressed target of next block\n"
1882             "If [data] is specified, tries to solve the block and returns true if it was successful.");
1883
1884     if (params.size() == 0)
1885     {
1886         if (vNodes.empty())
1887             throw JSONRPCError(-9, "Bitcoin is not connected!");
1888
1889         if (IsInitialBlockDownload())
1890             throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
1891
1892         static CReserveKey reservekey(pwalletMain);
1893
1894         // Update block
1895         static unsigned int nTransactionsUpdatedLast;
1896         static CBlockIndex* pindexPrev;
1897         static int64 nStart;
1898         static CBlock* pblock;
1899         if (pindexPrev != pindexBest ||
1900             (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5))
1901         {
1902             nTransactionsUpdatedLast = nTransactionsUpdated;
1903             pindexPrev = pindexBest;
1904             nStart = GetTime();
1905
1906             // Create new block
1907             if(pblock)
1908                 delete pblock;
1909             pblock = CreateNewBlock(reservekey);
1910             if (!pblock)
1911                 throw JSONRPCError(-7, "Out of memory");
1912         }
1913
1914         // Update nTime
1915         pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
1916         pblock->nNonce = 0;
1917
1918         Array transactions;
1919         BOOST_FOREACH(CTransaction tx, pblock->vtx) {
1920             if(tx.IsCoinBase())
1921                 continue;
1922
1923             CDataStream ssTx;
1924             ssTx << tx;
1925
1926             transactions.push_back(HexStr(ssTx.begin(), ssTx.end()));
1927         }
1928
1929         Object result;
1930         result.push_back(Pair("version", pblock->nVersion));
1931         result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
1932         result.push_back(Pair("transactions", transactions));
1933         result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
1934         result.push_back(Pair("coinbaseflags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
1935         result.push_back(Pair("time", (int64_t)pblock->nTime));
1936         result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
1937         result.push_back(Pair("curtime", (int64_t)GetAdjustedTime()));
1938
1939         union {
1940             int32_t nBits;
1941             char cBits[4];
1942         } uBits;
1943         uBits.nBits = htonl((int32_t)pblock->nBits);
1944         result.push_back(Pair("bits", HexStr(BEGIN(uBits.cBits), END(uBits.cBits))));
1945
1946         return result;
1947     }
1948     else
1949     {
1950         // Parse parameters
1951         CDataStream ssBlock(ParseHex(params[0].get_str()));
1952         CBlock pblock;
1953         ssBlock >> pblock;
1954
1955         return ProcessBlock(NULL, &pblock);
1956     }
1957 }
1958
1959 Value getblockhash(const Array& params, bool fHelp)
1960 {
1961     if (fHelp || params.size() != 1)
1962         throw runtime_error(
1963             "getblockhash <index>\n"
1964             "Returns hash of block in best-block-chain at <index>.");
1965
1966     int nHeight = params[0].get_int();
1967     if (nHeight < 0 || nHeight > nBestHeight)
1968         throw runtime_error("Block number out of range.");
1969
1970     CBlock block;
1971     CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
1972     while (pblockindex->nHeight > nHeight)
1973         pblockindex = pblockindex->pprev;
1974     return pblockindex->phashBlock->GetHex();
1975 }
1976
1977 Value getblock(const Array& params, bool fHelp)
1978 {
1979     if (fHelp || params.size() != 1)
1980         throw runtime_error(
1981             "getblock <hash>\n"
1982             "Returns details of a block with given block-hash.");
1983
1984     std::string strHash = params[0].get_str();
1985     uint256 hash(strHash);
1986
1987     if (mapBlockIndex.count(hash) == 0)
1988         throw JSONRPCError(-5, "Block not found");
1989
1990     CBlock block;
1991     CBlockIndex* pblockindex = mapBlockIndex[hash];
1992     block.ReadFromDisk(pblockindex, true);
1993
1994     return blockToJSON(block, pblockindex);
1995 }
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007 //
2008 // Call Table
2009 //
2010
2011 pair<string, rpcfn_type> pCallTable[] =
2012 {
2013     make_pair("help",                   &help),
2014     make_pair("stop",                   &stop),
2015     make_pair("getblockcount",          &getblockcount),
2016     make_pair("getblocknumber",         &getblocknumber),
2017     make_pair("getconnectioncount",     &getconnectioncount),
2018     make_pair("getdifficulty",          &getdifficulty),
2019     make_pair("getgenerate",            &getgenerate),
2020     make_pair("setgenerate",            &setgenerate),
2021     make_pair("gethashespersec",        &gethashespersec),
2022     make_pair("getinfo",                &getinfo),
2023     make_pair("getmininginfo",          &getmininginfo),
2024     make_pair("getnewaddress",          &getnewaddress),
2025     make_pair("getaccountaddress",      &getaccountaddress),
2026     make_pair("setaccount",             &setaccount),
2027     make_pair("getaccount",             &getaccount),
2028     make_pair("getaddressesbyaccount",  &getaddressesbyaccount),
2029     make_pair("sendtoaddress",          &sendtoaddress),
2030     make_pair("getreceivedbyaddress",   &getreceivedbyaddress),
2031     make_pair("getreceivedbyaccount",   &getreceivedbyaccount),
2032     make_pair("listreceivedbyaddress",  &listreceivedbyaddress),
2033     make_pair("listreceivedbyaccount",  &listreceivedbyaccount),
2034     make_pair("backupwallet",           &backupwallet),
2035     make_pair("keypoolrefill",          &keypoolrefill),
2036     make_pair("walletpassphrase",       &walletpassphrase),
2037     make_pair("walletpassphrasechange", &walletpassphrasechange),
2038     make_pair("walletlock",             &walletlock),
2039     make_pair("encryptwallet",          &encryptwallet),
2040     make_pair("validateaddress",        &validateaddress),
2041     make_pair("getbalance",             &getbalance),
2042     make_pair("move",                   &movecmd),
2043     make_pair("sendfrom",               &sendfrom),
2044     make_pair("sendmany",               &sendmany),
2045     make_pair("addmultisigaddress",     &addmultisigaddress),
2046     make_pair("getblock",               &getblock),
2047     make_pair("getblockhash",           &getblockhash),
2048     make_pair("gettransaction",         &gettransaction),
2049     make_pair("listtransactions",       &listtransactions),
2050     make_pair("signmessage",            &signmessage),
2051     make_pair("verifymessage",          &verifymessage),
2052     make_pair("getwork",                &getwork),
2053     make_pair("listaccounts",           &listaccounts),
2054     make_pair("settxfee",               &settxfee),
2055     make_pair("getmemorypool",          &getmemorypool),
2056     make_pair("listsinceblock",         &listsinceblock),
2057     make_pair("dumpprivkey",            &dumpprivkey),
2058     make_pair("importprivkey",          &importprivkey)
2059 };
2060 map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
2061
2062 string pAllowInSafeMode[] =
2063 {
2064     "help",
2065     "stop",
2066     "getblockcount",
2067     "getblocknumber",  // deprecated
2068     "getconnectioncount",
2069     "getdifficulty",
2070     "getgenerate",
2071     "setgenerate",
2072     "gethashespersec",
2073     "getinfo",
2074     "getmininginfo",
2075     "getnewaddress",
2076     "getaccountaddress",
2077     "getaccount",
2078     "getaddressesbyaccount",
2079     "backupwallet",
2080     "keypoolrefill",
2081     "walletpassphrase",
2082     "walletlock",
2083     "validateaddress",
2084     "getwork",
2085     "getmemorypool",
2086 };
2087 set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
2088
2089
2090
2091
2092 //
2093 // HTTP protocol
2094 //
2095 // This ain't Apache.  We're just using HTTP header for the length field
2096 // and to be compatible with other JSON-RPC implementations.
2097 //
2098
2099 string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders)
2100 {
2101     ostringstream s;
2102     s << "POST / HTTP/1.1\r\n"
2103       << "User-Agent: bitcoin-json-rpc/" << FormatFullVersion() << "\r\n"
2104       << "Host: 127.0.0.1\r\n"
2105       << "Content-Type: application/json\r\n"
2106       << "Content-Length: " << strMsg.size() << "\r\n"
2107       << "Connection: close\r\n"
2108       << "Accept: application/json\r\n";
2109     BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders)
2110         s << item.first << ": " << item.second << "\r\n";
2111     s << "\r\n" << strMsg;
2112
2113     return s.str();
2114 }
2115
2116 string rfc1123Time()
2117 {
2118     char buffer[64];
2119     time_t now;
2120     time(&now);
2121     struct tm* now_gmt = gmtime(&now);
2122     string locale(setlocale(LC_TIME, NULL));
2123     setlocale(LC_TIME, "C"); // we want posix (aka "C") weekday/month strings
2124     strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt);
2125     setlocale(LC_TIME, locale.c_str());
2126     return string(buffer);
2127 }
2128
2129 static string HTTPReply(int nStatus, const string& strMsg)
2130 {
2131     if (nStatus == 401)
2132         return strprintf("HTTP/1.0 401 Authorization Required\r\n"
2133             "Date: %s\r\n"
2134             "Server: bitcoin-json-rpc/%s\r\n"
2135             "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
2136             "Content-Type: text/html\r\n"
2137             "Content-Length: 296\r\n"
2138             "\r\n"
2139             "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
2140             "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
2141             "<HTML>\r\n"
2142             "<HEAD>\r\n"
2143             "<TITLE>Error</TITLE>\r\n"
2144             "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
2145             "</HEAD>\r\n"
2146             "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
2147             "</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
2148     const char *cStatus;
2149          if (nStatus == 200) cStatus = "OK";
2150     else if (nStatus == 400) cStatus = "Bad Request";
2151     else if (nStatus == 403) cStatus = "Forbidden";
2152     else if (nStatus == 404) cStatus = "Not Found";
2153     else if (nStatus == 500) cStatus = "Internal Server Error";
2154     else cStatus = "";
2155     return strprintf(
2156             "HTTP/1.1 %d %s\r\n"
2157             "Date: %s\r\n"
2158             "Connection: close\r\n"
2159             "Content-Length: %d\r\n"
2160             "Content-Type: application/json\r\n"
2161             "Server: bitcoin-json-rpc/%s\r\n"
2162             "\r\n"
2163             "%s",
2164         nStatus,
2165         cStatus,
2166         rfc1123Time().c_str(),
2167         strMsg.size(),
2168         FormatFullVersion().c_str(),
2169         strMsg.c_str());
2170 }
2171
2172 int ReadHTTPStatus(std::basic_istream<char>& stream)
2173 {
2174     string str;
2175     getline(stream, str);
2176     vector<string> vWords;
2177     boost::split(vWords, str, boost::is_any_of(" "));
2178     if (vWords.size() < 2)
2179         return 500;
2180     return atoi(vWords[1].c_str());
2181 }
2182
2183 int ReadHTTPHeader(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
2184 {
2185     int nLen = 0;
2186     loop
2187     {
2188         string str;
2189         std::getline(stream, str);
2190         if (str.empty() || str == "\r")
2191             break;
2192         string::size_type nColon = str.find(":");
2193         if (nColon != string::npos)
2194         {
2195             string strHeader = str.substr(0, nColon);
2196             boost::trim(strHeader);
2197             boost::to_lower(strHeader);
2198             string strValue = str.substr(nColon+1);
2199             boost::trim(strValue);
2200             mapHeadersRet[strHeader] = strValue;
2201             if (strHeader == "content-length")
2202                 nLen = atoi(strValue.c_str());
2203         }
2204     }
2205     return nLen;
2206 }
2207
2208 int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
2209 {
2210     mapHeadersRet.clear();
2211     strMessageRet = "";
2212
2213     // Read status
2214     int nStatus = ReadHTTPStatus(stream);
2215
2216     // Read header
2217     int nLen = ReadHTTPHeader(stream, mapHeadersRet);
2218     if (nLen < 0 || nLen > MAX_SIZE)
2219         return 500;
2220
2221     // Read message
2222     if (nLen > 0)
2223     {
2224         vector<char> vch(nLen);
2225         stream.read(&vch[0], nLen);
2226         strMessageRet = string(vch.begin(), vch.end());
2227     }
2228
2229     return nStatus;
2230 }
2231
2232 bool HTTPAuthorized(map<string, string>& mapHeaders)
2233 {
2234     string strAuth = mapHeaders["authorization"];
2235     if (strAuth.substr(0,6) != "Basic ")
2236         return false;
2237     string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
2238     string strUserPass = DecodeBase64(strUserPass64);
2239     return strUserPass == strRPCUserColonPass;
2240 }
2241
2242 //
2243 // JSON-RPC protocol.  Bitcoin speaks version 1.0 for maximum compatibility,
2244 // but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
2245 // unspecified (HTTP errors and contents of 'error').
2246 //
2247 // 1.0 spec: http://json-rpc.org/wiki/specification
2248 // 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http
2249 // http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
2250 //
2251
2252 string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
2253 {
2254     Object request;
2255     request.push_back(Pair("method", strMethod));
2256     request.push_back(Pair("params", params));
2257     request.push_back(Pair("id", id));
2258     return write_string(Value(request), false) + "\n";
2259 }
2260
2261 string JSONRPCReply(const Value& result, const Value& error, const Value& id)
2262 {
2263     Object reply;
2264     if (error.type() != null_type)
2265         reply.push_back(Pair("result", Value::null));
2266     else
2267         reply.push_back(Pair("result", result));
2268     reply.push_back(Pair("error", error));
2269     reply.push_back(Pair("id", id));
2270     return write_string(Value(reply), false) + "\n";
2271 }
2272
2273 void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
2274 {
2275     // Send error reply from json-rpc error object
2276     int nStatus = 500;
2277     int code = find_value(objError, "code").get_int();
2278     if (code == -32600) nStatus = 400;
2279     else if (code == -32601) nStatus = 404;
2280     string strReply = JSONRPCReply(Value::null, objError, id);
2281     stream << HTTPReply(nStatus, strReply) << std::flush;
2282 }
2283
2284 bool ClientAllowed(const string& strAddress)
2285 {
2286     if (strAddress == asio::ip::address_v4::loopback().to_string())
2287         return true;
2288     const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
2289     BOOST_FOREACH(string strAllow, vAllow)
2290         if (WildcardMatch(strAddress, strAllow))
2291             return true;
2292     return false;
2293 }
2294
2295 #ifdef USE_SSL
2296 //
2297 // IOStream device that speaks SSL but can also speak non-SSL
2298 //
2299 class SSLIOStreamDevice : public iostreams::device<iostreams::bidirectional> {
2300 public:
2301     SSLIOStreamDevice(SSLStream &streamIn, bool fUseSSLIn) : stream(streamIn)
2302     {
2303         fUseSSL = fUseSSLIn;
2304         fNeedHandshake = fUseSSLIn;
2305     }
2306
2307     void handshake(ssl::stream_base::handshake_type role)
2308     {
2309         if (!fNeedHandshake) return;
2310         fNeedHandshake = false;
2311         stream.handshake(role);
2312     }
2313     std::streamsize read(char* s, std::streamsize n)
2314     {
2315         handshake(ssl::stream_base::server); // HTTPS servers read first
2316         if (fUseSSL) return stream.read_some(asio::buffer(s, n));
2317         return stream.next_layer().read_some(asio::buffer(s, n));
2318     }
2319     std::streamsize write(const char* s, std::streamsize n)
2320     {
2321         handshake(ssl::stream_base::client); // HTTPS clients write first
2322         if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
2323         return asio::write(stream.next_layer(), asio::buffer(s, n));
2324     }
2325     bool connect(const std::string& server, const std::string& port)
2326     {
2327         ip::tcp::resolver resolver(stream.get_io_service());
2328         ip::tcp::resolver::query query(server.c_str(), port.c_str());
2329         ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
2330         ip::tcp::resolver::iterator end;
2331         boost::system::error_code error = asio::error::host_not_found;
2332         while (error && endpoint_iterator != end)
2333         {
2334             stream.lowest_layer().close();
2335             stream.lowest_layer().connect(*endpoint_iterator++, error);
2336         }
2337         if (error)
2338             return false;
2339         return true;
2340     }
2341
2342 private:
2343     bool fNeedHandshake;
2344     bool fUseSSL;
2345     SSLStream& stream;
2346 };
2347 #endif
2348
2349 void ThreadRPCServer(void* parg)
2350 {
2351     IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
2352     try
2353     {
2354         vnThreadsRunning[4]++;
2355         ThreadRPCServer2(parg);
2356         vnThreadsRunning[4]--;
2357     }
2358     catch (std::exception& e) {
2359         vnThreadsRunning[4]--;
2360         PrintException(&e, "ThreadRPCServer()");
2361     } catch (...) {
2362         vnThreadsRunning[4]--;
2363         PrintException(NULL, "ThreadRPCServer()");
2364     }
2365     printf("ThreadRPCServer exiting\n");
2366 }
2367
2368 void ThreadRPCServer2(void* parg)
2369 {
2370     printf("ThreadRPCServer started\n");
2371
2372     strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
2373     if (strRPCUserColonPass == ":")
2374     {
2375         string strWhatAmI = "To use bitcoind";
2376         if (mapArgs.count("-server"))
2377             strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
2378         else if (mapArgs.count("-daemon"))
2379             strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
2380         PrintConsole(
2381             _("Error: %s, you must set rpcpassword=<password>\nin the configuration file: %s\n"
2382               "If the file does not exist, create it with owner-readable-only file permissions.\n"),
2383                 strWhatAmI.c_str(),
2384                 GetConfigFile().c_str());
2385 #ifndef QT_GUI
2386         CreateThread(Shutdown, NULL);
2387 #endif
2388         return;
2389     }
2390
2391     bool fUseSSL = GetBoolArg("-rpcssl");
2392     asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback();
2393
2394     asio::io_service io_service;
2395     ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
2396     ip::tcp::acceptor acceptor(io_service, endpoint);
2397
2398     acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
2399
2400 #ifdef USE_SSL
2401     ssl::context context(io_service, ssl::context::sslv23);
2402     if (fUseSSL)
2403     {
2404         context.set_options(ssl::context::no_sslv2);
2405         filesystem::path certfile = GetArg("-rpcsslcertificatechainfile", "server.cert");
2406         if (!certfile.is_complete()) certfile = filesystem::path(GetDataDir()) / certfile;
2407         if (filesystem::exists(certfile)) context.use_certificate_chain_file(certfile.string().c_str());
2408         else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", certfile.string().c_str());
2409         filesystem::path pkfile = GetArg("-rpcsslprivatekeyfile", "server.pem");
2410         if (!pkfile.is_complete()) pkfile = filesystem::path(GetDataDir()) / pkfile;
2411         if (filesystem::exists(pkfile)) context.use_private_key_file(pkfile.string().c_str(), ssl::context::pem);
2412         else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pkfile.string().c_str());
2413
2414         string ciphers = GetArg("-rpcsslciphers",
2415                                          "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
2416         SSL_CTX_set_cipher_list(context.impl(), ciphers.c_str());
2417     }
2418 #else
2419     if (fUseSSL)
2420         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2421 #endif
2422
2423     loop
2424     {
2425         // Accept connection
2426 #ifdef USE_SSL
2427         SSLStream sslStream(io_service, context);
2428         SSLIOStreamDevice d(sslStream, fUseSSL);
2429         iostreams::stream<SSLIOStreamDevice> stream(d);
2430 #else
2431         ip::tcp::iostream stream;
2432 #endif
2433
2434         ip::tcp::endpoint peer;
2435         vnThreadsRunning[4]--;
2436 #ifdef USE_SSL
2437         acceptor.accept(sslStream.lowest_layer(), peer);
2438 #else
2439         acceptor.accept(*stream.rdbuf(), peer);
2440 #endif
2441         vnThreadsRunning[4]++;
2442         if (fShutdown)
2443             return;
2444
2445         // Restrict callers by IP
2446         if (!ClientAllowed(peer.address().to_string()))
2447         {
2448             // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
2449             if (!fUseSSL)
2450                 stream << HTTPReply(403, "") << std::flush;
2451             continue;
2452         }
2453
2454         map<string, string> mapHeaders;
2455         string strRequest;
2456
2457         boost::thread api_caller(ReadHTTP, boost::ref(stream), boost::ref(mapHeaders), boost::ref(strRequest));
2458         if (!api_caller.timed_join(boost::posix_time::seconds(GetArg("-rpctimeout", 30))))
2459         {   // Timed out:
2460             acceptor.cancel();
2461             printf("ThreadRPCServer ReadHTTP timeout\n");
2462             continue;
2463         }
2464
2465         // Check authorization
2466         if (mapHeaders.count("authorization") == 0)
2467         {
2468             stream << HTTPReply(401, "") << std::flush;
2469             continue;
2470         }
2471         if (!HTTPAuthorized(mapHeaders))
2472         {
2473             // Deter brute-forcing short passwords
2474             if (mapArgs["-rpcpassword"].size() < 15)
2475                 Sleep(50);
2476
2477             stream << HTTPReply(401, "") << std::flush;
2478             printf("ThreadRPCServer incorrect password attempt\n");
2479             continue;
2480         }
2481
2482         Value id = Value::null;
2483         try
2484         {
2485             // Parse request
2486             Value valRequest;
2487             if (!read_string(strRequest, valRequest) || valRequest.type() != obj_type)
2488                 throw JSONRPCError(-32700, "Parse error");
2489             const Object& request = valRequest.get_obj();
2490
2491             // Parse id now so errors from here on will have the id
2492             id = find_value(request, "id");
2493
2494             // Parse method
2495             Value valMethod = find_value(request, "method");
2496             if (valMethod.type() == null_type)
2497                 throw JSONRPCError(-32600, "Missing method");
2498             if (valMethod.type() != str_type)
2499                 throw JSONRPCError(-32600, "Method must be a string");
2500             string strMethod = valMethod.get_str();
2501             if (strMethod != "getwork" && strMethod != "getmemorypool")
2502                 printf("ThreadRPCServer method=%s\n", strMethod.c_str());
2503
2504             // Parse params
2505             Value valParams = find_value(request, "params");
2506             Array params;
2507             if (valParams.type() == array_type)
2508                 params = valParams.get_array();
2509             else if (valParams.type() == null_type)
2510                 params = Array();
2511             else
2512                 throw JSONRPCError(-32600, "Params must be an array");
2513
2514             // Find method
2515             map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
2516             if (mi == mapCallTable.end())
2517                 throw JSONRPCError(-32601, "Method not found");
2518
2519             // Observe safe mode
2520             string strWarning = GetWarnings("rpc");
2521             if (strWarning != "" && !GetBoolArg("-disablesafemode") && !setAllowInSafeMode.count(strMethod))
2522                 throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
2523
2524             try
2525             {
2526                 // Execute
2527                 Value result;
2528                 CRITICAL_BLOCK(cs_main)
2529                 CRITICAL_BLOCK(pwalletMain->cs_wallet)
2530                     result = (*(*mi).second)(params, false);
2531
2532                 // Send reply
2533                 string strReply = JSONRPCReply(result, Value::null, id);
2534                 stream << HTTPReply(200, strReply) << std::flush;
2535             }
2536             catch (std::exception& e)
2537             {
2538                 ErrorReply(stream, JSONRPCError(-1, e.what()), id);
2539             }
2540         }
2541         catch (Object& objError)
2542         {
2543             ErrorReply(stream, objError, id);
2544         }
2545         catch (std::exception& e)
2546         {
2547             ErrorReply(stream, JSONRPCError(-32700, e.what()), id);
2548         }
2549     }
2550 }
2551
2552
2553
2554
2555 Object CallRPC(const string& strMethod, const Array& params)
2556 {
2557     if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
2558         throw runtime_error(strprintf(
2559             _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
2560               "If the file does not exist, create it with owner-readable-only file permissions."),
2561                 GetConfigFile().c_str()));
2562
2563     // Connect to localhost
2564     bool fUseSSL = GetBoolArg("-rpcssl");
2565 #ifdef USE_SSL
2566     asio::io_service io_service;
2567     ssl::context context(io_service, ssl::context::sslv23);
2568     context.set_options(ssl::context::no_sslv2);
2569     SSLStream sslStream(io_service, context);
2570     SSLIOStreamDevice d(sslStream, fUseSSL);
2571     iostreams::stream<SSLIOStreamDevice> stream(d);
2572     if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332")))
2573         throw runtime_error("couldn't connect to server");
2574 #else
2575     if (fUseSSL)
2576         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2577
2578     ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332"));
2579     if (stream.fail())
2580         throw runtime_error("couldn't connect to server");
2581 #endif
2582
2583
2584     // HTTP basic authentication
2585     string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
2586     map<string, string> mapRequestHeaders;
2587     mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
2588
2589     // Send request
2590     string strRequest = JSONRPCRequest(strMethod, params, 1);
2591     string strPost = HTTPPost(strRequest, mapRequestHeaders);
2592     stream << strPost << std::flush;
2593
2594     // Receive reply
2595     map<string, string> mapHeaders;
2596     string strReply;
2597     int nStatus = ReadHTTP(stream, mapHeaders, strReply);
2598     if (nStatus == 401)
2599         throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
2600     else if (nStatus >= 400 && nStatus != 400 && nStatus != 404 && nStatus != 500)
2601         throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
2602     else if (strReply.empty())
2603         throw runtime_error("no response from server");
2604
2605     // Parse reply
2606     Value valReply;
2607     if (!read_string(strReply, valReply))
2608         throw runtime_error("couldn't parse reply from server");
2609     const Object& reply = valReply.get_obj();
2610     if (reply.empty())
2611         throw runtime_error("expected reply to have result, error and id properties");
2612
2613     return reply;
2614 }
2615
2616
2617
2618
2619 template<typename T>
2620 void ConvertTo(Value& value)
2621 {
2622     if (value.type() == str_type)
2623     {
2624         // reinterpret string as unquoted json value
2625         Value value2;
2626         if (!read_string(value.get_str(), value2))
2627             throw runtime_error("type mismatch");
2628         value = value2.get_value<T>();
2629     }
2630     else
2631     {
2632         value = value.get_value<T>();
2633     }
2634 }
2635
2636 int CommandLineRPC(int argc, char *argv[])
2637 {
2638     string strPrint;
2639     int nRet = 0;
2640     try
2641     {
2642         // Skip switches
2643         while (argc > 1 && IsSwitchChar(argv[1][0]))
2644         {
2645             argc--;
2646             argv++;
2647         }
2648
2649         // Method
2650         if (argc < 2)
2651             throw runtime_error("too few parameters");
2652         string strMethod = argv[1];
2653
2654         // Parameters default to strings
2655         Array params;
2656         for (int i = 2; i < argc; i++)
2657             params.push_back(argv[i]);
2658         int n = params.size();
2659
2660         //
2661         // Special case non-string parameter types
2662         //
2663         if (strMethod == "setgenerate"            && n > 0) ConvertTo<bool>(params[0]);
2664         if (strMethod == "setgenerate"            && n > 1) ConvertTo<boost::int64_t>(params[1]);
2665         if (strMethod == "sendtoaddress"          && n > 1) ConvertTo<double>(params[1]);
2666         if (strMethod == "settxfee"               && n > 0) ConvertTo<double>(params[0]);
2667         if (strMethod == "getreceivedbyaddress"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2668         if (strMethod == "getreceivedbyaccount"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2669         if (strMethod == "listreceivedbyaddress"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2670         if (strMethod == "listreceivedbyaddress"  && n > 1) ConvertTo<bool>(params[1]);
2671         if (strMethod == "listreceivedbyaccount"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2672         if (strMethod == "listreceivedbyaccount"  && n > 1) ConvertTo<bool>(params[1]);
2673         if (strMethod == "getbalance"             && n > 1) ConvertTo<boost::int64_t>(params[1]);
2674         if (strMethod == "getblockhash"           && n > 0) ConvertTo<boost::int64_t>(params[0]);
2675         if (strMethod == "move"                   && n > 2) ConvertTo<double>(params[2]);
2676         if (strMethod == "move"                   && n > 3) ConvertTo<boost::int64_t>(params[3]);
2677         if (strMethod == "sendfrom"               && n > 2) ConvertTo<double>(params[2]);
2678         if (strMethod == "sendfrom"               && n > 3) ConvertTo<boost::int64_t>(params[3]);
2679         if (strMethod == "listtransactions"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2680         if (strMethod == "listtransactions"       && n > 2) ConvertTo<boost::int64_t>(params[2]);
2681         if (strMethod == "listaccounts"           && n > 0) ConvertTo<boost::int64_t>(params[0]);
2682         if (strMethod == "walletpassphrase"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2683         if (strMethod == "listsinceblock"         && n > 1) ConvertTo<boost::int64_t>(params[1]);
2684         if (strMethod == "sendmany"               && n > 1)
2685         {
2686             string s = params[1].get_str();
2687             Value v;
2688             if (!read_string(s, v) || v.type() != obj_type)
2689                 throw runtime_error("type mismatch");
2690             params[1] = v.get_obj();
2691         }
2692         if (strMethod == "sendmany"                && n > 2) ConvertTo<boost::int64_t>(params[2]);
2693         if (strMethod == "addmultisigaddress"      && n > 0) ConvertTo<boost::int64_t>(params[0]);
2694         if (strMethod == "addmultisigaddress"      && n > 1)
2695         {
2696             string s = params[1].get_str();
2697             Value v;
2698             if (!read_string(s, v) || v.type() != array_type)
2699                 throw runtime_error("type mismatch "+s);
2700             params[1] = v.get_array();
2701         }
2702
2703         // Execute
2704         Object reply = CallRPC(strMethod, params);
2705
2706         // Parse reply
2707         const Value& result = find_value(reply, "result");
2708         const Value& error  = find_value(reply, "error");
2709
2710         if (error.type() != null_type)
2711         {
2712             // Error
2713             strPrint = "error: " + write_string(error, false);
2714             int code = find_value(error.get_obj(), "code").get_int();
2715             nRet = abs(code);
2716         }
2717         else
2718         {
2719             // Result
2720             if (result.type() == null_type)
2721                 strPrint = "";
2722             else if (result.type() == str_type)
2723                 strPrint = result.get_str();
2724             else
2725                 strPrint = write_string(result, true);
2726         }
2727     }
2728     catch (std::exception& e)
2729     {
2730         strPrint = string("error: ") + e.what();
2731         nRet = 87;
2732     }
2733     catch (...)
2734     {
2735         PrintException(NULL, "CommandLineRPC()");
2736     }
2737
2738     if (strPrint != "")
2739     {
2740         fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
2741     }
2742     return nRet;
2743 }
2744
2745
2746
2747
2748 #ifdef TEST
2749 int main(int argc, char *argv[])
2750 {
2751 #ifdef _MSC_VER
2752     // Turn off microsoft heap dump noise
2753     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
2754     _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
2755 #endif
2756     setbuf(stdin, NULL);
2757     setbuf(stdout, NULL);
2758     setbuf(stderr, NULL);
2759
2760     try
2761     {
2762         if (argc >= 2 && string(argv[1]) == "-server")
2763         {
2764             printf("server ready\n");
2765             ThreadRPCServer(NULL);
2766         }
2767         else
2768         {
2769             return CommandLineRPC(argc, argv);
2770         }
2771     }
2772     catch (std::exception& e) {
2773         PrintException(&e, "main()");
2774     } catch (...) {
2775         PrintException(NULL, "main()");
2776     }
2777     return 0;
2778 }
2779 #endif