Merge pull request #196
f9822c4
wallet JSON update for non-deterministic wallet data (warptangent)4c6230d
Checking and handling for deterministic vs non-deterministic wallet (warptangent)1beedb9
Extract check for deterministic keys to wallet2::is_deterministic() (warptangent)359ede3
indentation (warptangent)2290eff
replace lines with call to recently added print_seed() (warptangent)
This commit is contained in:
commit
ebb117c7b6
3 changed files with 66 additions and 33 deletions
|
@ -206,22 +206,23 @@ bool simple_wallet::viewkey(const std::vector<std::string> &args/* = std::vector
|
||||||
|
|
||||||
bool simple_wallet::seed(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
bool simple_wallet::seed(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||||
{
|
{
|
||||||
|
bool success = false;
|
||||||
std::string electrum_words;
|
std::string electrum_words;
|
||||||
|
|
||||||
|
if (m_wallet->is_deterministic())
|
||||||
|
{
|
||||||
if (m_wallet->get_seed_language().empty())
|
if (m_wallet->get_seed_language().empty())
|
||||||
{
|
{
|
||||||
std::string mnemonic_language = get_mnemonic_language();
|
std::string mnemonic_language = get_mnemonic_language();
|
||||||
m_wallet->set_seed_language(mnemonic_language);
|
m_wallet->set_seed_language(mnemonic_language);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = m_wallet->get_seed(electrum_words);
|
success = m_wallet->get_seed(electrum_words);
|
||||||
|
}
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
success_msg_writer(true) << "\nPLEASE NOTE: the following 25 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.\n";
|
print_seed(electrum_words);
|
||||||
boost::replace_nth(electrum_words, " ", 15, "\n");
|
|
||||||
boost::replace_nth(electrum_words, " ", 7, "\n");
|
|
||||||
std::cout << electrum_words << std::endl;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -511,9 +512,11 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string
|
||||||
crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed));
|
crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed));
|
||||||
|
|
||||||
std::string mnemonic_language = old_language;
|
std::string mnemonic_language = old_language;
|
||||||
// Ask for seed language if it is not a wallet restore or if it was a deprecated wallet
|
// Ask for seed language if:
|
||||||
// that was earlier used before this restore.
|
// it's a deterministic wallet AND
|
||||||
if (!m_restore_deterministic_wallet || was_deprecated_wallet)
|
// (it is not a wallet restore OR if it was a deprecated wallet
|
||||||
|
// that was earlier used before this restore)
|
||||||
|
if ((!two_random) && (!m_restore_deterministic_wallet || was_deprecated_wallet))
|
||||||
{
|
{
|
||||||
if (was_deprecated_wallet)
|
if (was_deprecated_wallet)
|
||||||
{
|
{
|
||||||
|
@ -583,7 +586,10 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa
|
||||||
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
||||||
// If the wallet file is deprecated, we should ask for mnemonic language again and store
|
// If the wallet file is deprecated, we should ask for mnemonic language again and store
|
||||||
// everything in the new format.
|
// everything in the new format.
|
||||||
if (!m_non_deterministic && m_wallet->is_deprecated())
|
// NOTE: this is_deprecated() refers to the wallet file format before becoming JSON. It does not refer to the "old english" seed words form of "deprecated" used elsewhere.
|
||||||
|
if (m_wallet->is_deprecated())
|
||||||
|
{
|
||||||
|
if (m_wallet->is_deterministic())
|
||||||
{
|
{
|
||||||
message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " <<
|
message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " <<
|
||||||
"a deprecated version of the wallet. Please proceed to upgrade your wallet.\n";
|
"a deprecated version of the wallet. Please proceed to upgrade your wallet.\n";
|
||||||
|
@ -596,6 +602,13 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa
|
||||||
m_wallet->get_seed(seed);
|
m_wallet->get_seed(seed);
|
||||||
print_seed(seed);
|
print_seed(seed);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " <<
|
||||||
|
"a deprecated version of the wallet. Your wallet file format is being upgraded now.\n";
|
||||||
|
m_wallet->rewrite(m_wallet_file, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,8 +89,23 @@ void wallet2::init(const std::string& daemon_address, uint64_t upper_transaction
|
||||||
m_daemon_address = daemon_address;
|
m_daemon_address = daemon_address;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
bool wallet2::is_deterministic()
|
||||||
|
{
|
||||||
|
crypto::secret_key second;
|
||||||
|
keccak((uint8_t *)&get_account().get_keys().m_spend_secret_key, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key));
|
||||||
|
sc_reduce32((uint8_t *)&second);
|
||||||
|
bool keys_deterministic = memcmp(second.data,get_account().get_keys().m_view_secret_key.data, sizeof(crypto::secret_key)) == 0;
|
||||||
|
return keys_deterministic;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool wallet2::get_seed(std::string& electrum_words)
|
bool wallet2::get_seed(std::string& electrum_words)
|
||||||
{
|
{
|
||||||
|
bool keys_deterministic = is_deterministic();
|
||||||
|
if (!keys_deterministic)
|
||||||
|
{
|
||||||
|
std::cout << "This is not a deterministic wallet" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (seed_language.empty())
|
if (seed_language.empty())
|
||||||
{
|
{
|
||||||
std::cout << "seed_language not set" << std::endl;
|
std::cout << "seed_language not set" << std::endl;
|
||||||
|
@ -99,12 +114,7 @@ bool wallet2::get_seed(std::string& electrum_words)
|
||||||
|
|
||||||
crypto::ElectrumWords::bytes_to_words(get_account().get_keys().m_spend_secret_key, electrum_words, seed_language);
|
crypto::ElectrumWords::bytes_to_words(get_account().get_keys().m_spend_secret_key, electrum_words, seed_language);
|
||||||
|
|
||||||
crypto::secret_key second;
|
return true;
|
||||||
keccak((uint8_t *)&get_account().get_keys().m_spend_secret_key, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key));
|
|
||||||
|
|
||||||
sc_reduce32((uint8_t *)&second);
|
|
||||||
|
|
||||||
return memcmp(second.data,get_account().get_keys().m_view_secret_key.data, sizeof(crypto::secret_key)) == 0;
|
|
||||||
}
|
}
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets the seed language
|
* \brief Gets the seed language
|
||||||
|
@ -476,8 +486,11 @@ bool wallet2::store_keys(const std::string& keys_file_name, const std::string& p
|
||||||
rapidjson::Value value(rapidjson::kStringType);
|
rapidjson::Value value(rapidjson::kStringType);
|
||||||
value.SetString(account_data.c_str(), account_data.length());
|
value.SetString(account_data.c_str(), account_data.length());
|
||||||
json.AddMember("key_data", value, json.GetAllocator());
|
json.AddMember("key_data", value, json.GetAllocator());
|
||||||
|
if (!seed_language.empty())
|
||||||
|
{
|
||||||
value.SetString(seed_language.c_str(), seed_language.length());
|
value.SetString(seed_language.c_str(), seed_language.length());
|
||||||
json.AddMember("seed_language", value, json.GetAllocator());
|
json.AddMember("seed_language", value, json.GetAllocator());
|
||||||
|
}
|
||||||
|
|
||||||
// Serialize the JSON object
|
// Serialize the JSON object
|
||||||
rapidjson::StringBuffer buffer;
|
rapidjson::StringBuffer buffer;
|
||||||
|
@ -543,9 +556,12 @@ void wallet2::load_keys(const std::string& keys_file_name, const std::string& pa
|
||||||
{
|
{
|
||||||
account_data = std::string(json["key_data"].GetString(), json["key_data"].GetString() +
|
account_data = std::string(json["key_data"].GetString(), json["key_data"].GetString() +
|
||||||
json["key_data"].GetStringLength());
|
json["key_data"].GetStringLength());
|
||||||
|
if (json.HasMember("seed_language"))
|
||||||
|
{
|
||||||
set_seed_language(std::string(json["seed_language"].GetString(), json["seed_language"].GetString() +
|
set_seed_language(std::string(json["seed_language"].GetString(), json["seed_language"].GetString() +
|
||||||
json["seed_language"].GetStringLength()));
|
json["seed_language"].GetStringLength()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const cryptonote::account_keys& keys = m_account.get_keys();
|
const cryptonote::account_keys& keys = m_account.get_keys();
|
||||||
r = epee::serialization::load_t_from_binary(m_account, account_data);
|
r = epee::serialization::load_t_from_binary(m_account, account_data);
|
||||||
|
|
|
@ -168,6 +168,10 @@ namespace tools
|
||||||
i_wallet2_callback* callback() const { return m_callback; }
|
i_wallet2_callback* callback() const { return m_callback; }
|
||||||
void callback(i_wallet2_callback* callback) { m_callback = callback; }
|
void callback(i_wallet2_callback* callback) { m_callback = callback; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks if deterministic wallet
|
||||||
|
*/
|
||||||
|
bool is_deterministic();
|
||||||
bool get_seed(std::string& electrum_words);
|
bool get_seed(std::string& electrum_words);
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets the seed language
|
* \brief Gets the seed language
|
||||||
|
|
Loading…
Reference in a new issue