diff --git a/src/page.h b/src/page.h index 0077b08..c35eda4 100644 --- a/src/page.h +++ b/src/page.h @@ -662,6 +662,8 @@ namespace xmreg { delta_time[3], delta_time[4]); } + cout << _tx_info.tx_json << endl; + // sum xmr in inputs and ouputs in the given tx pair sum_inputs = sum_xmr_inputs(_tx_info.tx_json); pair sum_outputs = sum_xmr_outputs(_tx_info.tx_json); @@ -669,6 +671,11 @@ namespace xmreg { // get mixin number in each transaction vector mixin_numbers = get_mixin_no_in_txs(_tx_info.tx_json); + uint64_t mixin_no = 0; + + if (!mixin_numbers.empty()) + mixin_numbers.at(0) - 1; + // set output page template map txs.push_back(mstch::map { {"timestamp" , xmreg::timestamp_to_str(_tx_info.receive_time)}, @@ -679,7 +686,7 @@ namespace xmreg { {"xmr_outputs" , fmt::format("{:0.2f}", XMR_AMOUNT(sum_outputs.first))}, {"no_inputs" , sum_inputs.second}, {"no_outputs" , sum_outputs.second}, - {"mixin" , fmt::format("{:d}", mixin_numbers.at(0) - 1)}, + {"mixin" , fmt::format("{:d}", mixin_no)}, {"txsize" , fmt::format("{:0.2f}", static_cast(_tx_info.blob_size)/1024.0)} }); } @@ -1227,7 +1234,10 @@ namespace xmreg { } string - show_my_outputs(string tx_hash_str, string xmr_address_str, string viewkey_str) + show_my_outputs(string tx_hash_str, + string xmr_address_str, + string viewkey_str, /* or tx_prv_key_str when tx_prove == true */ + bool tx_prove = false) { // remove white characters @@ -1247,7 +1257,10 @@ namespace xmreg { if (viewkey_str.empty()) { - return string("Viewkey not provided!"); + if (!tx_prove) + return string("Viewkey not provided!"); + else + return string("Tx private key not provided!"); } // parse tx hash string to hash object @@ -1268,16 +1281,15 @@ namespace xmreg { return string("Cant parse xmr address: " + xmr_address_str); } - // parse string representing given private viewkey + // parse string representing given private key crypto::secret_key prv_view_key; if (!xmreg::parse_str_secret_key(viewkey_str, prv_view_key)) { - cerr << "Cant parse view key: " << viewkey_str << endl; - return string("Cant parse view key: " + viewkey_str); + cerr << "Cant parse the private key: " << viewkey_str << endl; + return string("Cant parse private key: " + viewkey_str); } - // tx age pair age; @@ -1378,7 +1390,7 @@ namespace xmreg { {"has_payment_id8" , txd.payment_id8 != null_hash8}, {"payment_id" , pid_str}, {"payment_id8" , pid8_str}, - {"tx_prove" , false} + {"tx_prove" , tx_prove} }; string server_time_str = xmreg::timestamp_to_str(server_timestamp, "%F"); @@ -1389,16 +1401,17 @@ namespace xmreg { // to create, so called, derived key. key_derivation derivation; - if (!generate_key_derivation(txd.pk, prv_view_key, derivation)) + public_key pub_key = tx_prove ? address.m_view_public_key : txd.pk; + + if (!generate_key_derivation(pub_key, prv_view_key, derivation)) { - cerr << "Cant get dervied key for: " << "\n" - << "pub_tx_key: " << txd.pk << " and " + cerr << "Cant get derived key for: " << "\n" + << "pub_tx_key: " << pub_key << " and " << "prv_view_key" << prv_view_key << endl; return string("Cant get key_derivation"); } - mstch::array outputs; uint64_t sum_xmr {0}; @@ -1415,15 +1428,15 @@ namespace xmreg { // get the tx output public key // that normally would be generated for us, // if someone had sent us some xmr. - public_key pubkey; + public_key tx_pubkey; derive_public_key(derivation, output_idx, address.m_spend_public_key, - pubkey); + tx_pubkey); // check if generated public key matches the current output's key - bool mine_output = (outp.first.key == pubkey); + bool mine_output = (outp.first.key == tx_pubkey); // if mine output has RingCT, i.e., tx version is 2 if (mine_output && tx.version == 2) @@ -1434,7 +1447,7 @@ namespace xmreg { bool r; r = decode_ringct(tx.rct_signatures, - txd.pk, + pub_key, prv_view_key, i, tx.rct_signatures.ecdhInfo[i].mask, @@ -1491,264 +1504,7 @@ namespace xmreg { string xmr_address_str, string tx_prv_key_str) { - - // remove white characters - boost::trim(tx_hash_str); - boost::trim(xmr_address_str); - boost::trim(tx_prv_key_str); - - if (tx_hash_str.empty()) - { - return string("tx hash/id not provided!"); - } - - if (xmr_address_str.empty()) - { - return string("Monero address not provided!"); - } - - if (tx_prv_key_str.empty()) - { - return string("Tx private key not provided!"); - } - - // parse tx hash string to hash object - crypto::hash tx_hash; - - if (!xmreg::parse_str_secret_key(tx_hash_str, tx_hash)) - { - cerr << "Cant parse tx hash: " << tx_hash_str << endl; - return string("Cant get tx hash due to parse error: " + tx_hash_str); - } - - // parse string representing given monero address - cryptonote::account_public_address address; - - if (!xmreg::parse_str_address(xmr_address_str, address, testnet)) - { - cerr << "Cant parse string address: " << xmr_address_str << endl; - return string("Cant parse xmr address: " + xmr_address_str); - } - - // parse string representing given private viewkey - crypto::secret_key tx_prv_key; - - if (!xmreg::parse_str_secret_key(tx_prv_key_str, tx_prv_key)) - { - cerr << "Cant parse view key: " << tx_prv_key_str << endl; - return string("Cant parse view key: " + tx_prv_key_str); - } - - // tx age - pair age; - - string blk_timestamp {"N/A"}; - - // get transaction - transaction tx; - - if (!mcore->get_tx(tx_hash, tx)) - { - cerr << "Cant get tx in blockchain: " << tx_hash - << ". \n Check mempool now" << endl; - - vector> found_txs - = search_mempool(tx_hash); - - if (!found_txs.empty()) - { - // there should be only one tx found - tx = found_txs.at(0).second; - - // since its tx in mempool, it has no blk yet - // so use its recive_time as timestamp to show - - uint64_t tx_recieve_timestamp - = found_txs.at(0).first.receive_time; - - blk_timestamp = xmreg::timestamp_to_str(tx_recieve_timestamp); - - age = get_age(server_timestamp, - tx_recieve_timestamp, - FULL_AGE_FORMAT); - } - else - { - // tx is nowhere to be found :-( - return string("Cant get tx: " + tx_hash_str); - } - } - - tx_details txd = get_tx_details(tx); - - uint64_t tx_blk_height {0}; - - bool tx_blk_found {false}; - - try - { - tx_blk_height = core_storage->get_db().get_tx_block_height(tx_hash); - tx_blk_found = true; - } - catch (exception& e) - { - cerr << "Cant get block height: " << tx_hash - << e.what() << endl; - } - - - // get block cointaining this tx - block blk; - - if (tx_blk_found && !mcore->get_block_by_height(tx_blk_height, blk)) - { - cerr << "Cant get block: " << tx_blk_height << endl; - } - - string tx_blk_height_str {"N/A"}; - - if (tx_blk_found) - { - // calculate difference between tx and server timestamps - age = get_age(server_timestamp, blk.timestamp, FULL_AGE_FORMAT); - - blk_timestamp = xmreg::timestamp_to_str(blk.timestamp); - - tx_blk_height_str = std::to_string(tx_blk_height); - } - - // payments id. both normal and encrypted (payment_id8) - string pid_str = REMOVE_HASH_BRAKETS(fmt::format("{:s}", txd.payment_id)); - string pid8_str = REMOVE_HASH_BRAKETS(fmt::format("{:s}", txd.payment_id8)); - - // initalise page tempate map with basic info about blockchain - mstch::map context { - {"testnet" , testnet}, - {"tx_hash" , tx_hash_str}, - {"xmr_address" , xmr_address_str}, - {"tx_prv_key" , REMOVE_HASH_BRAKETS( - fmt::format("{:s}", tx_prv_key))}, - {"tx_pub_key" , REMOVE_HASH_BRAKETS( - fmt::format("{:s}", txd.pk))}, - {"blk_height" , tx_blk_height_str}, - {"tx_size" , fmt::format("{:0.4f}", - static_cast(txd.size) / 1024.0)}, - {"tx_fee" , fmt::format("{:0.12f}", XMR_AMOUNT(txd.fee))}, - {"blk_timestamp" , blk_timestamp}, - {"delta_time" , age.first}, - {"outputs_no" , txd.output_pub_keys.size()}, - {"has_payment_id" , txd.payment_id != null_hash}, - {"has_payment_id8" , txd.payment_id8 != null_hash8}, - {"payment_id" , pid_str}, - {"payment_id8" , pid8_str}, - {"tx_prove" , true} - }; - - string server_time_str = xmreg::timestamp_to_str(server_timestamp, "%F"); - - uint64_t output_idx {0}; - - // public transaction key is combined with our viewkey - // to create, so called, derived key. - key_derivation derivation; - - if (!generate_key_derivation(address.m_view_public_key, - tx_prv_key, - derivation)) - { - cerr << "Cant get dervied key for: " << "\n" - << "pub_tx_key: " << txd.pk << " and " - << "tx_prv_key" << tx_prv_key << endl; - - return string("Cant get key_derivation"); - } - - - mstch::array outputs; - - uint64_t sum_xmr {0}; - - std::vector money_transfered(tx.vout.size()); - - std::deque mask(tx.vout.size()); - - uint64_t i {0}; - - for (pair& outp: txd.output_pub_keys) - { - - // get the tx output public key - // that normally would be generated for us, - // if someone had sent us some xmr. - public_key pubkey; - - derive_public_key(derivation, - output_idx, - address.m_spend_public_key, - pubkey); - - // check if generated public key matches the current output's key - bool mine_output = (outp.first.key == pubkey); - - // if mine output has RingCT, i.e., tx version is 2 - if (mine_output && tx.version == 2) - { - - uint64_t rct_amount {0}; - - bool r; - - r = decode_ringct(tx.rct_signatures, - txd.pk, - tx_prv_key, - i, - tx.rct_signatures.ecdhInfo[i].mask, - money_transfered[i]); - - if (!r) - { - cerr << "Cant decode ringCT!" << endl; - } - - outp.second = money_transfered[i]; - - cout << "i, money_transfered[i]" - << i << "," - << money_transfered[i] - << endl; - } - - if (mine_output) - { - sum_xmr += outp.second; - } - - outputs.push_back(mstch::map { - {"out_pub_key" , REMOVE_HASH_BRAKETS( - fmt::format("{:s}", - outp.first.key))}, - {"amount" , fmt::format("{:0.12f}", - XMR_AMOUNT(outp.second))}, - {"mine_output" , mine_output}, - {"output_idx" , fmt::format("{:02d}", output_idx++)} - }); - - ++i; - } - - cout << "outputs.size(): " << outputs.size() << endl; - - context["outputs"] = outputs; - context["sum_xmr"] = XMR_AMOUNT(sum_xmr); - - // read my_outputs.html - string my_outputs_html = xmreg::read(TMPL_MY_OUTPUTS); - - // add header and footer - string full_page = get_full_page(my_outputs_html); - - // render the page - return mstch::render(full_page, context); + return show_my_outputs(tx_hash_str, xmr_address_str, tx_prv_key_str, true); } diff --git a/src/templates/my_outputs.html b/src/templates/my_outputs.html index d8f3f9c..dfab537 100644 --- a/src/templates/my_outputs.html +++ b/src/templates/my_outputs.html @@ -33,7 +33,7 @@ {{#tx_prove}}

Prove that you send this tx to the given address

address: {{xmr_address}}
-
Tx private key: {{tx_prv_key}}
+
Tx private key: {{viewkey}}
{{/tx_prove}}

Outputs ({{outputs_no}})