Guest User

tx keys attempt

a guest
Oct 24th, 2025
35
0
13 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.55 KB | None | 0 0
  1. // src/wallet/api/pending_transaction.cpp
  2.  
  3. /** Returns a vector of tuples with (txid, destination address, tx key) for each output of a specific transaction, disregarding change. */
  4. std::vector<std::tuple<std::string, std::string, std::string>> PendingTransactionImpl::txKeys(const std::string &tx_hash) const
  5. {
  6.     std::vector<std::tuple<std::string, std::string, std::string>> keys;
  7.  
  8.     for (const auto &ptx : m_pending_tx)
  9.     {
  10.         const std::string current_tx_hash = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx));
  11.        
  12.         if (current_tx_hash != tx_hash)
  13.         {
  14.             continue;
  15.         }
  16.  
  17.         const std::string main_tx_key = epee::string_tools::pod_to_hex(unwrap(unwrap(ptx.tx_key)));
  18.  
  19.         if (ptx.tx.vout.size() != ptx.construction_data.splitted_dsts.size()) {
  20.             throw std::runtime_error(
  21.                 "Number of outputs in transaction "
  22.                 + current_tx_hash
  23.                 + " (" + std::to_string(ptx.tx.vout.size()) + ")"
  24.                 + " does not match number of destinations ("
  25.                 + std::to_string(ptx.construction_data.splitted_dsts.size()) + ")");
  26.         }
  27.  
  28.         for (size_t i = 0; i < ptx.tx.vout.size(); i++) {
  29.             const cryptonote::tx_out tx_output = ptx.tx.vout[i];
  30.             const cryptonote::tx_destination_entry dest_entry = ptx.construction_data.splitted_dsts[i];
  31.  
  32.             // skip change outputs
  33.             if (dest_entry.addr.m_spend_public_key == ptx.construction_data.change_dts.addr.m_spend_public_key &&
  34.                 dest_entry.addr.m_view_public_key == ptx.construction_data.change_dts.addr.m_view_public_key) {
  35.                 continue;
  36.             }
  37.  
  38.             crypto::public_key out_pk;
  39.             if (!cryptonote::get_output_public_key(ptx.tx.vout[i], out_pk)) {
  40.                 throw std::runtime_error("Unable to get output public key from transaction out");
  41.             }
  42.  
  43.             std::vector<crypto::secret_key> keys_to_try = ptx.additional_tx_keys;
  44.             keys_to_try.push_back(ptx.tx_key);
  45.  
  46.             bool found_key = false;
  47.             crypto::secret_key matched_key = crypto::null_skey;
  48.  
  49.             for (const auto &candidate_key: keys_to_try) {
  50.                 // compute derivation from recipient view pubkey and our tx secret key
  51.                 crypto::key_derivation derivation;
  52.                 if (!crypto::generate_key_derivation(dest_entry.addr.m_view_public_key, candidate_key, derivation)) {
  53.                     continue;
  54.                 }
  55.  
  56.                 // derive expected output public key and compare
  57.                 crypto::public_key expected_out_pk;
  58.                 if (!crypto::derive_public_key(derivation, i, dest_entry.addr.m_spend_public_key, expected_out_pk)) {
  59.                     continue;
  60.                 }
  61.  
  62.                 if (expected_out_pk == out_pk) {
  63.                     found_key = true;
  64.                     matched_key = candidate_key;
  65.                     break;
  66.                 }
  67.             }
  68.  
  69.             if (!found_key) {
  70.                 throw std::runtime_error("No matching tx key found for output");
  71.             }
  72.  
  73.             // push (txid, destination address (human-readable), hex(tx_secret_key))
  74.             const std::string dest_addr_str = dest_entry.address(m_wallet.m_wallet->nettype(), crypto::null_hash);
  75.             keys.emplace_back(
  76.                 current_tx_hash,
  77.                 dest_addr_str,
  78.                 epee::string_tools::pod_to_hex(unwrap(unwrap(matched_key)))
  79.             );
  80.         }
  81.     }
  82.  
  83.     return keys;
  84. }
Advertisement
Add Comment
Please, Sign In to add comment