added --generate-from-svb-key functionality (#53)
Co-authored-by: Some Random Crypto Guy <somerandomcryptoguy@protonmail.com>
This commit is contained in:
committed by
GitHub
parent
7f25459169
commit
0c4998b091
@@ -336,6 +336,34 @@ void carrot_and_legacy_account::set_keys(const cryptonote::account_keys& keys, b
|
||||
m_keys.m_carrot_main_address = keys.m_carrot_main_address;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void carrot_and_legacy_account::create_from_svb_key(const cryptonote::account_public_address& address, const crypto::secret_key& svb_key)
|
||||
{
|
||||
// top level keys
|
||||
m_keys.s_master = crypto::null_skey;
|
||||
make_carrot_provespend_key(m_keys.s_master, m_keys.k_prove_spend);
|
||||
m_keys.s_view_balance = svb_key;
|
||||
|
||||
// view balance keys
|
||||
make_carrot_viewincoming_key(m_keys.s_view_balance, m_keys.k_view_incoming);
|
||||
make_carrot_generateimage_key(m_keys.s_view_balance, m_keys.k_generate_image);
|
||||
make_carrot_generateaddress_secret(m_keys.s_view_balance, m_keys.s_generate_address);
|
||||
|
||||
// carrot account address - use the provided address spend pubkey
|
||||
m_keys.m_carrot_account_address = address;
|
||||
k_view_incoming_dev.view_key_scalar_mult_ed25519(m_keys.m_carrot_account_address.m_spend_public_key,
|
||||
m_keys.m_carrot_account_address.m_view_public_key
|
||||
);
|
||||
|
||||
// carrot main wallet address
|
||||
m_keys.m_carrot_main_address = address;
|
||||
k_view_incoming_dev.view_key_scalar_mult_ed25519(crypto::get_G(),
|
||||
m_keys.m_carrot_main_address.m_view_public_key
|
||||
);
|
||||
|
||||
this->default_derive_type = AddressDeriveType::Carrot;
|
||||
generate_subaddress_map();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_derive_type)
|
||||
{
|
||||
// top level keys
|
||||
@@ -354,6 +382,7 @@ void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_
|
||||
m_keys.m_carrot_account_address.m_spend_public_key,
|
||||
m_keys.m_carrot_account_address.m_view_public_key
|
||||
);
|
||||
m_keys.m_carrot_account_address.m_is_carrot = true;
|
||||
|
||||
// carrot main wallet address
|
||||
m_keys.m_carrot_main_address.m_spend_public_key = m_keys.m_carrot_account_address.m_spend_public_key;
|
||||
@@ -361,6 +390,7 @@ void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_
|
||||
crypto::get_G(),
|
||||
m_keys.m_carrot_main_address.m_view_public_key
|
||||
);
|
||||
m_keys.m_carrot_main_address.m_is_carrot = true;
|
||||
|
||||
this->default_derive_type = default_derive_type;
|
||||
generate_subaddress_map();
|
||||
|
||||
@@ -153,6 +153,7 @@ namespace carrot
|
||||
const AddressDeriveType default_derive_type = AddressDeriveType::Carrot
|
||||
);
|
||||
|
||||
void create_from_svb_key(const cryptonote::account_public_address& address, const crypto::secret_key& svb_key);
|
||||
void set_carrot_keys(const AddressDeriveType default_derive_type = AddressDeriveType::Carrot);
|
||||
void insert_subaddresses(const std::unordered_map<crypto::public_key, subaddress_index_extended>& subaddress_map);
|
||||
void insert_return_output_info(
|
||||
|
||||
@@ -192,6 +192,7 @@ namespace
|
||||
const command_line::arg_descriptor<std::string> arg_generate_new_wallet = {"generate-new-wallet", sw::tr("Generate new wallet and save it to <arg>"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_device = {"generate-from-device", sw::tr("Generate new wallet from device and save it to <arg>"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_view_key = {"generate-from-view-key", sw::tr("Generate incoming-only wallet from view key"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_svb_key = {"generate-from-svb-key", sw::tr("Generate full view-only wallet from view key"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_spend_key = {"generate-from-spend-key", sw::tr("Generate deterministic wallet from spend key"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_keys = {"generate-from-keys", sw::tr("Generate wallet from private keys"), ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_from_multisig_keys = {"generate-from-multisig-keys", sw::tr("Generate a master wallet from multisig wallet keys"), ""};
|
||||
@@ -4424,12 +4425,12 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
|
||||
bool welcome = false;
|
||||
|
||||
if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_device.empty()) + (!m_generate_from_view_key.empty()) + (!m_generate_from_spend_key.empty()) + (!m_generate_from_keys.empty()) + (!m_generate_from_multisig_keys.empty()) + (!m_generate_from_json.empty()) > 1)
|
||||
if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_device.empty()) + (!m_generate_from_view_key.empty()) + (!m_generate_from_svb_key.empty()) + (!m_generate_from_spend_key.empty()) + (!m_generate_from_keys.empty()) + (!m_generate_from_multisig_keys.empty()) + (!m_generate_from_json.empty()) > 1)
|
||||
{
|
||||
fail_msg_writer() << tr("can't specify more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\", --generate-from-view-key=\"wallet_name\", --generate-from-spend-key=\"wallet_name\", --generate-from-keys=\"wallet_name\", --generate-from-multisig-keys=\"wallet_name\", --generate-from-json=\"jsonfilename\" and --generate-from-device=\"wallet_name\"");
|
||||
fail_msg_writer() << tr("can't specify more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\", --generate-from-view-key=\"wallet_name\", --generate-from-svb-key=\"wallet_name\", --generate-from-spend-key=\"wallet_name\", --generate-from-keys=\"wallet_name\", --generate-from-multisig-keys=\"wallet_name\", --generate-from-json=\"jsonfilename\" and --generate-from-device=\"wallet_name\"");
|
||||
return false;
|
||||
}
|
||||
else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_device.empty() && m_generate_from_view_key.empty() && m_generate_from_spend_key.empty() && m_generate_from_keys.empty() && m_generate_from_multisig_keys.empty() && m_generate_from_json.empty())
|
||||
else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_device.empty() && m_generate_from_view_key.empty() && m_generate_from_svb_key.empty() && m_generate_from_spend_key.empty() && m_generate_from_keys.empty() && m_generate_from_multisig_keys.empty() && m_generate_from_json.empty())
|
||||
{
|
||||
if(!ask_wallet_create_if_needed()) return false;
|
||||
}
|
||||
@@ -4584,6 +4585,69 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
password = *r;
|
||||
welcome = true;
|
||||
}
|
||||
else if (!m_generate_from_svb_key.empty())
|
||||
{
|
||||
m_wallet_file = m_generate_from_svb_key;
|
||||
// parse address
|
||||
std::string address_string = input_line("Standard address");
|
||||
if (std::cin.eof())
|
||||
return false;
|
||||
if (address_string.empty()) {
|
||||
fail_msg_writer() << tr("No data supplied, cancelled");
|
||||
return false;
|
||||
}
|
||||
cryptonote::address_parse_info info;
|
||||
if(!get_account_address_from_str(info, nettype, address_string))
|
||||
{
|
||||
fail_msg_writer() << tr("failed to parse address");
|
||||
return false;
|
||||
}
|
||||
if (info.is_subaddress)
|
||||
{
|
||||
fail_msg_writer() << tr("This address is a subaddress which cannot be used here.");
|
||||
return false;
|
||||
}
|
||||
if (!info.is_carrot)
|
||||
{
|
||||
fail_msg_writer() << tr("This address is not a Carrot address, and cannot be used here.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse view secret key
|
||||
epee::wipeable_string viewkey_string = input_secure_line("Secret view key");
|
||||
if (std::cin.eof())
|
||||
return false;
|
||||
if (viewkey_string.empty()) {
|
||||
fail_msg_writer() << tr("No data supplied, cancelled");
|
||||
return false;
|
||||
}
|
||||
crypto::secret_key viewkey;
|
||||
if (!viewkey_string.hex_to_pod(unwrap(unwrap(viewkey))))
|
||||
{
|
||||
fail_msg_writer() << tr("failed to parse view key secret key");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create all of the necessary keys for Carrot view-only wallet
|
||||
|
||||
/*
|
||||
// check the view key matches the given address
|
||||
crypto::public_key pkey;
|
||||
if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
|
||||
fail_msg_writer() << tr("failed to verify view key secret key");
|
||||
return false;
|
||||
}
|
||||
if (info.address.m_view_public_key != pkey) {
|
||||
fail_msg_writer() << tr("view key does not match standard address");
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
auto r = new_wallet(vm, info.address, boost::none, viewkey);
|
||||
CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
|
||||
password = *r;
|
||||
welcome = true;
|
||||
}
|
||||
else if (!m_generate_from_spend_key.empty())
|
||||
{
|
||||
m_wallet_file = m_generate_from_spend_key;
|
||||
@@ -5049,6 +5113,7 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
|
||||
m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet);
|
||||
m_generate_from_device = command_line::get_arg(vm, arg_generate_from_device);
|
||||
m_generate_from_view_key = command_line::get_arg(vm, arg_generate_from_view_key);
|
||||
m_generate_from_svb_key = command_line::get_arg(vm, arg_generate_from_svb_key);
|
||||
m_generate_from_spend_key = command_line::get_arg(vm, arg_generate_from_spend_key);
|
||||
m_generate_from_keys = command_line::get_arg(vm, arg_generate_from_keys);
|
||||
m_generate_from_multisig_keys = command_line::get_arg(vm, arg_generate_from_multisig_keys);
|
||||
@@ -5064,6 +5129,7 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
|
||||
m_subaddress_lookahead = command_line::get_arg(vm, arg_subaddress_lookahead);
|
||||
m_use_english_language_names = command_line::get_arg(vm, arg_use_english_language_names);
|
||||
m_restoring = !m_generate_from_view_key.empty() ||
|
||||
!m_generate_from_svb_key.empty() ||
|
||||
!m_generate_from_spend_key.empty() ||
|
||||
!m_generate_from_keys.empty() ||
|
||||
!m_generate_from_multisig_keys.empty() ||
|
||||
@@ -5287,8 +5353,9 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
|
||||
const cryptonote::account_public_address& address, const boost::optional<crypto::secret_key>& spendkey,
|
||||
const crypto::secret_key& viewkey)
|
||||
const cryptonote::account_public_address& address,
|
||||
const boost::optional<crypto::secret_key>& spendkey,
|
||||
const crypto::secret_key& viewkey)
|
||||
{
|
||||
std::pair<std::unique_ptr<tools::wallet2>, tools::password_container> rc;
|
||||
try { rc = tools::wallet2::make_new(vm, false, password_prompter); }
|
||||
@@ -11829,6 +11896,7 @@ int main(int argc, char* argv[])
|
||||
command_line::add_arg(desc_params, arg_generate_new_wallet);
|
||||
command_line::add_arg(desc_params, arg_generate_from_device);
|
||||
command_line::add_arg(desc_params, arg_generate_from_view_key);
|
||||
command_line::add_arg(desc_params, arg_generate_from_svb_key);
|
||||
command_line::add_arg(desc_params, arg_generate_from_spend_key);
|
||||
command_line::add_arg(desc_params, arg_generate_from_keys);
|
||||
command_line::add_arg(desc_params, arg_generate_from_multisig_keys);
|
||||
|
||||
@@ -101,8 +101,11 @@ namespace cryptonote
|
||||
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm, const crypto::secret_key& recovery_key,
|
||||
bool recover, bool two_random, const std::string &old_language);
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm, const cryptonote::account_public_address& address,
|
||||
const boost::optional<crypto::secret_key>& spendkey, const crypto::secret_key& viewkey);
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm,
|
||||
const cryptonote::account_public_address& address,
|
||||
const boost::optional<crypto::secret_key>& spendkey,
|
||||
const crypto::secret_key& viewkey
|
||||
);
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm,
|
||||
const epee::wipeable_string &multisig_keys, const epee::wipeable_string &seed_pass, const std::string &old_language);
|
||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm);
|
||||
@@ -430,6 +433,7 @@ namespace cryptonote
|
||||
std::string m_generate_new;
|
||||
std::string m_generate_from_device;
|
||||
std::string m_generate_from_view_key;
|
||||
std::string m_generate_from_svb_key;
|
||||
std::string m_generate_from_spend_key;
|
||||
std::string m_generate_from_keys;
|
||||
std::string m_generate_from_multisig_keys;
|
||||
|
||||
@@ -5845,7 +5845,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
|
||||
*/
|
||||
void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password,
|
||||
const cryptonote::account_public_address &account_public_address,
|
||||
const crypto::secret_key& viewkey, bool create_address_file)
|
||||
const crypto::secret_key& viewkey, bool create_address_file)
|
||||
{
|
||||
clear();
|
||||
prepare_file_names(wallet_);
|
||||
@@ -5857,7 +5857,11 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
|
||||
THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file);
|
||||
}
|
||||
|
||||
m_account.create_from_viewkey(account_public_address, viewkey);
|
||||
if (account_public_address.m_is_carrot) {
|
||||
m_account.create_from_svb_key(account_public_address, viewkey);
|
||||
} else {
|
||||
m_account.create_from_viewkey(account_public_address, viewkey);
|
||||
}
|
||||
init_type(hw::device::device_type::SOFTWARE);
|
||||
m_watch_only = true;
|
||||
m_account_public_address = account_public_address;
|
||||
|
||||
@@ -1019,6 +1019,7 @@ private:
|
||||
* \param account_public_address The account's public address
|
||||
* \param viewkey view secret key
|
||||
* \param create_address_file Whether to create an address file
|
||||
* \param is_carrot Whether viewkey is k_v (CN) or s_vb (Carrot)
|
||||
*/
|
||||
void generate(const std::string& wallet, const epee::wipeable_string& password,
|
||||
const cryptonote::account_public_address &account_public_address,
|
||||
|
||||
Reference in New Issue
Block a user