From 63741d82644944f236c93e9f44cb988a38df1993 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 11 Jun 2015 09:44:13 +0100 Subject: Integrated addresses (standard address plus payment id) --- src/simplewallet/simplewallet.cpp | 64 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 3159e85d4..c40e3f0ae 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -298,6 +298,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("sweep_dust", boost::bind(&simple_wallet::sweep_dust, this, _1), "Send all dust outputs to the same address with mixin 0"); m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), "set_log - Change current log detalization level, is a number 0-4"); m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this, _1), "Show current wallet public address"); + m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::print_integrated_address, this, _1), "Show an integrated address for the current wallet public address and a payment id"); m_cmd_binder.set_handler("save", boost::bind(&simple_wallet::save, this, _1), "Save wallet synchronized data"); m_cmd_binder.set_handler("save_watch_only", boost::bind(&simple_wallet::save_watch_only, this, _1), "Save watch only keys file"); m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), "Get viewkey"); @@ -1137,6 +1138,7 @@ bool simple_wallet::transfer(const std::vector &args_) } std::vector extra; + bool payment_id_seen = false; if (1 == local_args.size() % 2) { std::string payment_id_str = local_args.back(); @@ -1156,13 +1158,17 @@ bool simple_wallet::transfer(const std::vector &args_) fail_msg_writer() << "payment id has invalid format: \"" << payment_id_str << "\", expected 64-character string"; return true; } + payment_id_seen = true; } vector dsts; + crypto::hash payment_id = null_hash; for (size_t i = 0; i < local_args.size(); i += 2) { cryptonote::tx_destination_entry de; - if(!get_account_address_from_str(de.addr, m_wallet->testnet(), local_args[i])) + bool has_payment_id; + crypto::hash new_payment_id; + if(!get_account_integrated_address_from_str(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[i])) { // if treating as an address fails, try as url bool dnssec_ok = false; @@ -1174,7 +1180,7 @@ bool simple_wallet::transfer(const std::vector &args_) // for now, move on only if one address found if (addresses_from_dns.size() == 1) { - if (get_account_address_from_str(de.addr, m_wallet->testnet(), addresses_from_dns[0])) + if (get_account_integrated_address_from_str(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), addresses_from_dns[0])) { // if it was an address, prompt user for confirmation. // inform user of DNSSEC validation status as well. @@ -1221,6 +1227,26 @@ bool simple_wallet::transfer(const std::vector &args_) } } + if (has_payment_id) { + if (payment_id_seen && payment_id != new_payment_id) { + fail_msg_writer() << "A single transaction cannot use more than one payment id: " << local_args[i]; + return true; + } + + if (!payment_id_seen) + { + std::string extra_nonce; + set_payment_id_to_tx_extra_nonce(extra_nonce, new_payment_id); + bool r = add_extra_nonce_to_tx_extra(extra, extra_nonce); + if(!r) + { + fail_msg_writer() << "Failed to set up payment id, though it was decoded correctly"; + return true; + } + payment_id = new_payment_id; + } + } + bool ok = cryptonote::parse_amount(de.amount, local_args[i + 1]); if(!ok || 0 == de.amount) { @@ -1491,6 +1517,40 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::print_integrated_address(const std::vector &args/* = std::vector()*/) +{ + if (args.size() != 1) + { + fail_msg_writer() << "Missing payment id or address"; + return true; + } + crypto::hash payment_id; + if(tools::wallet2::parse_payment_id(args.back(), payment_id)) + { + success_msg_writer() << m_wallet->get_account().get_public_integrated_address_str(payment_id, m_wallet->testnet()); + return true; + } + else { + bool has_payment_id; + crypto::hash payment_id; + account_public_address addr; + if(get_account_integrated_address_from_str(addr, has_payment_id, payment_id, m_wallet->testnet(), args.back())) + { + if (has_payment_id) + { + success_msg_writer() << "Integrated address: account " << get_account_address_as_str(m_wallet->testnet(),addr) << ", payment id " << payment_id; + } + else + { + success_msg_writer() << "Standard address: account " << get_account_address_as_str(m_wallet->testnet(),addr); + } + return true; + } + } + fail_msg_writer() << "Failed to parse payment id or address"; + return true; +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::process_command(const std::vector &args) { return m_cmd_binder.process_command_vec(args); -- cgit v1.2.3