diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index e95db1d9d..036ce616d 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -868,12 +868,21 @@ bool simple_wallet::carrot_keys(const std::vector &args/* = std::ve printf("master secret: "); print_secret_key(m_wallet->get_account().get_keys().s_master); putchar('\n'); - printf("view-received secret: "); - print_secret_key(m_wallet->get_account().get_keys().m_view_secret_key); + printf("prove-spend key: "); + print_secret_key(m_wallet->get_account().get_keys().k_prove_spend); putchar('\n'); - printf("view-all secret: "); + printf("view-balance secret: "); print_secret_key(m_wallet->get_account().get_keys().s_view_balance); putchar('\n'); + printf("generate-image key: "); + print_secret_key(m_wallet->get_account().get_keys().k_generate_image); + putchar('\n'); + printf("view-incoming key: "); + print_secret_key(m_wallet->get_account().get_keys().k_view_incoming); + putchar('\n'); + printf("generate-address secret: "); + print_secret_key(m_wallet->get_account().get_keys().s_generate_address); + putchar('\n'); } // TODO: print the public wallet address for the different wallet tiers //std::cout << "public: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_view_public_key) << std::endl; @@ -894,7 +903,8 @@ bool simple_wallet::viewkey(const std::vector &args/* = std::vector print_secret_key(m_wallet->get_account().get_keys().m_view_secret_key); putchar('\n'); } - std::cout << "public: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_view_public_key) << std::endl; + std::cout << "CN public: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_view_public_key) << std::endl; + std::cout << "Carrot public: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_carrot_account_address.m_view_public_key) << std::endl; return true; } @@ -917,7 +927,8 @@ bool simple_wallet::spendkey(const std::vector &args/* = std::vecto print_secret_key(m_wallet->get_account().get_keys().m_spend_secret_key); putchar('\n'); } - std::cout << "public: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_spend_public_key) << std::endl; + std::cout << "CN public: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_spend_public_key) << std::endl; + std::cout << "Carrot public: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_carrot_account_address.m_spend_public_key) << std::endl; return true; } @@ -6374,6 +6385,7 @@ bool simple_wallet::show_balance_unlocked(bool detailed) const std::string tag = m_wallet->get_account_tags().second[m_current_subaddress_account]; success_msg_writer() << tr("Tag: ") << (tag.empty() ? std::string{tr("(No tag assigned)")} : tag); std::vector asset_types = m_wallet->list_asset_types(); + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; for (auto& asset: asset_types) { uint64_t blocks_to_unlock, time_to_unlock; uint64_t unlocked_balance = m_wallet->unlocked_balance(m_current_subaddress_account, asset, false, &blocks_to_unlock, &time_to_unlock); @@ -6397,8 +6409,10 @@ bool simple_wallet::show_balance_unlocked(bool detailed) m_wallet->get_transfers(transfers); for (const auto& i : balance_per_subaddress) { + carrot::subaddress_index_extended subaddr = {{m_current_subaddress_account, i.first}, + is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}; cryptonote::subaddress_index subaddr_index = {m_current_subaddress_account, i.first}; - std::string address_str = m_wallet->get_subaddress_as_str(subaddr_index).substr(0, 6); + std::string address_str = m_wallet->get_subaddress_as_str(subaddr).substr(0, 6); uint64_t num_unspent_outputs = std::count_if(transfers.begin(), transfers.end(), [&subaddr_index](const tools::wallet2::transfer_details& td) { return !td.m_spent && td.m_subaddr_index == subaddr_index; }); success_msg_writer() << boost::format(tr("%8u %6s %21s %21s %7u %21s")) % i.first % address_str % print_money(i.second) % print_money(unlocked_balance_per_subaddress[i.first].first) % num_unspent_outputs % m_wallet->get_subaddress_label(subaddr_index); } @@ -8843,29 +8857,31 @@ bool simple_wallet::donate(const std::vector &args_) fail_msg_writer() << tr("amount is wrong: ") << local_args.back() << ", " << tr("expected number from 0 to ") << print_money(std::numeric_limits::max()); return true; } + uint8_t hf_version = m_wallet->get_current_hard_fork(); // push back address, amount, payment id std::string address_str; + std::string DONATION_ADDR = (hf_version >= HF_VERSION_CARROT) ? SALVIUM_DONATION_ADDR_CARROT : SALVIUM_DONATION_ADDR; if (m_wallet->nettype() != cryptonote::MAINNET) { // if not mainnet, convert donation address string to the relevant network type address_parse_info info; - if (!cryptonote::get_account_address_from_str(info, cryptonote::MAINNET, SALVIUM_DONATION_ADDR)) + if (!cryptonote::get_account_address_from_str(info, cryptonote::MAINNET, DONATION_ADDR)) { - fail_msg_writer() << tr("Failed to parse donation address: ") << SALVIUM_DONATION_ADDR; + fail_msg_writer() << tr("Failed to parse donation address: ") << DONATION_ADDR; return true; } address_str = cryptonote::get_account_address_as_str(m_wallet->nettype(), info.is_subaddress, info.address); } else { - address_str = SALVIUM_DONATION_ADDR; + address_str = DONATION_ADDR; } local_args.push_back(address_str); local_args.push_back(amount_str); if (!payment_id_str.empty()) local_args.push_back(payment_id_str); if (m_wallet->nettype() == cryptonote::MAINNET) - message_writer() << (boost::format(tr("Donating %s %s to The Salvium Team (donate.salvium.io or %s).")) % amount_str % cryptonote::get_unit(cryptonote::get_default_decimal_point()) % SALVIUM_DONATION_ADDR).str(); + message_writer() << (boost::format(tr("Donating %s %s to The Salvium Team (donate.salvium.io or %s).")) % amount_str % cryptonote::get_unit(cryptonote::get_default_decimal_point()) % DONATION_ADDR).str(); else message_writer() << (boost::format(tr("Donating %s %s to %s.")) % amount_str % cryptonote::get_unit(cryptonote::get_default_decimal_point()) % address_str).str(); transfer(local_args); @@ -10803,15 +10819,16 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: std::vector local_args = args; tools::wallet2::transfer_container transfers; m_wallet->get_transfers(transfers); + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; - auto print_address_sub = [this, &transfers](uint32_t index) + auto print_address_sub = [this, &transfers, is_carrot](uint32_t index) { bool used = std::find_if( transfers.begin(), transfers.end(), [this, &index](const tools::wallet2::transfer_details& td) { return td.m_subaddr_index == cryptonote::subaddress_index{ m_current_subaddress_account, index }; }) != transfers.end(); - success_msg_writer() << index << " " << m_wallet->get_subaddress_as_str({m_current_subaddress_account, index}) << " " << (index == 0 ? tr("Primary address") : m_wallet->get_subaddress_label({m_current_subaddress_account, index})) << " " << (used ? tr("(used)") : ""); + success_msg_writer() << index << " " << m_wallet->get_subaddress_as_str({{m_current_subaddress_account, index}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}) << " " << (index == 0 ? tr("Primary address") : m_wallet->get_subaddress_label({m_current_subaddress_account, index})) << " " << (used ? tr("(used)") : ""); }; uint32_t index = 0; diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 251badaf8..13de5b013 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -53,8 +53,10 @@ #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "wallet.simplewallet" -// Hardcode Monero's donation address (see #1447) -constexpr const char SALVIUM_DONATION_ADDR[] = "888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H"; + +// Hardcode Salvium's donation address (pre-Carrot and post-Carrot) +constexpr const char SALVIUM_DONATION_ADDR[] = "SaLvdVvjgeffnxRDFoEEgeSt3jVcU49W7byT6nawvJFVio9XR7V53tU4mdo3HjjKno2WApvqxmcmKLZyoeSZZQ6jVqSGj1TLsNL"; +constexpr const char SALVIUM_DONATION_ADDR_CARROT[] = "SC11sFBPrGmNuT8AiTPUW479BwkdPJwBxdjKEhZ96yDfFg3B4mawgcpE1YfCAa1zwzUiRTMP9eqB54av48ALhzUu1Q5QoPGUfh"; /*! * \namespace cryptonote diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index cfe25335c..7713c3f07 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1583,10 +1583,15 @@ crypto::public_key wallet2::get_subaddress_spend_public_key(const cryptonote::su return hwdev.get_subaddress_spend_public_key(m_account.get_keys(), index); } //---------------------------------------------------------------------------------------------------- -std::string wallet2::get_subaddress_as_str(const cryptonote::subaddress_index& index) const +std::string wallet2::get_subaddress_as_str(const carrot::subaddress_index_extended& subaddr) const { - cryptonote::account_public_address address = get_subaddress(index); - return cryptonote::get_account_address_as_str(m_nettype, !index.is_zero(), address); + carrot::CarrotDestinationV1 address = m_account.subaddress(subaddr); + + // Build the cryptonote::account_public_address + account_public_address addr{address.address_spend_pubkey, address.address_view_pubkey}; + + // change this code into base 58 + return cryptonote::get_account_address_as_str(m_nettype, address.is_subaddress, addr, subaddr.derive_type == carrot::AddressDeriveType::Carrot); } //---------------------------------------------------------------------------------------------------- std::string wallet2::get_integrated_address_as_str(const crypto::hash8& payment_id) const diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 398de5934..336328020 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1179,7 +1179,8 @@ private: boost::optional get_subaddress_index(const cryptonote::account_public_address& address) const; crypto::public_key get_subaddress_spend_public_key(const cryptonote::subaddress_index& index) const; std::vector get_subaddress_spend_public_keys(uint32_t account, uint32_t begin, uint32_t end) const; - std::string get_subaddress_as_str(const cryptonote::subaddress_index& index) const; + //std::string get_subaddress_as_str(const cryptonote::subaddress_index& index) const; + std::string get_subaddress_as_str(const carrot::subaddress_index_extended& index) const; std::string get_address_as_str() const { return get_subaddress_as_str({0, 0}); } std::string get_integrated_address_as_str(const crypto::hash8& payment_id) const; void add_subaddress_account(const std::string& label); diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 8fce8198a..3a558fdfc 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -438,7 +438,9 @@ namespace tools entry.type = pd.m_coinbase ? "block" : "in"; entry.subaddr_index = pd.m_subaddr_index; entry.subaddr_indices.push_back(pd.m_subaddr_index); - entry.address = m_wallet->get_subaddress_as_str(pd.m_subaddr_index); + //entry.address = m_wallet->get_subaddress_as_str(pd.m_subaddr_index); + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; + entry.address = m_wallet->get_subaddress_as_str({{pd.m_subaddr_index.major, pd.m_subaddr_index.minor}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); set_confirmations(entry, m_wallet->get_blockchain_current_height(), m_wallet->get_last_block_reward(), pd.m_unlock_time); } //------------------------------------------------------------------------------------------------------------------------------ @@ -470,7 +472,9 @@ namespace tools entry.subaddr_index = { pd.m_subaddr_account, 0 }; for (uint32_t i: pd.m_subaddr_indices) entry.subaddr_indices.push_back({pd.m_subaddr_account, i}); - entry.address = m_wallet->get_subaddress_as_str({pd.m_subaddr_account, 0}); + //entry.address = m_wallet->get_subaddress_as_str({pd.m_subaddr_account, 0}); + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; + entry.address = m_wallet->get_subaddress_as_str({{pd.m_subaddr_account, 0}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); set_confirmations(entry, m_wallet->get_blockchain_current_height(), m_wallet->get_last_block_reward(), pd.m_unlock_time); } //------------------------------------------------------------------------------------------------------------------------------ @@ -503,7 +507,9 @@ namespace tools entry.subaddr_index = { pd.m_subaddr_account, 0 }; for (uint32_t i: pd.m_subaddr_indices) entry.subaddr_indices.push_back({pd.m_subaddr_account, i}); - entry.address = m_wallet->get_subaddress_as_str({pd.m_subaddr_account, 0}); + //entry.address = m_wallet->get_subaddress_as_str({pd.m_subaddr_account, 0}); + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; + entry.address = m_wallet->get_subaddress_as_str({{pd.m_subaddr_account, 0}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); set_confirmations(entry, m_wallet->get_blockchain_current_height(), m_wallet->get_last_block_reward(), pd.m_tx.unlock_time); } //------------------------------------------------------------------------------------------------------------------------------ @@ -526,7 +532,9 @@ namespace tools entry.type = "pool"; entry.subaddr_index = pd.m_subaddr_index; entry.subaddr_indices.push_back(pd.m_subaddr_index); - entry.address = m_wallet->get_subaddress_as_str(pd.m_subaddr_index); + //entry.address = m_wallet->get_subaddress_as_str(pd.m_subaddr_index); + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; + entry.address = m_wallet->get_subaddress_as_str({{pd.m_subaddr_index.major, pd.m_subaddr_index.minor}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); set_confirmations(entry, m_wallet->get_blockchain_current_height(), m_wallet->get_last_block_reward(), pd.m_unlock_time); } //------------------------------------------------------------------------------------------------------------------------------ @@ -534,6 +542,8 @@ namespace tools { if (!m_wallet) return not_open(er); + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; + std::vector assets_in_wallet = m_wallet->list_asset_types(); std::string asset_type = req.asset_type.empty() ? "SAL1" : boost::algorithm::to_upper_copy(req.asset_type); // verify that the asset is in the list of in-wallet assets @@ -590,7 +600,7 @@ namespace tools info.account_index = account_index; info.address_index = i; cryptonote::subaddress_index index = {info.account_index, info.address_index}; - info.address = m_wallet->get_subaddress_as_str(index); + info.address = m_wallet->get_subaddress_as_str({{info.account_index, info.address_index}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); info.balance = balance_per_subaddress[i]; info.unlocked_balance = unlocked_balance_per_subaddress[i].first; info.blocks_to_unlock = unlocked_balance_per_subaddress[i].second.first; @@ -616,6 +626,9 @@ namespace tools bool wallet_rpc_server::on_getaddress(const wallet_rpc::COMMAND_RPC_GET_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); + + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; + try { THROW_WALLET_EXCEPTION_IF(req.account_index >= m_wallet->get_num_subaddress_accounts(), error::account_index_outofbound); @@ -638,7 +651,8 @@ namespace tools res.addresses.resize(res.addresses.size() + 1); auto& info = res.addresses.back(); const cryptonote::subaddress_index index = {req.account_index, i}; - info.address = m_wallet->get_subaddress_as_str(index); + //info.address = m_wallet->get_subaddress_as_str(index); + info.address = m_wallet->get_subaddress_as_str({{req.account_index, i}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); info.label = m_wallet->get_subaddress_label(index); info.address_index = index.minor; info.used = std::find_if(transfers.begin(), transfers.end(), [&](const tools::wallet2::transfer_details& td) { return td.m_subaddr_index == index; }) != transfers.end(); @@ -731,6 +745,9 @@ namespace tools bool wallet_rpc_server::on_get_accounts(const wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); + + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; + try { res.total_balance = 0; @@ -751,7 +768,8 @@ namespace tools continue; wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::subaddress_account_info info; info.account_index = subaddr_index.major; - info.base_address = m_wallet->get_subaddress_as_str(subaddr_index); + //info.base_address = m_wallet->get_subaddress_as_str(subaddr_index); + info.base_address = m_wallet->get_subaddress_as_str({{subaddr_index.major, subaddr_index.minor}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); //for (const auto& asset: asset_types) { info.balance = m_wallet->balance(subaddr_index.major, "SAL1", req.strict_balances); @@ -2084,6 +2102,9 @@ namespace tools bool wallet_rpc_server::on_get_payments(const wallet_rpc::COMMAND_RPC_GET_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_PAYMENTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); + + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; + crypto::hash payment_id; crypto::hash8 payment_id8; cryptonote::blobdata payment_id_blob; @@ -2124,7 +2145,8 @@ namespace tools rpc_payment.unlock_time = payment.m_unlock_time; rpc_payment.locked = !m_wallet->is_transfer_unlocked(payment.m_unlock_time, payment.m_block_height); rpc_payment.subaddr_index = payment.m_subaddr_index; - rpc_payment.address = m_wallet->get_subaddress_as_str(payment.m_subaddr_index); + //rpc_payment.address = m_wallet->get_subaddress_as_str(payment.m_subaddr_index); + rpc_payment.address = m_wallet->get_subaddress_as_str({{payment.m_subaddr_index.major, payment.m_subaddr_index.minor}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); res.payments.push_back(rpc_payment); } @@ -2134,6 +2156,9 @@ namespace tools bool wallet_rpc_server::on_get_bulk_payments(const wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { res.payments.clear(); + + bool is_carrot = m_wallet->get_current_hard_fork() >= HF_VERSION_CARROT; + if (!m_wallet) return not_open(er); /* If the payment ID list is empty, we get payments to any payment ID (or lack thereof) */ @@ -2151,7 +2176,8 @@ namespace tools rpc_payment.block_height = payment.second.m_block_height; rpc_payment.unlock_time = payment.second.m_unlock_time; rpc_payment.subaddr_index = payment.second.m_subaddr_index; - rpc_payment.address = m_wallet->get_subaddress_as_str(payment.second.m_subaddr_index); + //rpc_payment.address = m_wallet->get_subaddress_as_str(payment.second.m_subaddr_index); + rpc_payment.address = m_wallet->get_subaddress_as_str({{payment.second.m_subaddr_index.major, payment.second.m_subaddr_index.minor}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); rpc_payment.locked = !m_wallet->is_transfer_unlocked(payment.second.m_unlock_time, payment.second.m_block_height); res.payments.push_back(std::move(rpc_payment)); } @@ -2206,7 +2232,8 @@ namespace tools rpc_payment.block_height = payment.m_block_height; rpc_payment.unlock_time = payment.m_unlock_time; rpc_payment.subaddr_index = payment.m_subaddr_index; - rpc_payment.address = m_wallet->get_subaddress_as_str(payment.m_subaddr_index); + //rpc_payment.address = m_wallet->get_subaddress_as_str(payment.m_subaddr_index); + rpc_payment.address = m_wallet->get_subaddress_as_str({{payment.m_subaddr_index.major, payment.m_subaddr_index.minor}, is_carrot ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot}); rpc_payment.locked = !m_wallet->is_transfer_unlocked(payment.m_unlock_time, payment.m_block_height); res.payments.push_back(std::move(rpc_payment)); }