FormatMoney cleanup
[novacoin.git] / src / rpcdump.cpp
1 // Copyright (c) 2009-2012 Bitcoin Developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "init.h" // for pwalletMain
6 #include "bitcoinrpc.h"
7 #include "ui_interface.h"
8 #include "base58.h"
9
10 #define printf OutputDebugStringF
11
12 using namespace json_spirit;
13 using namespace std;
14
15 void EnsureWalletIsUnlocked();
16
17 class CTxDump
18 {
19 public:
20     CBlockIndex *pindex;
21     int64_t nValue;
22     bool fSpent;
23     CWalletTx* ptx;
24     int nOut;
25     CTxDump(CWalletTx* ptx = NULL, int nOut = -1)
26     {
27         pindex = NULL;
28         nValue = 0;
29         fSpent = false;
30         this->ptx = ptx;
31         this->nOut = nOut;
32     }
33 };
34
35 Value importprivkey(const Array& params, bool fHelp)
36 {
37     if (fHelp || params.size() < 1 || params.size() > 3)
38         throw runtime_error(
39             "importprivkey <novacoinprivkey> [label] [rescan=true]\n"
40             "Adds a private key (as returned by dumpprivkey) to your wallet.");
41
42     string strSecret = params[0].get_str();
43     string strLabel = "";
44     if (params.size() > 1)
45         strLabel = params[1].get_str();
46
47     // Whether to perform rescan after import
48     bool fRescan = true;
49     if (params.size() > 2)
50         fRescan = params[2].get_bool();
51
52     CBitcoinSecret vchSecret;
53     bool fGood = vchSecret.SetString(strSecret);
54
55     if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
56     if (fWalletUnlockMintOnly) // ppcoin: no importprivkey in mint-only mode
57         throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for minting only.");
58
59     CKey key;
60     bool fCompressed;
61     CSecret secret = vchSecret.GetSecret(fCompressed);
62     key.SetSecret(secret, fCompressed);
63     CKeyID vchAddress = key.GetPubKey().GetID();
64     {
65         LOCK2(cs_main, pwalletMain->cs_wallet);
66
67         pwalletMain->MarkDirty();
68         pwalletMain->SetAddressBookName(vchAddress, strLabel);
69
70         // Don't throw error in case a key is already there
71         if (pwalletMain->HaveKey(vchAddress))
72             return Value::null;
73
74         pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1;
75
76         if (!pwalletMain->AddKey(key))
77             throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
78
79         // whenever a key is imported, we need to scan the whole chain
80         pwalletMain->nTimeFirstKey = 1; // 0 would be considered 'no value'
81
82         if (fRescan) 
83         {
84             pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true);
85             pwalletMain->ReacceptWalletTransactions();
86         }
87     }
88
89     return Value::null;
90 }
91
92 Value importaddress(const Array& params, bool fHelp)
93 {
94     if (fHelp || params.size() < 1 || params.size() > 3)
95         throw runtime_error(
96             "importaddress <address> [label] [rescan=true]\n"
97             "Adds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend.");
98
99     CScript script;
100     CBitcoinAddress address(params[0].get_str());
101     if (address.IsValid()) {
102         script.SetDestination(address.Get());
103     } else if (IsHex(params[0].get_str())) {
104         std::vector<unsigned char> data(ParseHex(params[0].get_str()));
105         script = CScript(data.begin(), data.end());
106     } else {
107         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Novacoin address or script");
108     }
109
110     string strLabel = "";
111     if (params.size() > 1)
112         strLabel = params[1].get_str();
113
114     // Whether to perform rescan after import
115     bool fRescan = true;
116     if (params.size() > 2)
117         fRescan = params[2].get_bool();
118
119     {
120         LOCK2(cs_main, pwalletMain->cs_wallet);
121         if (::IsMine(*pwalletMain, script) == MINE_SPENDABLE)
122             throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
123
124         // Don't throw error in case an address is already there
125         if (pwalletMain->HaveWatchOnly(script))
126             return Value::null;
127
128         pwalletMain->MarkDirty();
129
130         if (address.IsValid())
131             pwalletMain->SetAddressBookName(address.Get(), strLabel);
132
133         if (!pwalletMain->AddWatchOnly(script))
134             throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
135
136         if (fRescan)
137         {
138             pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true);
139             pwalletMain->ReacceptWalletTransactions();
140         }
141     }
142
143     return Value::null;
144 }
145
146 Value removeaddress(const Array& params, bool fHelp)
147 {
148     if (fHelp || params.size() != 1)
149         throw runtime_error(
150             "removeaddress 'address'\n"
151             "\nRemoves watch-only address or script (in hex) added by importaddress.\n"
152             "\nArguments:\n"
153             "1. 'address' (string, required) The address\n"
154             "\nExamples:\n"
155             "\nremoveaddress 4EqHMPgEAf56CQmU6ZWS8Ug4d7N3gsQVQA\n"
156             "\nRemove watch-only address 4EqHMPgEAf56CQmU6ZWS8Ug4d7N3gsQVQA\n");
157
158     CScript script;
159
160     CBitcoinAddress address(params[0].get_str());
161     if (address.IsValid()) {
162         script.SetDestination(address.Get());
163     } else if (IsHex(params[0].get_str())) {
164         std::vector<unsigned char> data(ParseHex(params[0].get_str()));
165         script = CScript(data.begin(), data.end());
166     } else {
167         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script");
168     }
169
170     if (::IsMine(*pwalletMain, script) == MINE_SPENDABLE)
171         throw JSONRPCError(RPC_WALLET_ERROR, "The wallet contains the private key for this address or script - can't remove it");
172
173     if (!pwalletMain->HaveWatchOnly(script))
174         throw JSONRPCError(RPC_WALLET_ERROR, "The wallet does not contain this address or script");
175
176     LOCK2(cs_main, pwalletMain->cs_wallet);
177
178     pwalletMain->MarkDirty();
179
180     if (!pwalletMain->RemoveWatchOnly(script))
181         throw JSONRPCError(RPC_WALLET_ERROR, "Error removing address from wallet");
182
183     return Value::null;
184 }
185
186 Value importwallet(const Array& params, bool fHelp)
187 {
188     if (fHelp || params.size() != 1)
189         throw runtime_error(
190             "importwallet <filename>\n"
191             "Imports keys from a wallet dump file (see dumpwallet)."
192             + HelpRequiringPassphrase());
193
194     EnsureWalletIsUnlocked();
195
196     if(!ImportWallet(pwalletMain, params[0].get_str().c_str()))
197        throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet");
198
199     return Value::null;
200 }
201
202 Value dumpprivkey(const Array& params, bool fHelp)
203 {
204     if (fHelp || params.size() != 1)
205         throw runtime_error(
206             "dumpprivkey <novacoinaddress>\n"
207             "Reveals the private key corresponding to <novacoinaddress>.");
208
209     EnsureWalletIsUnlocked();
210
211     string strAddress = params[0].get_str();
212     CBitcoinAddress address;
213     if (!address.SetString(strAddress))
214         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
215     if (fWalletUnlockMintOnly) // ppcoin: no dumpprivkey in mint-only mode
216         throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for minting only.");
217     CKeyID keyID;
218     if (!address.GetKeyID(keyID))
219         throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
220     CSecret vchSecret;
221     bool fCompressed;
222     if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed))
223         throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
224     return CBitcoinSecret(vchSecret, fCompressed).ToString();
225 }
226
227 Value dumpwallet(const Array& params, bool fHelp)
228 {
229     if (fHelp || params.size() != 1)
230         throw runtime_error(
231             "dumpwallet <filename>\n"
232             "Dumps all wallet keys in a human-readable format."
233             + HelpRequiringPassphrase());
234
235     EnsureWalletIsUnlocked();
236
237     if(!DumpWallet(pwalletMain, params[0].get_str().c_str() ))
238       throw JSONRPCError(RPC_WALLET_ERROR, "Error dumping wallet keys to file");
239
240     return Value::null;
241 }
242
243 Value dumpmalleablekey(const Array& params, bool fHelp)
244 {
245     if (fHelp || params.size() != 1)
246         throw runtime_error (
247             "dumpmalleablekey <Key view>\n"
248             "Dump the private and public key pairs, which correspond to provided key view.\n");
249
250     CMalleableKey mKey;
251     CMalleableKeyView keyView;
252     keyView.SetString(params[0].get_str());
253
254     if (!pwalletMain->GetMalleableKey(keyView, mKey))
255         throw runtime_error("There is no such item in the wallet");
256
257     Object result;
258     result.push_back(Pair("PrivatePair", mKey.ToString()));
259     result.push_back(Pair("PublicPair", mKey.GetMalleablePubKey().ToString()));
260
261     return result;
262 }
263
264 Value importmalleablekey(const Array& params, bool fHelp)
265 {
266     if (fHelp || params.size() != 1)
267         throw runtime_error (
268             "importmalleablekey <Key data>\n"
269             "Imports the private key pair into your wallet.\n");
270
271     CMalleableKey mKey;
272     bool fSuccess = mKey.SetString(params[0].get_str());
273
274     Object result;
275
276     if (fSuccess)
277     {
278         fSuccess = pwalletMain->AddMalleableKey(mKey);
279         result.push_back(Pair("Successful", fSuccess));
280         result.push_back(Pair("PublicPair", mKey.GetMalleablePubKey().ToString()));
281         result.push_back(Pair("KeyView", CMalleableKeyView(mKey).ToString()));
282     }
283     else
284         result.push_back(Pair("Successful", false));
285
286     return result;
287 }