mirror of
https://github.com/jwinterm/aeon.git
synced 2026-10-20 05:28:32 +02:00
version-1.4
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@@ -17,6 +18,8 @@
|
||||
#include "rpc/core_rpc_server_commands_defs.h"
|
||||
#include "wallet/wallet_rpc_server.h"
|
||||
#include "version.h"
|
||||
#include "crypto/crypto.h" // for crypto::secret_key definition
|
||||
#include "crypto/electrum-words.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <crtdbg.h>
|
||||
@@ -38,6 +41,9 @@ namespace
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_address = {"daemon-address", "Use daemon instance at <host>:<port>", ""};
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_host = {"daemon-host", "Use daemon instance at host <arg> instead of localhost", ""};
|
||||
const command_line::arg_descriptor<std::string> arg_password = {"password", "Wallet password", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_electrum_seed = {"electrum-seed", "Specify electrum seed for wallet recovery/creation", ""};
|
||||
const command_line::arg_descriptor<bool> arg_restore_deterministic_wallet = {"restore-deterministic-wallet", "Recover wallet using electrum-style mnemonic", false};
|
||||
const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", "creates non-deterministic view and spend keys", false};
|
||||
const command_line::arg_descriptor<int> arg_daemon_port = {"daemon-port", "Use daemon instance at port <arg> instead of 8081", 0};
|
||||
const command_line::arg_descriptor<uint32_t> arg_log_level = {"set_log", "", 0, true};
|
||||
|
||||
@@ -208,17 +214,25 @@ bool simple_wallet::ask_wallet_create_if_needed()
|
||||
{
|
||||
std::string wallet_path;
|
||||
|
||||
std::cout << "Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n";
|
||||
std::cout << "Wallet file name: ";
|
||||
|
||||
std::getline(std::cin, wallet_path);
|
||||
|
||||
wallet_path = string_tools::trim(wallet_path);
|
||||
wallet_path = command_line::input_line(
|
||||
"Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n"
|
||||
"Wallet file name: "
|
||||
);
|
||||
|
||||
bool keys_file_exists;
|
||||
bool wallet_file_exists;
|
||||
tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exists);
|
||||
|
||||
// add logic to error out if new wallet requested but named wallet file exists
|
||||
if (keys_file_exists || wallet_file_exists)
|
||||
{
|
||||
if (!m_generate_new.empty() || m_restore_deterministic_wallet)
|
||||
{
|
||||
fail_msg_writer() << "Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool r;
|
||||
if(keys_file_exists)
|
||||
{
|
||||
@@ -251,13 +265,14 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t c = 0;
|
||||
if(!m_generate_new.empty()) ++c;
|
||||
if(!m_wallet_file.empty()) ++c;
|
||||
if (1 != c)
|
||||
if(!m_generate_new.empty() && !m_wallet_file.empty())
|
||||
{
|
||||
if(!ask_wallet_create_if_needed())
|
||||
return false;
|
||||
fail_msg_writer() << "Specifying both --generate-new-wallet=\"wallet_name\" and --wallet-file=\"wallet_name\" doesn't make sense!";
|
||||
return false;
|
||||
}
|
||||
else if (m_generate_new.empty() && m_wallet_file.empty())
|
||||
{
|
||||
if(!ask_wallet_create_if_needed()) return false;
|
||||
}
|
||||
|
||||
if (m_daemon_host.empty())
|
||||
@@ -282,9 +297,36 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_generate_new.empty())
|
||||
if (!m_generate_new.empty() || m_restore_deterministic_wallet)
|
||||
{
|
||||
bool r = new_wallet(m_generate_new, pwd_container.password());
|
||||
if (m_wallet_file.empty()) m_wallet_file = m_generate_new; // alias for simplicity later
|
||||
|
||||
// check for recover flag. if present, require electrum word list (only recovery option for now).
|
||||
if (m_restore_deterministic_wallet)
|
||||
{
|
||||
if (m_non_deterministic)
|
||||
{
|
||||
fail_msg_writer() << "Cannot specify both --restore-deterministic-wallet and --non-deterministic";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_electrum_seed.empty())
|
||||
{
|
||||
m_electrum_seed = command_line::input_line("Specify electrum seed: ");
|
||||
if (m_electrum_seed.empty())
|
||||
{
|
||||
fail_msg_writer() << "specify a recovery parameter with the --electrum-seed=\"words list here\"";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!crypto::ElectrumWords::words_to_bytes(m_electrum_seed, m_recovery_key))
|
||||
{
|
||||
fail_msg_writer() << "electrum-style word list failed verification";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool r = new_wallet(m_wallet_file, pwd_container.password(), m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic);
|
||||
CHECK_AND_ASSERT_MES(r, false, "account creation failed");
|
||||
}
|
||||
else
|
||||
@@ -306,11 +348,14 @@ bool simple_wallet::deinit()
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void simple_wallet::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
{
|
||||
m_wallet_file = command_line::get_arg(vm, arg_wallet_file);
|
||||
m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet);
|
||||
m_daemon_address = command_line::get_arg(vm, arg_daemon_address);
|
||||
m_daemon_host = command_line::get_arg(vm, arg_daemon_host);
|
||||
m_daemon_port = command_line::get_arg(vm, arg_daemon_port);
|
||||
m_wallet_file = command_line::get_arg(vm, arg_wallet_file);
|
||||
m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet);
|
||||
m_daemon_address = command_line::get_arg(vm, arg_daemon_address);
|
||||
m_daemon_host = command_line::get_arg(vm, arg_daemon_host);
|
||||
m_daemon_port = command_line::get_arg(vm, arg_daemon_port);
|
||||
m_electrum_seed = command_line::get_arg(vm, arg_electrum_seed);
|
||||
m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet);
|
||||
m_non_deterministic = command_line::get_arg(vm, arg_non_deterministic);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::try_connect_to_daemon()
|
||||
@@ -324,16 +369,19 @@ bool simple_wallet::try_connect_to_daemon()
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password)
|
||||
bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, bool recover, bool two_random)
|
||||
{
|
||||
m_wallet_file = wallet_file;
|
||||
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet->callback(this);
|
||||
|
||||
crypto::secret_key recovery_val;
|
||||
try
|
||||
{
|
||||
m_wallet->generate(wallet_file, password);
|
||||
recovery_val = m_wallet->generate(wallet_file, password, recovery_key, recover, two_random);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Generated new wallet: " << m_wallet->get_account().get_public_address_str() << std::endl << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
@@ -344,6 +392,13 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
||||
|
||||
m_wallet->init(m_daemon_address);
|
||||
|
||||
// convert rng value to electrum-style word list
|
||||
std::string electrum_words;
|
||||
crypto::ElectrumWords::bytes_to_words(recovery_val, electrum_words);
|
||||
|
||||
std::string print_electrum = "";
|
||||
|
||||
|
||||
success_msg_writer() <<
|
||||
"**********************************************************************\n" <<
|
||||
"Your wallet has been generated.\n" <<
|
||||
@@ -351,8 +406,16 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
||||
"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" <<
|
||||
"**********************************************************************";
|
||||
"your wallet again. Your wallet key is NOT under risk anyway.\n"
|
||||
;
|
||||
|
||||
if (!two_random)
|
||||
{
|
||||
success_msg_writer(true) << "\nPLEASE NOTE: the following 24 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. You will not be able to view these words again, so it is imperative to make note of them now.\n";
|
||||
std::cout << electrum_words << std::endl;
|
||||
}
|
||||
success_msg_writer() << "**********************************************************************";
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -722,6 +785,7 @@ bool simple_wallet::show_blockchain_height(const std::vector<std::string>& args)
|
||||
fail_msg_writer() << "failed to get blockchain height: " << err;
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
{
|
||||
@@ -788,9 +852,38 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
|
||||
try
|
||||
{
|
||||
cryptonote::transaction tx;
|
||||
m_wallet->transfer(dsts, fake_outs_count, 0, DEFAULT_FEE, extra, tx);
|
||||
success_msg_writer(true) << "Money successfully sent, transaction " << get_transaction_hash(tx);
|
||||
// figure out what tx will be necessary
|
||||
auto ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, DEFAULT_FEE, extra);
|
||||
|
||||
// if more than one tx necessary, prompt user to confirm
|
||||
if (ptx_vector.size() > 1)
|
||||
{
|
||||
std::string prompt_str = "Your transaction needs to be split into ";
|
||||
prompt_str += std::to_string(ptx_vector.size());
|
||||
prompt_str += " transactions. This will result in a fee of ";
|
||||
prompt_str += print_money(ptx_vector.size() * DEFAULT_FEE);
|
||||
prompt_str += ". Is this okay? (Y/Yes/N/No)";
|
||||
std::string accepted = command_line::input_line(prompt_str);
|
||||
if (accepted != "Y" && accepted != "y" && accepted != "Yes" && accepted != "yes")
|
||||
{
|
||||
fail_msg_writer() << "Transaction cancelled.";
|
||||
|
||||
// would like to return false, because no tx made, but everything else returns true
|
||||
// and I don't know what returning false might adversely affect. *sigh*
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// actually commit the transactions
|
||||
while (!ptx_vector.empty())
|
||||
{
|
||||
auto & ptx = ptx_vector.back();
|
||||
m_wallet->commit_tx(ptx);
|
||||
success_msg_writer(true) << "Money successfully sent, transaction " << get_transaction_hash(ptx.tx);
|
||||
|
||||
// if no exception, remove element from vector
|
||||
ptx_vector.pop_back();
|
||||
}
|
||||
}
|
||||
catch (const tools::error::daemon_busy&)
|
||||
{
|
||||
@@ -836,16 +929,14 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
{
|
||||
fail_msg_writer() << e.what();
|
||||
}
|
||||
catch (const tools::error::tx_too_big& e)
|
||||
{
|
||||
cryptonote::transaction tx = e.tx();
|
||||
fail_msg_writer() << "transaction " << get_transaction_hash(e.tx()) << " is too big. Transaction size: " <<
|
||||
get_object_blobsize(e.tx()) << " bytes, transaction size limit: " << e.tx_size_limit() << " bytes";
|
||||
}
|
||||
catch (const tools::error::zero_destination&)
|
||||
{
|
||||
fail_msg_writer() << "one of destinations is zero";
|
||||
}
|
||||
catch (const tools::error::tx_too_big& e)
|
||||
{
|
||||
fail_msg_writer() << "Failed to find a suitable way to split transactions";
|
||||
}
|
||||
catch (const tools::error::transfer_error& e)
|
||||
{
|
||||
LOG_ERROR("unknown transfer error: " << e.to_string());
|
||||
@@ -916,6 +1007,9 @@ int main(int argc, char* argv[])
|
||||
command_line::add_arg(desc_params, arg_daemon_port);
|
||||
command_line::add_arg(desc_params, arg_command);
|
||||
command_line::add_arg(desc_params, arg_log_level);
|
||||
command_line::add_arg(desc_params, arg_restore_deterministic_wallet );
|
||||
command_line::add_arg(desc_params, arg_non_deterministic );
|
||||
command_line::add_arg(desc_params, arg_electrum_seed );
|
||||
tools::wallet_rpc_server::init_options(desc_params);
|
||||
|
||||
po::positional_options_description positional_options;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "wallet/wallet2.h"
|
||||
#include "console_handler.h"
|
||||
#include "password_container.h"
|
||||
#include "crypto/crypto.h" // for definition of crypto::secret_key
|
||||
|
||||
|
||||
namespace cryptonote
|
||||
@@ -39,7 +40,7 @@ namespace cryptonote
|
||||
|
||||
bool run_console_handler();
|
||||
|
||||
bool new_wallet(const std::string &wallet_file, const std::string& password);
|
||||
bool new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
|
||||
bool open_wallet(const std::string &wallet_file, const std::string& password);
|
||||
bool close_wallet();
|
||||
|
||||
@@ -53,6 +54,9 @@ namespace cryptonote
|
||||
bool show_payments(const std::vector<std::string> &args);
|
||||
bool show_blockchain_height(const std::vector<std::string> &args);
|
||||
bool transfer(const std::vector<std::string> &args);
|
||||
std::vector<std::vector<cryptonote::tx_destination_entry>> split_amounts(
|
||||
std::vector<cryptonote::tx_destination_entry> dsts, size_t num_splits
|
||||
);
|
||||
bool print_address(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
bool save(const std::vector<std::string> &args);
|
||||
bool set_log(const std::vector<std::string> &args);
|
||||
@@ -125,6 +129,12 @@ namespace cryptonote
|
||||
std::string m_generate_new;
|
||||
std::string m_import_path;
|
||||
|
||||
std::string m_electrum_seed; // electrum-style seed parameter
|
||||
|
||||
crypto::secret_key m_recovery_key; // recovery key (used as random for wallet gen)
|
||||
bool m_restore_deterministic_wallet; // recover flag
|
||||
bool m_non_deterministic; // old 2-random generation
|
||||
|
||||
std::string m_daemon_address;
|
||||
std::string m_daemon_host;
|
||||
int m_daemon_port;
|
||||
|
||||
Reference in New Issue
Block a user