diff options
author | stoffu <stoffu@protonmail.ch> | 2017-09-12 10:05:41 +0900 |
---|---|---|
committer | stoffu <stoffu@protonmail.ch> | 2017-11-18 20:44:27 +0900 |
commit | 998777ecd71fee25636f6ef40f05f88251d03e96 (patch) | |
tree | d3cc8cf38b70cd10678e9ef1d3a36f2ac7e8386d /src/wallet/api/wallet.cpp | |
parent | Merge pull request #2818 (diff) | |
download | monero-998777ecd71fee25636f6ef40f05f88251d03e96.tar.xz |
Tx proof (revised):
- refactoring: proof generation/checking code was moved from simplewallet.cpp to wallet2.cpp
- allow an arbitrary message to be signed together with txid
- introduce two types (outbound & inbound) of tx proofs; with the same syntax, inbound is selected when <address> belongs to this wallet, outbound otherwise. see GitHub thread for more discussion
- wallet RPC: added get_tx_key, check_tx_key, get_tx_proof, check_tx_proof
- wallet API: moved WalletManagerImpl::checkPayment to Wallet::checkTxKey, added Wallet::getTxProof/checkTxProof
- get_tx_key/check_tx_key: handle additional tx keys by concatenating them into a single string
Diffstat (limited to 'src/wallet/api/wallet.cpp')
-rw-r--r-- | src/wallet/api/wallet.cpp | 140 |
1 files changed, 132 insertions, 8 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 8e747d16b..db8911042 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1385,24 +1385,148 @@ std::string WalletImpl::getUserNote(const std::string &txid) const return m_wallet->get_tx_note(htxid); } -std::string WalletImpl::getTxKey(const std::string &txid) const +std::string WalletImpl::getTxKey(const std::string &txid_str) const { - cryptonote::blobdata txid_data; - if(!epee::string_tools::parse_hexstr_to_binbuff(txid, txid_data) || txid_data.size() != sizeof(crypto::hash)) + crypto::hash txid; + if(!epee::string_tools::hex_to_pod(txid_str, txid)) { - return ""; + m_status = Status_Error; + m_errorString = tr("Failed to parse txid"); + return ""; } - const crypto::hash htxid = *reinterpret_cast<const crypto::hash*>(txid_data.data()); crypto::secret_key tx_key; std::vector<crypto::secret_key> additional_tx_keys; - if (m_wallet->get_tx_key(htxid, tx_key, additional_tx_keys)) + if (m_wallet->get_tx_key(txid, tx_key, additional_tx_keys)) { - return epee::string_tools::pod_to_hex(tx_key); + m_status = Status_Ok; + std::ostringstream oss; + oss << epee::string_tools::pod_to_hex(tx_key); + for (size_t i = 0; i < additional_tx_keys.size(); ++i) + oss << epee::string_tools::pod_to_hex(additional_tx_keys[i]); + return oss.str(); } else { - return ""; + m_status = Status_Error; + m_errorString = tr("no tx keys found for this txid"); + return ""; + } +} + +bool WalletImpl::checkTxKey(const std::string &txid_str, std::string tx_key_str, const std::string &address_str, uint64_t &received, bool &in_pool, uint64_t &confirmations) +{ + crypto::hash txid; + if (!epee::string_tools::hex_to_pod(txid_str, txid)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse txid"); + return false; + } + + crypto::secret_key tx_key; + std::vector<crypto::secret_key> additional_tx_keys; + if (!epee::string_tools::hex_to_pod(tx_key_str.substr(0, 64), tx_key)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse tx key"); + return false; + } + tx_key_str = tx_key_str.substr(64); + while (!tx_key_str.empty()) + { + additional_tx_keys.resize(additional_tx_keys.size() + 1); + if (!epee::string_tools::hex_to_pod(tx_key_str.substr(0, 64), additional_tx_keys.back())) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse tx key"); + return false; + } + tx_key_str = tx_key_str.substr(64); + } + + cryptonote::address_parse_info info; + if (!cryptonote::get_account_address_from_str(info, m_wallet->testnet(), address_str)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse address"); + return false; + } + + try + { + m_wallet->check_tx_key(txid, tx_key, additional_tx_keys, info.address, received, in_pool, confirmations); + m_status = Status_Ok; + return true; + } + catch (const std::exception &e) + { + m_status = Status_Error; + m_errorString = e.what(); + return false; + } +} + +std::string WalletImpl::getTxProof(const std::string &txid_str, const std::string &address_str, const std::string &message, std::string &error_str) const +{ + crypto::hash txid; + if (!epee::string_tools::hex_to_pod(txid_str, txid)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse txid"); + return ""; + } + + cryptonote::address_parse_info info; + if (!cryptonote::get_account_address_from_str(info, m_wallet->testnet(), address_str)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse address"); + return ""; + } + + try + { + m_status = Status_Ok; + return m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, message, error_str); + } + catch (const std::exception &e) + { + m_status = Status_Error; + m_errorString = e.what(); + return ""; + } +} + +bool WalletImpl::checkTxProof(const std::string &txid_str, const std::string &address_str, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations) +{ + crypto::hash txid; + if (!epee::string_tools::hex_to_pod(txid_str, txid)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse txid"); + return false; + } + + cryptonote::address_parse_info info; + if (!cryptonote::get_account_address_from_str(info, m_wallet->testnet(), address_str)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse address"); + return false; + } + + try + { + good = m_wallet->check_tx_proof(txid, info.address, info.is_subaddress, message, signature, received, in_pool, confirmations); + m_status = Status_Ok; + return true; + } + catch (const std::exception &e) + { + m_status = Status_Error; + m_errorString = e.what(); + return false; } } |