mirror of
https://git.wownero.com/wownero/onion-wownero-blockchain-explorer.git
synced 2024-08-15 00:33:12 +00:00
Merge remote-tracking branch 'upstream/devel'
This commit is contained in:
commit
2a1fbbf9f1
5 changed files with 289 additions and 21 deletions
|
@ -19,12 +19,16 @@ endif()
|
|||
|
||||
message(STATUS MONERO_DIR ": ${MONERO_DIR}")
|
||||
|
||||
set(MONERO_SOURCE_DIR ${MONERO_DIR}
|
||||
if (NOT MONERO_SOURCE_DIR)
|
||||
set(MONERO_SOURCE_DIR ${MONERO_DIR}
|
||||
CACHE PATH "Path to the root directory for Monero")
|
||||
endif()
|
||||
|
||||
# set location of monero build tree
|
||||
set(MONERO_BUILD_DIR ${MONERO_SOURCE_DIR}/build/release/
|
||||
if (NOT MONERO_BUILD_DIR)
|
||||
# set location of monero build tree
|
||||
set(MONERO_BUILD_DIR ${MONERO_SOURCE_DIR}/build/release/
|
||||
CACHE PATH "Path to the build directory for Monero")
|
||||
endif()
|
||||
|
||||
set(MY_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake"
|
||||
CACHE PATH "The path to the cmake directory of the current project")
|
||||
|
@ -65,9 +69,16 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR WIN32)
|
|||
set_property(TARGET unbound PROPERTY IMPORTED_LOCATION ${MONERO_BUILD_DIR}/external/unbound/libunbound.a)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
# include boost headers
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
|
||||
# include monero
|
||||
include_directories(${MONERO_SOURCE_DIR}/build)
|
||||
|
||||
include_directories("ext/mstch/include")
|
||||
include_directories("ext/mstch/include/src")
|
||||
include_directories("ext/crow")
|
||||
|
||||
# add ext/ subfolder
|
||||
|
|
17
README.md
17
README.md
|
@ -25,25 +25,28 @@ Monero C++ libraries, but also demonstrates how to use:
|
|||
|
||||
Tor users:
|
||||
|
||||
- [http://dvwae436pd7nt4bc.onion](http://dvwae436pd7nt4bc.onion) (Front-end templates are [maintained by @suhz](https://github.com/suhz/onion-monero-blockchain-explorer/tree/moneroexplorer.com/src/templates)).
|
||||
- [http://dvwae436pd7nt4bc.onion](http://dvwae436pd7nt4bc.onion) (Down for now: front-end templates are [maintained by @suhz](https://github.com/suhz/onion-monero-blockchain-explorer/tree/moneroexplorer.com/src/templates)).
|
||||
|
||||
Clearnet versions:
|
||||
- [https://xmrchain.net/](https://xmrchain.net/) - https enabled, most popular and very stable.
|
||||
- [https://MoneroExplorer.com/](https://moneroexplorer.com/) - nice looking one, https enabled.
|
||||
- [https://monerohash.com/explorer/](https://monerohash.com/explorer/) - nice looking one, https enabled.
|
||||
- [http://explore.MoneroWorld.com](http://explore.moneroworld.com) - same as the second one.
|
||||
- [http://monerochain.com/](http://monerochain.com/) - JSON API based, multiple nodes.
|
||||
- [https://blox.minexmr.com/](https://blox.minexmr.com/) - - https enabled.
|
||||
- [https://community.xmr.to/explorer/mainnet/](https://community.xmr.to/explorer/mainnet/)
|
||||
|
||||
|
||||
Testnet version:
|
||||
|
||||
- [https://testnet.xmrchain.com/](https://testnet.xmrchain.com/) - https enabled.
|
||||
- [https://explorer.monero-otc.com/](https://explorer.monero-otc.com/) - https enabled.
|
||||
- [https://community.xmr.to/explorer/testnet/](https://community.xmr.to/explorer/testnet/)
|
||||
|
||||
Stagenet version:
|
||||
|
||||
- [https://stagenet.xmrchain.net/](https://stagenet.xmrchain.net/)
|
||||
- [http://139.162.60.17:8082/](http://139.162.60.17:8082/)
|
||||
- [http://162.210.173.150:8083/](http://162.210.173.150:8083/)
|
||||
- [https://community.xmr.to/explorer/stagenet/](https://community.xmr.to/explorer/stagenet/)
|
||||
|
||||
i2p users (main Monero network):
|
||||
|
||||
|
@ -86,11 +89,11 @@ Current development branch:
|
|||
|
||||
- https://github.com/moneroexamples/onion-monero-blockchain-explorer/tree/devel
|
||||
|
||||
|
||||
Note: `devel` branch of the explorer follows `master` branch of the monero.
|
||||
|
||||
## Compilation on Ubuntu 16.04/18.04
|
||||
|
||||
##### Compile latest Monero version (0.13)
|
||||
##### Compile latest Monero version (0.14.0.0)
|
||||
|
||||
Download and compile recent Monero into your home folder:
|
||||
|
||||
|
@ -103,11 +106,11 @@ sudo apt install git build-essential cmake libboost-all-dev miniupnpc libunbound
|
|||
# go to home folder
|
||||
cd ~
|
||||
|
||||
git clone --recursive https://github.com/monero-project/monero
|
||||
# download monero sourced for branch release-v0.13
|
||||
git clone --recursive -b release-v0.13 https://github.com/monero-project/monero.git
|
||||
|
||||
cd monero/
|
||||
|
||||
|
||||
USE_SINGLE_BUILDDIR=1 make
|
||||
```
|
||||
|
||||
|
|
7
main.cpp
7
main.cpp
|
@ -336,9 +336,14 @@ main(int ac, const char* av[])
|
|||
return crow::response(xmrblocks.show_block_hex(block_height, true));
|
||||
});
|
||||
|
||||
// CROW_ROUTE(app, "/ringmemberstxhex/<string>")
|
||||
// ([&](string tx_hash) {
|
||||
// return crow::response(xmrblocks.show_ringmemberstx_hex(remove_bad_chars(tx_hash)));
|
||||
// });
|
||||
|
||||
CROW_ROUTE(app, "/ringmemberstxhex/<string>")
|
||||
([&](string tx_hash) {
|
||||
return crow::response(xmrblocks.show_ringmemberstx_hex(remove_bad_chars(tx_hash)));
|
||||
return myxmr::jsonresponse {xmrblocks.show_ringmemberstx_jsonhex(remove_bad_chars(tx_hash))};
|
||||
});
|
||||
|
||||
}
|
||||
|
|
260
src/page.h
260
src/page.h
|
@ -22,15 +22,20 @@
|
|||
|
||||
#include "../ext/crow/crow.h"
|
||||
|
||||
#include "../ext/json.hpp"
|
||||
|
||||
#include "../ext/vpetrigocaches/cache.hpp"
|
||||
#include "../ext/vpetrigocaches/lru_cache_policy.hpp"
|
||||
#include "../ext/vpetrigocaches/fifo_cache_policy.hpp"
|
||||
#include "../ext/mstch/src/visitor/render_node.hpp"
|
||||
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <ctime>
|
||||
#include <future>
|
||||
#include <visitor/render_node.hpp>
|
||||
|
||||
|
||||
|
||||
#define TMPL_DIR "./templates"
|
||||
|
@ -190,8 +195,6 @@ using namespace std;
|
|||
using epee::string_tools::pod_to_hex;
|
||||
using epee::string_tools::hex_to_pod;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief The tx_details struct
|
||||
*
|
||||
|
@ -1842,7 +1845,248 @@ show_ringmemberstx_hex(string const& tx_hash_str)
|
|||
::buff_to_hex_nodelimer(oss.str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get ring member tx data
|
||||
*
|
||||
* Used for generating json file of txs used in unit testing.
|
||||
* Thanks to json output from this function, we can mock
|
||||
* a number of blockchain quries about key images
|
||||
*
|
||||
* @param tx_hash_str
|
||||
* @return
|
||||
*/
|
||||
json
|
||||
show_ringmemberstx_jsonhex(string const& tx_hash_str)
|
||||
{
|
||||
transaction tx;
|
||||
crypto::hash tx_hash;
|
||||
|
||||
if (!get_tx(tx_hash_str, tx, tx_hash))
|
||||
return string {"Cant get tx: "} + tx_hash_str;
|
||||
|
||||
vector<txin_to_key> input_key_imgs = xmreg::get_key_images(tx);
|
||||
|
||||
json tx_json;
|
||||
|
||||
string tx_hex;
|
||||
|
||||
try
|
||||
{
|
||||
tx_hex = tx_to_hex(tx);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
cerr << e.what() << endl;
|
||||
return json {"error", "Failed to obtain hex of tx"};
|
||||
}
|
||||
|
||||
tx_json["hash"] = tx_hash_str;
|
||||
tx_json["hex"] = tx_hex;
|
||||
tx_json["nettype"] = static_cast<size_t>(nettype);
|
||||
tx_json["is_ringct"] = (tx.version > 1);
|
||||
tx_json["rct_type"] = tx.rct_signatures.type;
|
||||
|
||||
tx_json["_comment"] = "Just a placeholder for some comment if needed later";
|
||||
|
||||
// add placeholder for sender and recipient details
|
||||
// this is most useful for unit testing on stagenet/testnet
|
||||
// private monero networks, so we can easly put these
|
||||
// networks accounts details here.
|
||||
tx_json["sender"] = json {
|
||||
{"seed", ""},
|
||||
{"address", ""},
|
||||
{"viewkey", ""},
|
||||
{"spendkey", ""},
|
||||
{"amount", 0ull},
|
||||
{"change", 0ull},
|
||||
{"outputs", json::array({json::array(
|
||||
{"index placeholder",
|
||||
"public_key placeholder",
|
||||
"amount placeholder"}
|
||||
)})
|
||||
},
|
||||
{"_comment", ""}};
|
||||
|
||||
tx_json["recipient"] = json::array();
|
||||
|
||||
|
||||
tx_json["recipient"].push_back(
|
||||
json { {"seed", ""},
|
||||
{"address", ""},
|
||||
{"is_subaddress", false},
|
||||
{"viewkey", ""},
|
||||
{"spendkey", ""},
|
||||
{"amount", 0ull},
|
||||
{"outputs", json::array({json::array(
|
||||
{"index placeholder",
|
||||
"public_key placeholder",
|
||||
"amount placeholder"}
|
||||
)})
|
||||
},
|
||||
{"_comment", ""}});
|
||||
|
||||
|
||||
uint64_t tx_blk_height {0};
|
||||
|
||||
try
|
||||
{
|
||||
tx_blk_height = core_storage->get_db().get_tx_block_height(tx_hash);
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
cerr << "Cant get block height: " << tx_hash
|
||||
<< e.what() << endl;
|
||||
|
||||
return json {"error", "Cant get block height"};
|
||||
}
|
||||
|
||||
// get block cointaining this tx
|
||||
block blk;
|
||||
|
||||
if ( !mcore->get_block_by_height(tx_blk_height, blk))
|
||||
{
|
||||
cerr << "Cant get block: " << tx_blk_height << endl;
|
||||
return json {"error", "Cant get block"};
|
||||
}
|
||||
|
||||
block_complete_entry complete_block_data;
|
||||
|
||||
if (!mcore->get_block_complete_entry(blk, complete_block_data))
|
||||
{
|
||||
cerr << "Failed to obtain complete block data " << endl;
|
||||
return json {"error", "Failed to obtain complete block data "};
|
||||
}
|
||||
|
||||
std::string complete_block_data_str;
|
||||
|
||||
if(!epee::serialization::store_t_to_binary(
|
||||
complete_block_data, complete_block_data_str))
|
||||
{
|
||||
cerr << "Failed to serialize complete_block_data\n";
|
||||
return json {"error", "Failed to obtain complete block data"};
|
||||
}
|
||||
|
||||
tx_details txd = get_tx_details(tx);
|
||||
|
||||
tx_json["payment_id"] = pod_to_hex(txd.payment_id);
|
||||
tx_json["payment_id8"] = pod_to_hex(txd.payment_id8);
|
||||
tx_json["payment_id8e"] = pod_to_hex(txd.payment_id8);
|
||||
|
||||
tx_json["block"] = epee::string_tools
|
||||
::buff_to_hex_nodelimer(complete_block_data_str);
|
||||
|
||||
tx_json["block_version"] = json {blk.major_version, blk.minor_version};
|
||||
|
||||
tx_json["inputs"] = json::array();
|
||||
|
||||
|
||||
// key: constracted from concatenation of in_key.amount and absolute_offsets,
|
||||
// value: vector of string where string is transaction hash + output index + tx_hex
|
||||
// will have to cut this string when de-seraializing this data
|
||||
// later in the unit tests
|
||||
// transaction hash and output index represent tx_out_index
|
||||
std::map<string, vector<string>> all_mixin_txs;
|
||||
|
||||
for (txin_to_key const& in_key: input_key_imgs)
|
||||
{
|
||||
// get absolute offsets of mixins
|
||||
std::vector<uint64_t> absolute_offsets
|
||||
= cryptonote::relative_output_offsets_to_absolute(
|
||||
in_key.key_offsets);
|
||||
|
||||
//tx_out_index is pair::<transaction hash, output index>
|
||||
vector<tx_out_index> indices;
|
||||
std::vector<output_data_t> mixin_outputs;
|
||||
|
||||
// get tx hashes and indices in the txs for the
|
||||
// given outputs of mixins
|
||||
// this cant THROW DB_EXCEPTION
|
||||
try
|
||||
{
|
||||
// get tx of the real output
|
||||
core_storage->get_db().get_output_tx_and_index(
|
||||
in_key.amount, absolute_offsets, indices);
|
||||
|
||||
// get mining ouput info
|
||||
core_storage->get_db().get_output_key(
|
||||
in_key.amount,
|
||||
absolute_offsets,
|
||||
mixin_outputs);
|
||||
}
|
||||
catch (exception const& e)
|
||||
{
|
||||
|
||||
string out_msg = fmt::format(
|
||||
"Cant get ring member tx_out_index for tx {:s}", tx_hash_str
|
||||
);
|
||||
|
||||
cerr << out_msg << endl;
|
||||
|
||||
return json {"error", out_msg};
|
||||
}
|
||||
|
||||
|
||||
tx_json["inputs"].push_back(json {{"key_image", pod_to_hex(in_key.k_image)},
|
||||
{"amount", in_key.amount},
|
||||
{"absolute_offsets", absolute_offsets},
|
||||
{"ring_members", json::array()}});
|
||||
|
||||
json& ring_members = tx_json["inputs"].back()["ring_members"];
|
||||
|
||||
|
||||
if (indices.size() != mixin_outputs.size())
|
||||
{
|
||||
cerr << "indices.size() != mixin_outputs.size()\n";
|
||||
return json {"error", "indices.size() != mixin_outputs.size()"};
|
||||
}
|
||||
|
||||
// serialize each mixin tx
|
||||
//for (auto const& txi : indices)
|
||||
for (size_t i = 0; i < indices.size(); ++i)
|
||||
{
|
||||
|
||||
tx_out_index const& txi = indices[i];
|
||||
output_data_t const& mo = mixin_outputs[i];
|
||||
|
||||
auto const& mixin_tx_hash = txi.first;
|
||||
auto const& output_index_in_tx = txi.second;
|
||||
|
||||
transaction mixin_tx;
|
||||
|
||||
if (!mcore->get_tx(mixin_tx_hash, mixin_tx))
|
||||
{
|
||||
throw std::runtime_error("Cant get tx: "
|
||||
+ pod_to_hex(mixin_tx_hash));
|
||||
}
|
||||
|
||||
// serialize tx
|
||||
string tx_hex = epee::string_tools::buff_to_hex_nodelimer(
|
||||
t_serializable_object_to_blob(mixin_tx));
|
||||
|
||||
ring_members.push_back(
|
||||
json {
|
||||
{"ouput_pk", pod_to_hex(mo.pubkey)},
|
||||
{"tx_hash", pod_to_hex(mixin_tx_hash)},
|
||||
{"output_index_in_tx", txi.second},
|
||||
{"tx_hex", tx_hex},
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
} // for (txin_to_key const& in_key: input_key_imgs)
|
||||
|
||||
|
||||
// archive all_mixin_outputs vector
|
||||
std::ostringstream oss;
|
||||
boost::archive::portable_binary_oarchive archive(oss);
|
||||
archive << all_mixin_txs;
|
||||
|
||||
// return as all_mixin_outputs vector hex
|
||||
//return epee::string_tools
|
||||
// ::buff_to_hex_nodelimer(oss.str());
|
||||
|
||||
return tx_json;
|
||||
}
|
||||
|
||||
string
|
||||
show_my_outputs(string tx_hash_str,
|
||||
|
@ -2162,8 +2406,11 @@ show_my_outputs(string tx_hash_str,
|
|||
address_info.address.m_spend_public_key,
|
||||
tx_pubkey);
|
||||
|
||||
//cout << pod_to_hex(outp.first.key) << endl;
|
||||
//cout << pod_to_hex(tx_pubkey) << endl;
|
||||
// cout << pod_to_hex(derivation) << ", " << output_idx << ", "
|
||||
// << pod_to_hex(address_info.address.m_spend_public_key) << ", "
|
||||
// << pod_to_hex(outp.first.key) << " == "
|
||||
// << pod_to_hex(tx_pubkey) << '\n' << '\n';
|
||||
|
||||
|
||||
// check if generated public key matches the current output's key
|
||||
bool mine_output = (outp.first.key == tx_pubkey);
|
||||
|
@ -2178,6 +2425,7 @@ show_my_outputs(string tx_hash_str,
|
|||
address_info.address.m_spend_public_key,
|
||||
tx_pubkey);
|
||||
|
||||
|
||||
mine_output = (outp.first.key == tx_pubkey);
|
||||
|
||||
with_additional = true;
|
||||
|
@ -4642,7 +4890,7 @@ json_block(string block_no_or_hash)
|
|||
{"data" , json {}}
|
||||
};
|
||||
|
||||
json& j_data = j_response["data"];
|
||||
nlohmann::json& j_data = j_response["data"];
|
||||
|
||||
uint64_t current_blockchain_height
|
||||
= core_storage->get_current_blockchain_height();
|
||||
|
|
|
@ -936,6 +936,7 @@ decode_ringct(rct::rctSig const& rv,
|
|||
{
|
||||
case rct::RCTTypeSimple:
|
||||
case rct::RCTTypeBulletproof:
|
||||
case rct::RCTTypeBulletproof2:
|
||||
amount = rct::decodeRctSimple(rv,
|
||||
rct::sk2rct(scalar1),
|
||||
i,
|
||||
|
|
Loading…
Reference in a new issue