From 6d40a92026255244b6525ffd76ce0b8f94690f9a Mon Sep 17 00:00:00 2001 From: stoffu Date: Thu, 28 Dec 2017 22:50:10 +0900 Subject: Reserve proof --- src/simplewallet/simplewallet.cpp | 114 ++++++++++++++++++++++++++++++++++++++ src/simplewallet/simplewallet.h | 2 + 2 files changed, 116 insertions(+) (limited to 'src/simplewallet') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index b9a3e45b4..96e1e561a 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1690,6 +1690,16 @@ simple_wallet::simple_wallet() boost::bind(&simple_wallet::check_spend_proof, this, _1), tr("check_spend_proof []"), tr("Check a signature proving that the signer generated , optionally with a challenge string .")); + m_cmd_binder.set_handler("get_reserve_proof", + boost::bind(&simple_wallet::get_reserve_proof, this, _1), + tr("get_reserve_proof (all|) []"), + tr("Generate a signature proving that you own at least this much, optionally with a challenge string .\n" + "If 'all' is specified, you prove the entire sum of all of your existing accounts' balances.\n" + "Otherwise, you prove the reserve of the smallest possible amount above available in your current account.")); + m_cmd_binder.set_handler("check_reserve_proof", + boost::bind(&simple_wallet::check_reserve_proof, this, _1), + tr("check_reserve_proof
[]"), + tr("Check a signature proving that the owner of
holds at least this much, optionally with a challenge string .")); m_cmd_binder.set_handler("show_transfers", boost::bind(&simple_wallet::show_transfers, this, _1), tr("show_transfers [in|out|pending|failed|pool] [index=[,,...]] [ []]"), @@ -5125,6 +5135,110 @@ bool simple_wallet::check_spend_proof(const std::vector &args) return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::get_reserve_proof(const std::vector &args) +{ + if(args.size() != 1 && args.size() != 2) { + fail_msg_writer() << tr("usage: get_reserve_proof (all|) []"); + return true; + } + + if (m_wallet->watch_only() || m_wallet->multisig()) + { + fail_msg_writer() << tr("The reserve proof can be generated only by a full wallet"); + return true; + } + + boost::optional> account_minreserve; + if (args[0] != "all") + { + account_minreserve = std::pair(); + account_minreserve->first = m_current_subaddress_account; + if (!cryptonote::parse_amount(account_minreserve->second, args[0])) + { + fail_msg_writer() << tr("amount is wrong: ") << args[0]; + return true; + } + } + + if (!try_connect_to_daemon()) + { + fail_msg_writer() << tr("failed to connect to the daemon"); + return true; + } + + if (m_wallet->ask_password() && !get_and_verify_password()) { return true; } + + LOCK_IDLE_SCOPE(); + + try + { + const std::string sig_str = m_wallet->get_reserve_proof(account_minreserve, args.size() == 2 ? args[1] : ""); + const std::string filename = "monero_reserve_proof"; + if (epee::file_io_utils::save_string_to_file(filename, sig_str)) + success_msg_writer() << tr("signature file saved to: ") << filename; + else + fail_msg_writer() << tr("failed to save signature file"); + } + catch (const std::exception &e) + { + fail_msg_writer() << e.what(); + } + return true; +} +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::check_reserve_proof(const std::vector &args) +{ + if(args.size() != 2 && args.size() != 3) { + fail_msg_writer() << tr("usage: check_reserve_proof
[]"); + return true; + } + + if (!try_connect_to_daemon()) + { + fail_msg_writer() << tr("failed to connect to the daemon"); + return true; + } + + cryptonote::address_parse_info info; + if(!cryptonote::get_account_address_from_str_or_url(info, m_wallet->testnet(), args[0], oa_prompter)) + { + fail_msg_writer() << tr("failed to parse address"); + return true; + } + if (info.is_subaddress) + { + fail_msg_writer() << tr("Address must not be a subaddress"); + return true; + } + + std::string sig_str; + if (!epee::file_io_utils::load_file_to_string(args[1], sig_str)) + { + fail_msg_writer() << tr("failed to load signature file"); + return true; + } + + LOCK_IDLE_SCOPE(); + + try + { + uint64_t total, spent; + if (m_wallet->check_reserve_proof(info.address, args.size() == 3 ? args[2] : "", sig_str, total, spent)) + { + success_msg_writer() << boost::format(tr("Good signature -- total: %s, spent: %s, unspent: %s")) % print_money(total) % print_money(spent) % print_money(total - spent); + } + else + { + fail_msg_writer() << tr("Bad signature"); + } + } + catch (const std::exception& e) + { + fail_msg_writer() << e.what(); + } + return true; +} +//---------------------------------------------------------------------------------------------------- static std::string get_human_readable_timestamp(uint64_t ts) { char buffer[64]; diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 024077ca1..45ed2c32c 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -170,6 +170,8 @@ namespace cryptonote bool check_tx_proof(const std::vector &args); bool get_spend_proof(const std::vector &args); bool check_spend_proof(const std::vector &args); + bool get_reserve_proof(const std::vector &args); + bool check_reserve_proof(const std::vector &args); bool show_transfers(const std::vector &args); bool unspent_outputs(const std::vector &args); bool rescan_blockchain(const std::vector &args); -- cgit v1.2.3