]> Git Repo - VerusCoin.git/blame - src/wallet-utility.cpp
PBaaS refund fix to fund refund transactions with gateway deposits
[VerusCoin.git] / src / wallet-utility.cpp
CommitLineData
8b78a819
T
1#include <iostream>
2#include <string>
3
4// Include local headers
5#include "wallet/walletdb.h"
6#include "util.h"
7#include "base58.h"
8#include "wallet/crypter.h"
9#include <boost/foreach.hpp>
10
60eafafa 11#include "komodo_defs.h"
12char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
c8c684e9 13std::string PBAAS_HOST;
14int32_t PBAAS_PORT;
15std::string PBAAS_USERPASS;
b2a98c42
MT
16bool PBAAS_TESTMODE;
17uint160 ASSETCHAINS_CHAINID;
18uint160 VERUS_CHAINID;
1e435b54 19std::string VERUS_CHAINNAME;
60eafafa 20int64_t MAX_MONEY = 200000000 * 100000000LL;
c8c684e9 21int64_t MAX_SUPPLY = 50000000000LL * 100000000LL;
6e0857ce 22uint64_t ASSETCHAINS_SUPPLY;
05c2ba63 23uint16_t BITCOIND_RPCPORT = 7771;
24uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
6e0857ce 25uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC;
26uint32_t ASSETCHAINS_MAGIC = 2387029918;
48d800c2 27uint32_t ASSETCHAINS_EQUIHASH = 0;
e980a26d 28uint32_t ASSETCHAINS_VERUSHASH = 1;
48d800c2 29uint32_t ASSETCHAINS_ALGO = 0;
1f722359
MT
30int32_t ASSETCHAINS_LWMAPOS = 0;
31int32_t VERUS_BLOCK_POSUNITS = 1000;
ceaccb0c 32int32_t ASSETCHAINS_OVERWINTER = 227520;
4b729ec5 33int32_t ASSETCHAINS_SAPLING = 227520;
48d800c2 34
5725f8ea 35unsigned int MAX_BLOCK_SIGOPS = 20000;
8b78a819 36
2d8b9129 37#include "pbaas/pbaas.h"
38
39struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
40{
41 return NULL;
42}
43CConnectedChains ConnectedChains;
44CCurrencyDefinition CConnectedChains::GetCachedCurrency(const uint160 &currencyID)
45{
46 return CCurrencyDefinition();
47}
48
8b78a819
T
49void show_help()
50{
51 std::cout <<
52 "This program outputs Bitcoin addresses and private keys from a wallet.dat file" << std::endl
53 << std::endl
54 << "Usage and options: "
55 << std::endl
56 << " -datadir=<directory> to tell the program where your wallet is"
57 << std::endl
58 << " -wallet=<name> (Optional) if your wallet is not named wallet.dat"
59 << std::endl
60 << " -regtest or -testnet (Optional) dumps addresses from regtest/testnet"
61 << std::endl
62 << " -dumppass (Optional)if you want to extract private keys associated with addresses"
63 << std::endl
64 << " -pass=<walletpassphrase> if you have encrypted private keys stored in your wallet"
65 << std::endl;
66}
67
68
69class WalletUtilityDB : public CDB
70{
71 private:
72 typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
73 MasterKeyMap mapMasterKeys;
74 unsigned int nMasterKeyMaxID;
75 SecureString mPass;
76 std::vector<CKeyingMaterial> vMKeys;
77
78 public:
79 WalletUtilityDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose)
80 {
81 nMasterKeyMaxID = 0;
82 mPass.reserve(100);
83 }
84
85 std::string getAddress(CDataStream ssKey);
86 std::string getKey(CDataStream ssKey, CDataStream ssValue);
87 std::string getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass);
88 bool updateMasterKeys(CDataStream ssKey, CDataStream ssValue);
89 bool parseKeys(bool dumppriv, std::string masterPass);
90
91 bool DecryptSecret(const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
92 bool Unlock();
93 bool DecryptKey(const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key);
94};
95
96
97/*
98 * Address from a public key in base58
99 */
100std::string WalletUtilityDB::getAddress(CDataStream ssKey)
101{
102 CPubKey vchPubKey;
103 ssKey >> vchPubKey;
104 CKeyID id = vchPubKey.GetID();
105 std::string strAddr = CBitcoinAddress(id).ToString();
106
107 return strAddr;
108}
109
110
111/*
112 * Non encrypted private key in WIF
113 */
114std::string WalletUtilityDB::getKey(CDataStream ssKey, CDataStream ssValue)
115{
116 std::string strKey;
117 CPubKey vchPubKey;
118 ssKey >> vchPubKey;
119 CPrivKey pkey;
120 CKey key;
121
122 ssValue >> pkey;
123 if (key.Load(pkey, vchPubKey, true))
124 strKey = CBitcoinSecret(key).ToString();
125
126 return strKey;
127}
128
129
130bool WalletUtilityDB::DecryptSecret(const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
131{
132 CCrypter cKeyCrypter;
133 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
134 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
135
136 BOOST_FOREACH(const CKeyingMaterial vMKey, vMKeys)
137 {
138 if(!cKeyCrypter.SetKey(vMKey, chIV))
139 continue;
140 if (cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)))
141 return true;
142 }
143 return false;
144}
145
146
147bool WalletUtilityDB::Unlock()
148{
149 CCrypter crypter;
150 CKeyingMaterial vMasterKey;
151
152 BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
153 {
154 if(!crypter.SetKeyFromPassphrase(mPass, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
155 return false;
156 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
157 continue; // try another master key
158 vMKeys.push_back(vMasterKey);
159 }
160 return true;
161}
162
163
164bool WalletUtilityDB::DecryptKey(const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key)
165{
166 CKeyingMaterial vchSecret;
167 if(!DecryptSecret(vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
168 return false;
169
170 if (vchSecret.size() != 32)
171 return false;
172
173 key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
174 return true;
175}
176
177
178/*
179 * Encrypted private key in WIF format
180 */
181std::string WalletUtilityDB::getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass)
182{
183 mPass = masterPass.c_str();
184 CPubKey vchPubKey;
185 ssKey >> vchPubKey;
186 CKey key;
187
188 std::vector<unsigned char> vKey;
189 ssValue >> vKey;
190
191 if (!Unlock())
192 return "";
193
194 if(!DecryptKey(vKey, vchPubKey, key))
195 return "";
196
197 std::string strKey = CBitcoinSecret(key).ToString();
198 return strKey;
199}
200
201
202/*
203 * Master key derivation
204 */
205bool WalletUtilityDB::updateMasterKeys(CDataStream ssKey, CDataStream ssValue)
206{
207 unsigned int nID;
208 ssKey >> nID;
209 CMasterKey kMasterKey;
210 ssValue >> kMasterKey;
211 if (mapMasterKeys.count(nID) != 0)
212 {
213 std::cout << "Error reading wallet database: duplicate CMasterKey id " << nID << std::endl;
214 return false;
215 }
216 mapMasterKeys[nID] = kMasterKey;
217
218 if (nMasterKeyMaxID < nID)
219 nMasterKeyMaxID = nID;
220
221 return true;
222}
223
224
225/*
226 * Look at all the records and parse keys for addresses and private keys
227 */
228bool WalletUtilityDB::parseKeys(bool dumppriv, std::string masterPass)
229{
230 DBErrors result = DB_LOAD_OK;
231 std::string strType;
232 bool first = true;
233
234 try {
235 Dbc* pcursor = GetCursor();
236 if (!pcursor)
237 {
238 LogPrintf("Error getting wallet database cursor\n");
239 result = DB_CORRUPT;
240 }
241
242 if (dumppriv)
243 {
244 while (result == DB_LOAD_OK && true)
245 {
246 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
247 CDataStream ssValue(SER_DISK, CLIENT_VERSION);
248 int result = ReadAtCursor(pcursor, ssKey, ssValue);
249
250 if (result == DB_NOTFOUND) {
251 break;
252 }
253 else if (result != 0)
254 {
255 LogPrintf("Error reading next record from wallet database\n");
256 result = DB_CORRUPT;
257 break;
258 }
259
260 ssKey >> strType;
261 if (strType == "mkey")
262 {
263 updateMasterKeys(ssKey, ssValue);
264 }
265 }
266 pcursor->close();
267 pcursor = GetCursor();
268 }
269
270 while (result == DB_LOAD_OK && true)
271 {
272 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
273 CDataStream ssValue(SER_DISK, CLIENT_VERSION);
274 int ret = ReadAtCursor(pcursor, ssKey, ssValue);
275
276 if (ret == DB_NOTFOUND)
277 {
278 std::cout << " ]" << std::endl;
279 first = true;
280 break;
281 }
282 else if (ret != DB_LOAD_OK)
283 {
284 LogPrintf("Error reading next record from wallet database\n");
285 result = DB_CORRUPT;
286 break;
287 }
288
289 ssKey >> strType;
290
291 if (strType == "key" || strType == "ckey")
292 {
293 std::string strAddr = getAddress(ssKey);
294 std::string strKey = "";
295
296
297 if (dumppriv && strType == "key")
298 strKey = getKey(ssKey, ssValue);
299 if (dumppriv && strType == "ckey")
300 {
301 if (masterPass == "")
302 {
303 std::cout << "Encrypted wallet, please provide a password. See help below" << std::endl;
304 show_help();
305 result = DB_LOAD_FAIL;
306 break;
307 }
308 strKey = getCryptedKey(ssKey, ssValue, masterPass);
309 }
310
311 if (strAddr != "")
312 {
313 if (first)
314 std::cout << "[ ";
315 else
316 std::cout << ", ";
317 }
318
319 if (dumppriv)
320 {
321 std::cout << "{\"addr\" : \"" + strAddr + "\", "
322 << "\"pkey\" : \"" + strKey + "\"}"
323 << std::flush;
324 }
325 else
326 {
327 std::cout << "\"" + strAddr + "\"";
328 }
329
330 first = false;
331 }
332 }
333
334 pcursor->close();
335 } catch (DbException &e) {
336 std::cout << "DBException caught " << e.get_errno() << std::endl;
337 } catch (std::exception &e) {
338 std::cout << "Exception caught " << std::endl;
339 }
340
341 if (result == DB_LOAD_OK)
342 return true;
343 else
344 return false;
345}
346
347
348int main(int argc, char* argv[])
349{
350 ParseParameters(argc, argv);
351 std::string walletFile = GetArg("-wallet", "wallet.dat");
352 std::string masterPass = GetArg("-pass", "");
353 bool fDumpPass = GetBoolArg("-dumppass", false);
354 bool help = GetBoolArg("-h", false);
355 bool result = false;
356
b2a98c42
MT
357 PBAAS_TESTMODE = false;
358
359
8b78a819
T
360 if (help)
361 {
362 show_help();
363 return 0;
364 }
365
366 try {
367 SelectParamsFromCommandLine();
368 result = WalletUtilityDB(walletFile, "r").parseKeys(fDumpPass, masterPass);
369 }
370 catch (const std::exception& e) {
371 std::cout << "Error opening wallet file " << walletFile << std::endl;
372 std::cout << e.what() << std::endl;
373 }
374
375 if (result)
376 return 0;
377 else
378 return -1;
e8972fab 379}
This page took 0.230463 seconds and 4 git commands to generate.