Remove cpp test for wallet-utility
This commit is contained in:
parent
6ca57f3e1f
commit
9e001dd04e
|
@ -15,7 +15,9 @@ EXTRA_DIST += \
|
||||||
test/data/tx394b54bb.hex \
|
test/data/tx394b54bb.hex \
|
||||||
test/data/txcreate1.hex \
|
test/data/txcreate1.hex \
|
||||||
test/data/txcreate2.hex \
|
test/data/txcreate2.hex \
|
||||||
test/data/txcreatesign.hex
|
test/data/txcreatesign.hex \
|
||||||
|
test/wallet-utility.py \
|
||||||
|
test/data/wallet.dat
|
||||||
|
|
||||||
JSON_TEST_FILES = \
|
JSON_TEST_FILES = \
|
||||||
test/data/script_valid.json \
|
test/data/script_valid.json \
|
||||||
|
@ -107,8 +109,7 @@ if ENABLE_WALLET
|
||||||
BITCOIN_TESTS += \
|
BITCOIN_TESTS += \
|
||||||
test/accounting_tests.cpp \
|
test/accounting_tests.cpp \
|
||||||
wallet/test/wallet_tests.cpp \
|
wallet/test/wallet_tests.cpp \
|
||||||
test/rpc_wallet_tests.cpp \
|
test/rpc_wallet_tests.cpp
|
||||||
test/walletutil_tests.cpp
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
||||||
|
@ -151,8 +152,10 @@ bitcoin_test_clean : FORCE
|
||||||
check-local:
|
check-local:
|
||||||
@echo "Running test/bitcoin-util-test.py..."
|
@echo "Running test/bitcoin-util-test.py..."
|
||||||
$(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py
|
$(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py
|
||||||
|
if ENABLE_WALLET
|
||||||
@echo "Running test/wallet-utility.py..."
|
@echo "Running test/wallet-utility.py..."
|
||||||
$(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/wallet-utility.py
|
$(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/wallet-utility.py
|
||||||
|
endif
|
||||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
|
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
|
||||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check
|
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check
|
||||||
|
|
||||||
|
|
|
@ -38,17 +38,6 @@ struct TestingSetup: public JoinSplitTestingSetup {
|
||||||
~TestingSetup();
|
~TestingSetup();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Wallet setup that configures a complete environment.
|
|
||||||
* Included are data directory, coins database, script check threads
|
|
||||||
* and wallet with 5 unused keys.
|
|
||||||
*/
|
|
||||||
struct WalletSetup: public BasicTestingSetup {
|
|
||||||
boost::filesystem::path pathTemp;
|
|
||||||
|
|
||||||
WalletSetup(CBaseChainParams::Network network = CBaseChainParams::MAIN);
|
|
||||||
~WalletSetup();
|
|
||||||
};
|
|
||||||
|
|
||||||
class CTxMemPoolEntry;
|
class CTxMemPoolEntry;
|
||||||
class CTxMemPool;
|
class CTxMemPool;
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
from subprocess import check_output
|
import subprocess
|
||||||
import json
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import buildenv
|
||||||
|
import shutil
|
||||||
|
|
||||||
def assert_equal(thing1, thing2):
|
def assert_equal(thing1, thing2):
|
||||||
if thing1 != thing2:
|
if thing1 != thing2:
|
||||||
|
@ -14,13 +16,46 @@ def assert_equal(thing1, thing2):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
datadir = os.environ["srcdir"] + "/test/data"
|
datadir = os.environ["srcdir"] + "/test/data"
|
||||||
command = os.environ["srcdir"] + "/wallet-utility"
|
execprog = './wallet-utility' + buildenv.exeext
|
||||||
|
execargs = '-datadir=' + datadir
|
||||||
|
execrun = execprog + ' ' + execargs
|
||||||
|
|
||||||
output = json.loads(check_output([command, "-datadir=" + datadir]))
|
proc = subprocess.Popen(execrun, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True)
|
||||||
|
try:
|
||||||
|
outs = proc.communicate()
|
||||||
|
except OSError:
|
||||||
|
print("OSError, Failed to execute " + execprog)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
assert_equal(output[0], "13EngsxkRi7SJPPqCyJsKf34U8FoX9E9Av");
|
output = json.loads(outs[0])
|
||||||
assert_equal(output[1], "1FKCLGTpPeYBUqfNxktck8k5nqxB8sjim8");
|
|
||||||
assert_equal(output[2], "13cdtE9tnNeXCZJ8KQ5WELgEmLSBLnr48F");
|
|
||||||
|
|
||||||
|
assert_equal(output[0], "13EngsxkRi7SJPPqCyJsKf34U8FoX9E9Av")
|
||||||
|
assert_equal(output[1], "1FKCLGTpPeYBUqfNxktck8k5nqxB8sjim8")
|
||||||
|
assert_equal(output[2], "13cdtE9tnNeXCZJ8KQ5WELgEmLSBLnr48F")
|
||||||
|
|
||||||
|
execargs = '-datadir=' + datadir + ' -dumppass'
|
||||||
|
execrun = execprog + ' ' + execargs
|
||||||
|
|
||||||
|
proc = subprocess.Popen(execrun, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True)
|
||||||
|
try:
|
||||||
|
outs = proc.communicate()
|
||||||
|
except OSError:
|
||||||
|
print("OSError, Failed to execute " + execprog)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
output = json.loads(outs[0])
|
||||||
|
|
||||||
|
assert_equal(output[0]['addr'], "13EngsxkRi7SJPPqCyJsKf34U8FoX9E9Av")
|
||||||
|
assert_equal(output[0]['pkey'], "5Jz5BWE2WQxp1hGqDZeisQFV1mRFR2AVBAgiXCbNcZyXNjD9aUd")
|
||||||
|
assert_equal(output[1]['addr'], "1FKCLGTpPeYBUqfNxktck8k5nqxB8sjim8")
|
||||||
|
assert_equal(output[1]['pkey'], "5HsX2b3v2GjngYQ5ZM4mLp2b2apw6aMNVaPELV1YmpiYR1S4jzc")
|
||||||
|
assert_equal(output[2]['addr'], "13cdtE9tnNeXCZJ8KQ5WELgEmLSBLnr48F")
|
||||||
|
assert_equal(output[2]['pkey'], "5KCWAs1wX2ESiL4PfDR8XYVSSETHFd2jaRGxt1QdanBFTit4XcH")
|
||||||
|
|
||||||
|
if os.path.exists(datadir + '/database'):
|
||||||
|
if os.path.isdir(datadir + '/database'):
|
||||||
|
shutil.rmtree(datadir + '/database')
|
||||||
|
|
||||||
|
if os.path.exists(datadir + '/db.log'):
|
||||||
|
os.remove(datadir + '/db.log')
|
||||||
|
sys.exit(0)
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
#include "main.h"
|
|
||||||
#include "test/test_bitcoin.h"
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <boost/filesystem/fstream.hpp>
|
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
#include "wallet/db.h"
|
|
||||||
#include "wallet/wallet.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(walletutil_tests, BasicTestingSetup)
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(walletutil_test)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* addresses and private keys in test/data/wallet.dat
|
|
||||||
*/
|
|
||||||
string expected_addr = "[ \"13EngsxkRi7SJPPqCyJsKf34U8FoX9E9Av\", \"1FKCLGTpPeYBUqfNxktck8k5nqxB8sjim8\", \"13cdtE9tnNeXCZJ8KQ5WELgEmLSBLnr48F\" ]\n";
|
|
||||||
string expected_addr_pkeys = "[ {\"addr\" : \"13EngsxkRi7SJPPqCyJsKf34U8FoX9E9Av\", \"pkey\" : \"5Jz5BWE2WQxp1hGqDZeisQFV1mRFR2AVBAgiXCbNcZyXNjD9aUd\"}, {\"addr\" : \"1FKCLGTpPeYBUqfNxktck8k5nqxB8sjim8\", \"pkey\" : \"5HsX2b3v2GjngYQ5ZM4mLp2b2apw6aMNVaPELV1YmpiYR1S4jzc\"}, {\"addr\" : \"13cdtE9tnNeXCZJ8KQ5WELgEmLSBLnr48F\", \"pkey\" : \"5KCWAs1wX2ESiL4PfDR8XYVSSETHFd2jaRGxt1QdanBFTit4XcH\"} ]\n";
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
string strCmd = "wallet-utility -datadir=test/data/ > test/data/op.txt";
|
|
||||||
#else
|
|
||||||
string strCmd = "./wallet-utility -datadir=test/data/ > test/data/op.txt";
|
|
||||||
#endif
|
|
||||||
int ret = system(strCmd.c_str());
|
|
||||||
BOOST_CHECK(ret == 0);
|
|
||||||
|
|
||||||
boost::filesystem::path opPath = "test/data/op.txt";
|
|
||||||
boost::filesystem::ifstream fIn;
|
|
||||||
fIn.open(opPath, std::ios::in);
|
|
||||||
|
|
||||||
if (!fIn)
|
|
||||||
{
|
|
||||||
std::cerr << "Could not open the output file" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
stringstream ss_addr;
|
|
||||||
ss_addr << fIn.rdbuf();
|
|
||||||
fIn.close();
|
|
||||||
boost::filesystem::remove(opPath);
|
|
||||||
|
|
||||||
string obtained = ss_addr.str();
|
|
||||||
BOOST_CHECK_EQUAL(obtained, expected_addr);
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
strCmd = "wallet-utility -datadir=test/data/ -dumppass > test/data/op.txt";
|
|
||||||
#else
|
|
||||||
strCmd = "./wallet-utility -datadir=test/data/ -dumppass > test/data/op.txt";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = system(strCmd.c_str());
|
|
||||||
BOOST_CHECK(ret == 0);
|
|
||||||
|
|
||||||
fIn.open(opPath, std::ios::in);
|
|
||||||
|
|
||||||
if (!fIn)
|
|
||||||
{
|
|
||||||
std::cerr << "Could not open the output file" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
stringstream ss_addr_pkeys;
|
|
||||||
ss_addr_pkeys << fIn.rdbuf();
|
|
||||||
fIn.close();
|
|
||||||
boost::filesystem::remove(opPath);
|
|
||||||
|
|
||||||
obtained = ss_addr_pkeys.str();
|
|
||||||
BOOST_CHECK_EQUAL(obtained, expected_addr_pkeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
|
|
@ -11,49 +11,49 @@
|
||||||
|
|
||||||
void show_help()
|
void show_help()
|
||||||
{
|
{
|
||||||
std::cout <<
|
std::cout <<
|
||||||
"This program outputs Bitcoin addresses and private keys from a wallet.dat file" << std::endl
|
"This program outputs Bitcoin addresses and private keys from a wallet.dat file" << std::endl
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< "Usage and options: "
|
<< "Usage and options: "
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " -datadir=<directory> to tell the program where your wallet is"
|
<< " -datadir=<directory> to tell the program where your wallet is"
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " -wallet=<name> (Optional) if your wallet is not named wallet.dat"
|
<< " -wallet=<name> (Optional) if your wallet is not named wallet.dat"
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " -regtest or -testnet (Optional) dumps addresses from regtest/testnet"
|
<< " -regtest or -testnet (Optional) dumps addresses from regtest/testnet"
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " -dumppass (Optional)if you want to extract private keys associated with addresses"
|
<< " -dumppass (Optional)if you want to extract private keys associated with addresses"
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " -pass=<walletpassphrase> if you have encrypted private keys stored in your wallet"
|
<< " -pass=<walletpassphrase> if you have encrypted private keys stored in your wallet"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class WalletUtilityDB : public CDB
|
class WalletUtilityDB : public CDB
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
|
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
|
||||||
MasterKeyMap mapMasterKeys;
|
MasterKeyMap mapMasterKeys;
|
||||||
unsigned int nMasterKeyMaxID;
|
unsigned int nMasterKeyMaxID;
|
||||||
SecureString mPass;
|
SecureString mPass;
|
||||||
std::vector<CKeyingMaterial> vMKeys;
|
std::vector<CKeyingMaterial> vMKeys;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WalletUtilityDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose)
|
WalletUtilityDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose)
|
||||||
{
|
{
|
||||||
nMasterKeyMaxID = 0;
|
nMasterKeyMaxID = 0;
|
||||||
mPass.reserve(100);
|
mPass.reserve(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getAddress(CDataStream ssKey);
|
std::string getAddress(CDataStream ssKey);
|
||||||
std::string getKey(CDataStream ssKey, CDataStream ssValue);
|
std::string getKey(CDataStream ssKey, CDataStream ssValue);
|
||||||
std::string getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass);
|
std::string getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass);
|
||||||
bool updateMasterKeys(CDataStream ssKey, CDataStream ssValue);
|
bool updateMasterKeys(CDataStream ssKey, CDataStream ssValue);
|
||||||
bool parseKeys(bool dumppriv, std::string masterPass);
|
bool parseKeys(bool dumppriv, std::string masterPass);
|
||||||
|
|
||||||
bool DecryptSecret(const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
|
bool DecryptSecret(const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
|
||||||
bool Unlock();
|
bool Unlock();
|
||||||
bool DecryptKey(const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key);
|
bool DecryptKey(const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,12 +62,12 @@ class WalletUtilityDB : public CDB
|
||||||
*/
|
*/
|
||||||
std::string WalletUtilityDB::getAddress(CDataStream ssKey)
|
std::string WalletUtilityDB::getAddress(CDataStream ssKey)
|
||||||
{
|
{
|
||||||
CPubKey vchPubKey;
|
CPubKey vchPubKey;
|
||||||
ssKey >> vchPubKey;
|
ssKey >> vchPubKey;
|
||||||
CKeyID id = vchPubKey.GetID();
|
CKeyID id = vchPubKey.GetID();
|
||||||
std::string strAddr = CBitcoinAddress(id).ToString();
|
std::string strAddr = CBitcoinAddress(id).ToString();
|
||||||
|
|
||||||
return strAddr;
|
return strAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,65 +76,65 @@ std::string WalletUtilityDB::getAddress(CDataStream ssKey)
|
||||||
*/
|
*/
|
||||||
std::string WalletUtilityDB::getKey(CDataStream ssKey, CDataStream ssValue)
|
std::string WalletUtilityDB::getKey(CDataStream ssKey, CDataStream ssValue)
|
||||||
{
|
{
|
||||||
std::string strKey;
|
std::string strKey;
|
||||||
CPubKey vchPubKey;
|
CPubKey vchPubKey;
|
||||||
ssKey >> vchPubKey;
|
ssKey >> vchPubKey;
|
||||||
CPrivKey pkey;
|
CPrivKey pkey;
|
||||||
CKey key;
|
CKey key;
|
||||||
|
|
||||||
ssValue >> pkey;
|
ssValue >> pkey;
|
||||||
if (key.Load(pkey, vchPubKey, true))
|
if (key.Load(pkey, vchPubKey, true))
|
||||||
strKey = CBitcoinSecret(key).ToString();
|
strKey = CBitcoinSecret(key).ToString();
|
||||||
|
|
||||||
return strKey;
|
return strKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool WalletUtilityDB::DecryptSecret(const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
|
bool WalletUtilityDB::DecryptSecret(const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
|
||||||
{
|
{
|
||||||
CCrypter cKeyCrypter;
|
CCrypter cKeyCrypter;
|
||||||
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
|
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
|
||||||
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
|
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
|
||||||
|
|
||||||
BOOST_FOREACH(const CKeyingMaterial vMKey, vMKeys)
|
BOOST_FOREACH(const CKeyingMaterial vMKey, vMKeys)
|
||||||
{
|
{
|
||||||
if(!cKeyCrypter.SetKey(vMKey, chIV))
|
if(!cKeyCrypter.SetKey(vMKey, chIV))
|
||||||
continue;
|
continue;
|
||||||
if (cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)))
|
if (cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool WalletUtilityDB::Unlock()
|
bool WalletUtilityDB::Unlock()
|
||||||
{
|
{
|
||||||
CCrypter crypter;
|
CCrypter crypter;
|
||||||
CKeyingMaterial vMasterKey;
|
CKeyingMaterial vMasterKey;
|
||||||
|
|
||||||
BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
|
BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
|
||||||
{
|
{
|
||||||
if(!crypter.SetKeyFromPassphrase(mPass, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
|
if(!crypter.SetKeyFromPassphrase(mPass, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
|
||||||
return false;
|
return false;
|
||||||
if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
|
if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
|
||||||
continue; // try another master key
|
continue; // try another master key
|
||||||
vMKeys.push_back(vMasterKey);
|
vMKeys.push_back(vMasterKey);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool WalletUtilityDB::DecryptKey(const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key)
|
bool WalletUtilityDB::DecryptKey(const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key)
|
||||||
{
|
{
|
||||||
CKeyingMaterial vchSecret;
|
CKeyingMaterial vchSecret;
|
||||||
if(!DecryptSecret(vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
if(!DecryptSecret(vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (vchSecret.size() != 32)
|
if (vchSecret.size() != 32)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
|
key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,22 +143,22 @@ bool WalletUtilityDB::DecryptKey(const std::vector<unsigned char>& vchCryptedSec
|
||||||
*/
|
*/
|
||||||
std::string WalletUtilityDB::getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass)
|
std::string WalletUtilityDB::getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass)
|
||||||
{
|
{
|
||||||
mPass = masterPass.c_str();
|
mPass = masterPass.c_str();
|
||||||
CPubKey vchPubKey;
|
CPubKey vchPubKey;
|
||||||
ssKey >> vchPubKey;
|
ssKey >> vchPubKey;
|
||||||
CKey key;
|
CKey key;
|
||||||
|
|
||||||
std::vector<unsigned char> vKey;
|
std::vector<unsigned char> vKey;
|
||||||
ssValue >> vKey;
|
ssValue >> vKey;
|
||||||
|
|
||||||
if (!Unlock())
|
if (!Unlock())
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
if(!DecryptKey(vKey, vchPubKey, key))
|
if(!DecryptKey(vKey, vchPubKey, key))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
std::string strKey = CBitcoinSecret(key).ToString();
|
std::string strKey = CBitcoinSecret(key).ToString();
|
||||||
return strKey;
|
return strKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,21 +167,21 @@ std::string WalletUtilityDB::getCryptedKey(CDataStream ssKey, CDataStream ssValu
|
||||||
*/
|
*/
|
||||||
bool WalletUtilityDB::updateMasterKeys(CDataStream ssKey, CDataStream ssValue)
|
bool WalletUtilityDB::updateMasterKeys(CDataStream ssKey, CDataStream ssValue)
|
||||||
{
|
{
|
||||||
unsigned int nID;
|
unsigned int nID;
|
||||||
ssKey >> nID;
|
ssKey >> nID;
|
||||||
CMasterKey kMasterKey;
|
CMasterKey kMasterKey;
|
||||||
ssValue >> kMasterKey;
|
ssValue >> kMasterKey;
|
||||||
if (mapMasterKeys.count(nID) != 0)
|
if (mapMasterKeys.count(nID) != 0)
|
||||||
{
|
{
|
||||||
std::cout << "Error reading wallet database: duplicate CMasterKey id " << nID << std::endl;
|
std::cout << "Error reading wallet database: duplicate CMasterKey id " << nID << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mapMasterKeys[nID] = kMasterKey;
|
mapMasterKeys[nID] = kMasterKey;
|
||||||
|
|
||||||
if (nMasterKeyMaxID < nID)
|
if (nMasterKeyMaxID < nID)
|
||||||
nMasterKeyMaxID = nID;
|
nMasterKeyMaxID = nID;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -190,150 +190,150 @@ bool WalletUtilityDB::updateMasterKeys(CDataStream ssKey, CDataStream ssValue)
|
||||||
*/
|
*/
|
||||||
bool WalletUtilityDB::parseKeys(bool dumppriv, std::string masterPass)
|
bool WalletUtilityDB::parseKeys(bool dumppriv, std::string masterPass)
|
||||||
{
|
{
|
||||||
DBErrors result = DB_LOAD_OK;
|
DBErrors result = DB_LOAD_OK;
|
||||||
std::string strType;
|
std::string strType;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Dbc* pcursor = GetCursor();
|
Dbc* pcursor = GetCursor();
|
||||||
if (!pcursor)
|
if (!pcursor)
|
||||||
{
|
{
|
||||||
LogPrintf("Error getting wallet database cursor\n");
|
LogPrintf("Error getting wallet database cursor\n");
|
||||||
result = DB_CORRUPT;
|
result = DB_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dumppriv)
|
if (dumppriv)
|
||||||
{
|
{
|
||||||
while (result == DB_LOAD_OK && true)
|
while (result == DB_LOAD_OK && true)
|
||||||
{
|
{
|
||||||
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
||||||
int result = ReadAtCursor(pcursor, ssKey, ssValue);
|
int result = ReadAtCursor(pcursor, ssKey, ssValue);
|
||||||
|
|
||||||
if (result == DB_NOTFOUND) {
|
if (result == DB_NOTFOUND) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (result != 0)
|
else if (result != 0)
|
||||||
{
|
{
|
||||||
LogPrintf("Error reading next record from wallet database\n");
|
LogPrintf("Error reading next record from wallet database\n");
|
||||||
result = DB_CORRUPT;
|
result = DB_CORRUPT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssKey >> strType;
|
ssKey >> strType;
|
||||||
if (strType == "mkey")
|
if (strType == "mkey")
|
||||||
{
|
{
|
||||||
updateMasterKeys(ssKey, ssValue);
|
updateMasterKeys(ssKey, ssValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pcursor->close();
|
pcursor->close();
|
||||||
pcursor = GetCursor();
|
pcursor = GetCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (result == DB_LOAD_OK && true)
|
while (result == DB_LOAD_OK && true)
|
||||||
{
|
{
|
||||||
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
||||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
|
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
|
||||||
|
|
||||||
if (ret == DB_NOTFOUND)
|
if (ret == DB_NOTFOUND)
|
||||||
{
|
{
|
||||||
std::cout << " ]" << std::endl;
|
std::cout << " ]" << std::endl;
|
||||||
first = true;
|
first = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (ret != DB_LOAD_OK)
|
else if (ret != DB_LOAD_OK)
|
||||||
{
|
{
|
||||||
LogPrintf("Error reading next record from wallet database\n");
|
LogPrintf("Error reading next record from wallet database\n");
|
||||||
result = DB_CORRUPT;
|
result = DB_CORRUPT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssKey >> strType;
|
ssKey >> strType;
|
||||||
|
|
||||||
if (strType == "key" || strType == "ckey")
|
if (strType == "key" || strType == "ckey")
|
||||||
{
|
{
|
||||||
std::string strAddr = getAddress(ssKey);
|
std::string strAddr = getAddress(ssKey);
|
||||||
std::string strKey = "";
|
std::string strKey = "";
|
||||||
|
|
||||||
|
|
||||||
if (dumppriv && strType == "key")
|
if (dumppriv && strType == "key")
|
||||||
strKey = getKey(ssKey, ssValue);
|
strKey = getKey(ssKey, ssValue);
|
||||||
if (dumppriv && strType == "ckey")
|
if (dumppriv && strType == "ckey")
|
||||||
{
|
{
|
||||||
if (masterPass == "")
|
if (masterPass == "")
|
||||||
{
|
{
|
||||||
std::cout << "Encrypted wallet, please provide a password. See help below" << std::endl;
|
std::cout << "Encrypted wallet, please provide a password. See help below" << std::endl;
|
||||||
show_help();
|
show_help();
|
||||||
result = DB_LOAD_FAIL;
|
result = DB_LOAD_FAIL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
strKey = getCryptedKey(ssKey, ssValue, masterPass);
|
strKey = getCryptedKey(ssKey, ssValue, masterPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strAddr != "")
|
if (strAddr != "")
|
||||||
{
|
{
|
||||||
if (first)
|
if (first)
|
||||||
std::cout << "[ ";
|
std::cout << "[ ";
|
||||||
else
|
else
|
||||||
std::cout << ", ";
|
std::cout << ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dumppriv)
|
if (dumppriv)
|
||||||
{
|
{
|
||||||
std::cout << "{\"addr\" : \"" + strAddr + "\", "
|
std::cout << "{\"addr\" : \"" + strAddr + "\", "
|
||||||
<< "\"pkey\" : \"" + strKey + "\"}"
|
<< "\"pkey\" : \"" + strKey + "\"}"
|
||||||
<< std::flush;
|
<< std::flush;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "\"" + strAddr + "\"";
|
std::cout << "\"" + strAddr + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcursor->close();
|
pcursor->close();
|
||||||
} catch (DbException &e) {
|
} catch (DbException &e) {
|
||||||
std::cout << "DBException caught " << e.get_errno() << std::endl;
|
std::cout << "DBException caught " << e.get_errno() << std::endl;
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
std::cout << "Exception caught " << std::endl;
|
std::cout << "Exception caught " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == DB_LOAD_OK)
|
if (result == DB_LOAD_OK)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
ParseParameters(argc, argv);
|
ParseParameters(argc, argv);
|
||||||
std::string walletFile = GetArg("-wallet", "wallet.dat");
|
std::string walletFile = GetArg("-wallet", "wallet.dat");
|
||||||
std::string masterPass = GetArg("-pass", "");
|
std::string masterPass = GetArg("-pass", "");
|
||||||
bool fDumpPass = GetBoolArg("-dumppass", false);
|
bool fDumpPass = GetBoolArg("-dumppass", false);
|
||||||
bool help = GetBoolArg("-h", false);
|
bool help = GetBoolArg("-h", false);
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if (help)
|
if (help)
|
||||||
{
|
{
|
||||||
show_help();
|
show_help();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SelectParamsFromCommandLine();
|
SelectParamsFromCommandLine();
|
||||||
result = WalletUtilityDB(walletFile, "r").parseKeys(fDumpPass, masterPass);
|
result = WalletUtilityDB(walletFile, "r").parseKeys(fDumpPass, masterPass);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cout << "Error opening wallet file " << walletFile << std::endl;
|
std::cout << "Error opening wallet file " << walletFile << std::endl;
|
||||||
std::cout << e.what() << std::endl;
|
std::cout << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue