mirror of
https://github.com/monero-project/monero.git
synced 2025-08-19 07:28:08 -04:00
Reserve proof
This commit is contained in:
parent
35d5aa36c9
commit
6d40a92026
10 changed files with 580 additions and 0 deletions
|
@ -1690,6 +1690,16 @@ simple_wallet::simple_wallet()
|
|||
boost::bind(&simple_wallet::check_spend_proof, this, _1),
|
||||
tr("check_spend_proof <txid> <signature_file> [<message>]"),
|
||||
tr("Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>."));
|
||||
m_cmd_binder.set_handler("get_reserve_proof",
|
||||
boost::bind(&simple_wallet::get_reserve_proof, this, _1),
|
||||
tr("get_reserve_proof (all|<amount>) [<message>]"),
|
||||
tr("Generate a signature proving that you own at least this much, optionally with a challenge string <message>.\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 <amount> 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 <address> <signature_file> [<message>]"),
|
||||
tr("Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>."));
|
||||
m_cmd_binder.set_handler("show_transfers",
|
||||
boost::bind(&simple_wallet::show_transfers, this, _1),
|
||||
tr("show_transfers [in|out|pending|failed|pool] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]"),
|
||||
|
@ -5125,6 +5135,110 @@ bool simple_wallet::check_spend_proof(const std::vector<std::string> &args)
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::get_reserve_proof(const std::vector<std::string> &args)
|
||||
{
|
||||
if(args.size() != 1 && args.size() != 2) {
|
||||
fail_msg_writer() << tr("usage: get_reserve_proof (all|<amount>) [<message>]");
|
||||
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<std::pair<uint32_t, uint64_t>> account_minreserve;
|
||||
if (args[0] != "all")
|
||||
{
|
||||
account_minreserve = std::pair<uint32_t, uint64_t>();
|
||||
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<std::string> &args)
|
||||
{
|
||||
if(args.size() != 2 && args.size() != 3) {
|
||||
fail_msg_writer() << tr("usage: check_reserve_proof <address> <signature_file> [<message>]");
|
||||
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];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue