From bd2c3e1950b8237b7ff98f234f308a156e2554ad Mon Sep 17 00:00:00 2001 From: foRevp2p Date: Sat, 23 Mar 2019 14:15:25 +0000 Subject: [PATCH] Keys Function --- src/SimpleWallet/SimpleWallet.cpp | 124 ++++++++++++++++++++++++++++-- src/SimpleWallet/SimpleWallet.h | 3 + 2 files changed, 121 insertions(+), 6 deletions(-) diff --git a/src/SimpleWallet/SimpleWallet.cpp b/src/SimpleWallet/SimpleWallet.cpp index 2179908..ceae9b1 100644 --- a/src/SimpleWallet/SimpleWallet.cpp +++ b/src/SimpleWallet/SimpleWallet.cpp @@ -22,6 +22,7 @@ #include "Common/CommandLine.h" #include "Common/SignalHandler.h" #include "Common/StringTools.h" +#include #include "Common/PathTools.h" #include "Common/Util.h" #include "CryptoNoteCore/CryptoNoteFormatUtils.h" @@ -558,6 +559,7 @@ simple_wallet::simple_wallet(System::Dispatcher& dispatcher, const CryptoNote::C m_consoleHandler.setHandler("start_mining", boost::bind(&simple_wallet::start_mining, this, _1), "start_mining [] - Start mining in daemon"); m_consoleHandler.setHandler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, _1), "Stop mining in daemon"); //m_consoleHandler.setHandler("refresh", boost::bind(&simple_wallet::refresh, this, _1), "Resynchronize transactions and balance"); + m_consoleHandler.setHandler("export_keys", boost::bind(&simple_wallet::export_keys, this, _1), "Show the secret keys of the opened wallet"); m_consoleHandler.setHandler("balance", boost::bind(&simple_wallet::show_balance, this, _1), "Show current wallet balance"); m_consoleHandler.setHandler("incoming_transfers", boost::bind(&simple_wallet::show_incoming_transfers, this, _1), "Show incoming transfers"); m_consoleHandler.setHandler("list_transfers", boost::bind(&simple_wallet::listTransfers, this, _1), "Show all known transfers"); @@ -605,13 +607,13 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { } if (m_generate_new.empty() && m_wallet_file_arg.empty()) { - std::cout << "Nor 'generate-new-wallet' neither 'wallet-file' argument was specified.\nWhat do you want to do?\n[O]pen existing wallet, [G]enerate new wallet file or [E]xit.\n"; + std::cout << "Nor 'generate-new-wallet' neither 'wallet-file' argument was specified.\nWhat do you want to do?\n[O]pen existing wallet\n[G]enerate new wallet file\n[I]mport wallet from keys\n[E]xit.\n"; char c; do { std::string answer; std::getline(std::cin, answer); c = answer[0]; - if (!(c == 'O' || c == 'G' || c == 'E' || c == 'o' || c == 'g' || c == 'e')) { + if (!(c == 'O' || c == 'G' || c == 'E' || c == 'I' || c == 'o' || c == 'g' || c == 'e' || c == 'i')) { std::cout << "Unknown command: " << c <getAddress())) { logger(WARNING, BRIGHT_RED) << "Couldn't write wallet address file: " + walletAddressFile; } + } else if (!m_import_new.empty()) { + std::string walletAddressFile = prepareWalletAddressFilename(m_import_new); + boost::system::error_code ignore; + if (boost::filesystem::exists(walletAddressFile, ignore)) { + logger(ERROR, BRIGHT_RED) << "Address file already exists: " + walletAddressFile; + return false; + } + + std::string private_spend_key_string; + std::string private_view_key_string; + do { + std::cout << "Private Spend Key: "; + std::getline(std::cin, private_spend_key_string); + boost::algorithm::trim(private_spend_key_string); + } while (private_spend_key_string.empty()); + do { + std::cout << "Private View Key: "; + std::getline(std::cin, private_view_key_string); + boost::algorithm::trim(private_view_key_string); + } while (private_view_key_string.empty()); + + Crypto::Hash private_spend_key_hash; + Crypto::Hash private_view_key_hash; + size_t size; + if (!Common::fromHex(private_spend_key_string, &private_spend_key_hash, sizeof(private_spend_key_hash), size) || size != sizeof(private_spend_key_hash)) { + return false; + } + if (!Common::fromHex(private_view_key_string, &private_view_key_hash, sizeof(private_view_key_hash), size) || size != sizeof(private_spend_key_hash)) { + return false; + } + Crypto::SecretKey private_spend_key = *(struct Crypto::SecretKey *) &private_spend_key_hash; + Crypto::SecretKey private_view_key = *(struct Crypto::SecretKey *) &private_view_key_hash; + + if (!new_wallet(private_spend_key, private_view_key, walletFileName, pwd_container.password())) { + logger(ERROR, BRIGHT_RED) << "account creation failed"; + return false; + } } else { m_wallet.reset(new WalletLegacy(m_currency, *m_node)); @@ -747,6 +792,60 @@ void simple_wallet::handle_command_line(const boost::program_options::variables_ m_daemon_host = command_line::get_arg(vm, arg_daemon_host); m_daemon_port = command_line::get_arg(vm, arg_daemon_port); } +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::new_wallet(Crypto::SecretKey &secret_key, Crypto::SecretKey &view_key, const std::string &wallet_file, const std::string& password) { + m_wallet_file = wallet_file; + + m_wallet.reset(new WalletLegacy(m_currency, *m_node.get())); + m_node->addObserver(static_cast(this)); + m_wallet->addObserver(this); + try { + m_initResultPromise.reset(new std::promise()); + std::future f_initError = m_initResultPromise->get_future(); + + AccountKeys wallet_keys; + wallet_keys.spendSecretKey = secret_key; + wallet_keys.viewSecretKey = view_key; + Crypto::secret_key_to_public_key(wallet_keys.spendSecretKey, wallet_keys.address.spendPublicKey); + Crypto::secret_key_to_public_key(wallet_keys.viewSecretKey, wallet_keys.address.viewPublicKey); + + m_wallet->initWithKeys(wallet_keys, password); + auto initError = f_initError.get(); + m_initResultPromise.reset(nullptr); + if (initError) { + fail_msg_writer() << "failed to generate new wallet: " << initError.message(); + return false; + } + + try { + CryptoNote::WalletHelper::storeWallet(*m_wallet, m_wallet_file); + } catch (std::exception& e) { + fail_msg_writer() << "failed to save new wallet: " << e.what(); + throw; + } + + AccountKeys keys; + m_wallet->getAccountKeys(keys); + + logger(INFO, BRIGHT_WHITE) << + "Imported wallet: " << m_wallet->getAddress() << std::endl; + } + catch (const std::exception& e) { + fail_msg_writer() << "failed to import wallet: " << e.what(); + return false; + } + + success_msg_writer() << + "**********************************************************************\n" << + "Your wallet has been imported.\n" << + "Use \"help\" command to see the list of available commands.\n" << + "Always use \"exit\" command when closing simplewallet to save\n" << + "current session's state. Otherwise, you will possibly need to synchronize \n" << + "your wallet again. Your wallet key is NOT under risk anyway.\n" << + "**********************************************************************"; + return true; +} + //---------------------------------------------------------------------------------------------------- bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string& password) { m_wallet_file = wallet_file; @@ -972,6 +1071,19 @@ bool simple_wallet::show_balance(const std::vector& args/* = std::v return true; } + +//---------------------------------------------------------------------------------------------------- + bool simple_wallet::export_keys(const std::vector& args/* = std::vector()*/) { + AccountKeys keys; + m_wallet->getAccountKeys(keys); + success_msg_writer(true) << "Spend secret key: " << Common::podToHex(keys.spendSecretKey); + success_msg_writer(true) << "View secret key: " << Common::podToHex(keys.viewSecretKey); + success_msg_writer(true) << "Private keys: " << Tools::Base58::encode_addr(parameters::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, + std::string(reinterpret_cast(&keys), sizeof(keys))); + + return true; + } + //---------------------------------------------------------------------------------------------------- bool simple_wallet::show_incoming_transfers(const std::vector& args) { bool hasTransfers = false; diff --git a/src/SimpleWallet/SimpleWallet.h b/src/SimpleWallet/SimpleWallet.h index a6fdda4..1e67ec7 100644 --- a/src/SimpleWallet/SimpleWallet.h +++ b/src/SimpleWallet/SimpleWallet.h @@ -63,6 +63,7 @@ namespace CryptoNote bool run_console_handler(); bool new_wallet(const std::string &wallet_file, const std::string& password); + bool new_wallet(Crypto::SecretKey &secret_key, Crypto::SecretKey &view_key, const std::string &wallet_file, const std::string& password); bool open_wallet(const std::string &wallet_file, const std::string& password); bool close_wallet(); @@ -71,6 +72,7 @@ namespace CryptoNote bool start_mining(const std::vector &args); bool stop_mining(const std::vector &args); bool show_balance(const std::vector &args = std::vector()); + bool export_keys(const std::vector &args = std::vector()); bool show_incoming_transfers(const std::vector &args); bool show_payments(const std::vector &args); bool show_blockchain_height(const std::vector &args); @@ -143,6 +145,7 @@ namespace CryptoNote private: std::string m_wallet_file_arg; std::string m_generate_new; + std::string m_import_new; std::string m_import_path; std::string m_daemon_address;