show_my_outputs method started
This commit is contained in:
parent
1d3ade509c
commit
bb8d193835
4
main.cpp
4
main.cpp
|
@ -100,6 +100,10 @@ int main(int ac, const char* av[]) {
|
||||||
return xmrblocks.show_tx(tx_hash, with_ring_signatures);
|
return xmrblocks.show_tx(tx_hash, with_ring_signatures);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CROW_ROUTE(app, "/myoutputs/<string>/<string>/<string>")
|
||||||
|
([&](string tx_hash, string xmr_address, string viewkey) {
|
||||||
|
return xmrblocks.show_my_outputs(tx_hash, xmr_address, viewkey);
|
||||||
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/search").methods("GET"_method)
|
CROW_ROUTE(app, "/search").methods("GET"_method)
|
||||||
([&](const crow::request& req) {
|
([&](const crow::request& req) {
|
||||||
|
|
189
src/page.h
189
src/page.h
|
@ -33,6 +33,7 @@
|
||||||
#define TMPL_FOOTER TMPL_DIR "/footer.html"
|
#define TMPL_FOOTER TMPL_DIR "/footer.html"
|
||||||
#define TMPL_BLOCK TMPL_DIR "/block.html"
|
#define TMPL_BLOCK TMPL_DIR "/block.html"
|
||||||
#define TMPL_TX TMPL_DIR "/tx.html"
|
#define TMPL_TX TMPL_DIR "/tx.html"
|
||||||
|
#define TMPL_MY_OUTPUTS TMPL_DIR "/my_outputs.html"
|
||||||
#define TMPL_SEARCH_RESULTS TMPL_DIR "/search_results.html"
|
#define TMPL_SEARCH_RESULTS TMPL_DIR "/search_results.html"
|
||||||
|
|
||||||
namespace xmreg {
|
namespace xmreg {
|
||||||
|
@ -1096,6 +1097,194 @@ namespace xmreg {
|
||||||
return mstch::render(full_page, context);
|
return mstch::render(full_page, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
show_my_outputs(string tx_hash_str, string xmr_address_str, string viewkey_str)
|
||||||
|
{
|
||||||
|
|
||||||
|
// 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, 0))
|
||||||
|
{
|
||||||
|
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 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// tx age
|
||||||
|
pair<string, string> 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<pair<tx_info, transaction>> 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 {
|
||||||
|
{"tx_hash" , tx_hash_str},
|
||||||
|
{"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<double>(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}
|
||||||
|
};
|
||||||
|
|
||||||
|
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(txd.pk, prv_view_key, derivation))
|
||||||
|
{
|
||||||
|
cerr << "Cant get dervied key for: " << "\n"
|
||||||
|
<< "pub_tx_key: " << txd.pk << " and "
|
||||||
|
<< "prv_view_key" << prv_view_key << endl;
|
||||||
|
|
||||||
|
return string("Cant get key_derivation");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mstch::array outputs;
|
||||||
|
|
||||||
|
|
||||||
|
for (pair<txout_to_key, uint64_t>& 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);
|
||||||
|
|
||||||
|
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++)}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
context["outputs"] = outputs;
|
||||||
|
|
||||||
|
// read tx.html
|
||||||
|
string tx_html = xmreg::read(TMPL_MY_OUTPUTS);
|
||||||
|
|
||||||
|
// add header and footer
|
||||||
|
string full_page = get_full_page(tx_html);
|
||||||
|
|
||||||
|
// render the page
|
||||||
|
return mstch::render(full_page, context);
|
||||||
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
search(string search_text)
|
search(string search_text)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<H4 style="margin:5px">Tx hash: {{tx_hash}}</H4>
|
||||||
|
<H5 style="margin:5px">Tx public key: {{tx_pub_key}}</H5>
|
||||||
|
|
||||||
|
|
||||||
|
{{#has_payment_id}}
|
||||||
|
<H5 style="margin:5px">Payment id: {{payment_id}}</H5>
|
||||||
|
{{/has_payment_id}}
|
||||||
|
|
||||||
|
{{#has_payment_id8}}
|
||||||
|
<H5 style="margin:5px">Payment id (encrypted): {{payment_id8}}</H5>
|
||||||
|
{{/has_payment_id8}}
|
||||||
|
|
||||||
|
|
||||||
|
<table class="center" style="width: 80%; margin-top:10px">
|
||||||
|
<tr>
|
||||||
|
<td>Block: {{blk_height}}</td>
|
||||||
|
<td>Timestamp [UCT]: {{blk_timestamp}}</td>
|
||||||
|
<td>Age [y:d:h:m:s]: {{delta_time}}</td>
|
||||||
|
<td>Fee: {{tx_fee}}</td>
|
||||||
|
<td>Tx size: {{tx_size}} kB</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Outputs ({{outputs_no}})</h3>
|
||||||
|
<div class="center">
|
||||||
|
<table class="center" >
|
||||||
|
<tr>
|
||||||
|
<td>Outputs public keys</td>
|
||||||
|
<td>amount</td>
|
||||||
|
<td>mine output?</td>
|
||||||
|
</tr>
|
||||||
|
{{#outputs}}
|
||||||
|
<tr>
|
||||||
|
<td>{{output_idx}}: {{out_pub_key}}</td>
|
||||||
|
<td>{{amount}}</td>
|
||||||
|
<td>{{mine_output}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/outputs}}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
Loading…
Reference in New Issue