4 // Include local headers
5 #include "wallet/walletdb.h"
8 #include "wallet/crypter.h"
9 #include <boost/foreach.hpp>
11 #include "komodo_defs.h"
12 char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
14 uint160 ASSETCHAINS_CHAINID;
15 uint160 VERUS_CHAINID;
16 std::string VERUS_CHAINNAME;
17 int64_t MAX_MONEY = 200000000 * 100000000LL;
18 uint64_t ASSETCHAINS_SUPPLY;
19 uint16_t BITCOIND_RPCPORT = 7771;
20 uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
21 uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC;
22 uint32_t ASSETCHAINS_MAGIC = 2387029918;
23 uint32_t ASSETCHAINS_EQUIHASH = 0;
24 uint32_t ASSETCHAINS_VERUSHASH = 1;
25 uint32_t ASSETCHAINS_ALGO = 0;
26 int32_t ASSETCHAINS_LWMAPOS = 0;
27 int32_t VERUS_BLOCK_POSUNITS = 1000;
28 int32_t ASSETCHAINS_OVERWINTER = 227520;
29 int32_t ASSETCHAINS_SAPLING = 227520;
31 unsigned int MAX_BLOCK_SIGOPS = 20000;
33 #include "pbaas/pbaas.h"
35 struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
39 CConnectedChains ConnectedChains;
40 CCurrencyDefinition CConnectedChains::GetCachedCurrency(const uint160 ¤cyID)
42 return CCurrencyDefinition();
48 "This program outputs Bitcoin addresses and private keys from a wallet.dat file" << std::endl
50 << "Usage and options: "
52 << " -datadir=<directory> to tell the program where your wallet is"
54 << " -wallet=<name> (Optional) if your wallet is not named wallet.dat"
56 << " -regtest or -testnet (Optional) dumps addresses from regtest/testnet"
58 << " -dumppass (Optional)if you want to extract private keys associated with addresses"
60 << " -pass=<walletpassphrase> if you have encrypted private keys stored in your wallet"
65 class WalletUtilityDB : public CDB
68 typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
69 MasterKeyMap mapMasterKeys;
70 unsigned int nMasterKeyMaxID;
72 std::vector<CKeyingMaterial> vMKeys;
75 WalletUtilityDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose)
81 std::string getAddress(CDataStream ssKey);
82 std::string getKey(CDataStream ssKey, CDataStream ssValue);
83 std::string getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass);
84 bool updateMasterKeys(CDataStream ssKey, CDataStream ssValue);
85 bool parseKeys(bool dumppriv, std::string masterPass);
87 bool DecryptSecret(const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
89 bool DecryptKey(const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key);
94 * Address from a public key in base58
96 std::string WalletUtilityDB::getAddress(CDataStream ssKey)
100 CKeyID id = vchPubKey.GetID();
101 std::string strAddr = CBitcoinAddress(id).ToString();
108 * Non encrypted private key in WIF
110 std::string WalletUtilityDB::getKey(CDataStream ssKey, CDataStream ssValue)
119 if (key.Load(pkey, vchPubKey, true))
120 strKey = CBitcoinSecret(key).ToString();
126 bool WalletUtilityDB::DecryptSecret(const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
128 CCrypter cKeyCrypter;
129 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
130 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
132 BOOST_FOREACH(const CKeyingMaterial vMKey, vMKeys)
134 if(!cKeyCrypter.SetKey(vMKey, chIV))
136 if (cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)))
143 bool WalletUtilityDB::Unlock()
146 CKeyingMaterial vMasterKey;
148 BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
150 if(!crypter.SetKeyFromPassphrase(mPass, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
152 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
153 continue; // try another master key
154 vMKeys.push_back(vMasterKey);
160 bool WalletUtilityDB::DecryptKey(const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key)
162 CKeyingMaterial vchSecret;
163 if(!DecryptSecret(vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
166 if (vchSecret.size() != 32)
169 key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
175 * Encrypted private key in WIF format
177 std::string WalletUtilityDB::getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass)
179 mPass = masterPass.c_str();
184 std::vector<unsigned char> vKey;
190 if(!DecryptKey(vKey, vchPubKey, key))
193 std::string strKey = CBitcoinSecret(key).ToString();
199 * Master key derivation
201 bool WalletUtilityDB::updateMasterKeys(CDataStream ssKey, CDataStream ssValue)
205 CMasterKey kMasterKey;
206 ssValue >> kMasterKey;
207 if (mapMasterKeys.count(nID) != 0)
209 std::cout << "Error reading wallet database: duplicate CMasterKey id " << nID << std::endl;
212 mapMasterKeys[nID] = kMasterKey;
214 if (nMasterKeyMaxID < nID)
215 nMasterKeyMaxID = nID;
222 * Look at all the records and parse keys for addresses and private keys
224 bool WalletUtilityDB::parseKeys(bool dumppriv, std::string masterPass)
226 DBErrors result = DB_LOAD_OK;
231 Dbc* pcursor = GetCursor();
234 LogPrintf("Error getting wallet database cursor\n");
240 while (result == DB_LOAD_OK && true)
242 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
243 CDataStream ssValue(SER_DISK, CLIENT_VERSION);
244 int result = ReadAtCursor(pcursor, ssKey, ssValue);
246 if (result == DB_NOTFOUND) {
249 else if (result != 0)
251 LogPrintf("Error reading next record from wallet database\n");
257 if (strType == "mkey")
259 updateMasterKeys(ssKey, ssValue);
263 pcursor = GetCursor();
266 while (result == DB_LOAD_OK && true)
268 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
269 CDataStream ssValue(SER_DISK, CLIENT_VERSION);
270 int ret = ReadAtCursor(pcursor, ssKey, ssValue);
272 if (ret == DB_NOTFOUND)
274 std::cout << " ]" << std::endl;
278 else if (ret != DB_LOAD_OK)
280 LogPrintf("Error reading next record from wallet database\n");
287 if (strType == "key" || strType == "ckey")
289 std::string strAddr = getAddress(ssKey);
290 std::string strKey = "";
293 if (dumppriv && strType == "key")
294 strKey = getKey(ssKey, ssValue);
295 if (dumppriv && strType == "ckey")
297 if (masterPass == "")
299 std::cout << "Encrypted wallet, please provide a password. See help below" << std::endl;
301 result = DB_LOAD_FAIL;
304 strKey = getCryptedKey(ssKey, ssValue, masterPass);
317 std::cout << "{\"addr\" : \"" + strAddr + "\", "
318 << "\"pkey\" : \"" + strKey + "\"}"
323 std::cout << "\"" + strAddr + "\"";
331 } catch (DbException &e) {
332 std::cout << "DBException caught " << e.get_errno() << std::endl;
333 } catch (std::exception &e) {
334 std::cout << "Exception caught " << std::endl;
337 if (result == DB_LOAD_OK)
344 int main(int argc, char* argv[])
346 ParseParameters(argc, argv);
347 std::string walletFile = GetArg("-wallet", "wallet.dat");
348 std::string masterPass = GetArg("-pass", "");
349 bool fDumpPass = GetBoolArg("-dumppass", false);
350 bool help = GetBoolArg("-h", false);
353 PBAAS_TESTMODE = false;
363 SelectParamsFromCommandLine();
364 result = WalletUtilityDB(walletFile, "r").parseKeys(fDumpPass, masterPass);
366 catch (const std::exception& e) {
367 std::cout << "Error opening wallet file " << walletFile << std::endl;
368 std::cout << e.what() << std::endl;