Code Monkey home page Code Monkey logo

onion-monero-blockchain-explorer's Introduction

Onion Monero Blockchain Explorer

Currently available Monero blockchain explorers have several limitations which are of special importance to privacy-oriented users:

  • they use JavaScript,
  • have images which might be used for cookieless tracking,
  • track users activities through google analytics,
  • are closed sourced,
  • are not available as hidden services,
  • do not support Monero testnet nor stagenet networks,
  • have limited JSON API.

In this example, these limitations are addressed by development of an Onion Monero Blockchain Explorer. The example not only shows how to use Monero C++ libraries, but also demonstrates how to use:

  • crow - C++ micro web framework
  • mstch - C++ {{mustache}} templates
  • json - JSON for Modern C++
  • fmt - Small, safe and fast string formatting library

Explorer hosts

Clearnet versions:

Testnet version:

Stagenet version:

i2p users (main Monero network):

Tor versions:

Alternative block explorers:

Onion Monero Blockchain Explorer features

The key features of the Onion Monero Blockchain Explorer are:

  • no cookies, no web analytics trackers, no images,
  • open sourced,
  • made fully in C++,
  • showing encrypted payments ID,
  • showing ring signatures,
  • showing transaction extra field,
  • showing public components of Monero addresses,
  • decoding which outputs and mixins belong to the given Monero address and viewkey,
  • can prove that you send Monero to someone,
  • detailed information about ring members, such as their age, timescale, and ring sizes,
  • showing number of amount output indices,
  • support Monero testnet and stagnet networks,
  • tx checker and pusher for online pushing of transactions,
  • estimate possible spendings based on address and viewkey,
  • can provide total amount of all miner fees,
  • decoding encrypted payment id,
  • decoding outputs and proving txs sent to sub-address.

Development branch

Current development branch:

Note: devel branch of the explorer follows master branch of the monero!

Compilation on Ubuntu 18.04/20.04

Monero download and compilation

To download and compile recent Monero follow instructions in the following link:

https://github.com/moneroexamples/monero-compilation/blob/master/README.md

Compile and run the explorer

Once the Monero compiles, the explorer can be downloaded and compiled as follows:

# go to home folder if still in ~/monero
cd ~

# download the source code 
git clone https://github.com/moneroexamples/onion-monero-blockchain-explorer.git

# enter the downloaded sourced code folder
cd onion-monero-blockchain-explorer

# make a build folder and enter it
mkdir build && cd build

# create the makefile
cmake ..

# compile
make

To run it:

./xmrblocks

By default it will look for blockchain in its default location i.e., ~/.bitmonero/lmdb. You can use -b option if its in different location.

For example:

./xmrblocks -b /home/mwo/non-default-monero-location/lmdb/

Example output:

[mwo@arch onion-monero-blockchain-explorer]$ ./xmrblocks
2016-May-28 10:04:49.160280 Blockchain initialized. last block: 1056761, d0.h0.m12.s47 time ago, current difficulty: 1517857750
(2016-05-28 02:04:49) [INFO    ] Crow/0.1 server is running, local port 8081

Go to your browser: http://127.0.0.1:8081

Compiling and running with Docker

The explorer can also be compiled using docker build as described below. By default it compiles against latest release (release-v0.17) branch of monero:

# build using all CPU cores
docker build --no-cache -t xmrblocks .

# alternatively, specify number of cores to use (e.g. 2)
docker build --no-cache --build-arg NPROC=2  -t xmrblocks .

# to build against development branch of monero (i.e. master branch)
docker build --no-cache --build-arg NPROC=3 --build-arg MONERO_BRANCH=master  -t xmrblocks .
  • The build needs 3 GB space.
  • The final container image is 179MB.

To run it, mount the monero blockchain onto the container as volume.

# either run in foreground
docker run -it -v <path-to-monero-blockckain-on-the-host>:/home/monero/.bitmonero -p 8081:8081  xmrblocks

# or in background
docker run -it -d -v <path-to-monero-blockchain-on-the-host>:/home/monero/.bitmonero -p 8081:8081  xmrblocks

Example output:

docker run --rm -it -v /mnt/w7/bitmonero:/home/monero/.bitmonero -p 8081:8081 xmrblocks
Staring in non-ssl mode
(2020-04-20 16:20:00) [INFO    ] Crow/0.1 server is running at 0.0.0.0:8081 using 1 threads

Docker Compose example

The explorer can also be built and run using Docker Compose, i.e.:

version: '3'
services:
  monerod:
    image: sethsimmons/simple-monerod:latest
    restart: unless-stopped
    container_name: monerod
    volumes:
      - xmrdata:/home/monero/.bitmonero
    ports:
      - 18080:18080
      - 18089:18089
    depends_on:
        - explore
    command:
      - "--rpc-restricted-bind-ip=0.0.0.0"
      - "--rpc-restricted-bind-port=18089"
      - "--public-node"
      - "--no-igd"
      - "--enable-dns-blocklist"

  explore:
    image: xmrblocks:latest
    build: ./onion-monero-blockchain-explorer
    container_name: explore
    restart: unless-stopped
    volumes:
      - xmrdata:/home/monero/.bitmonero
    ports:
      - 8081:8081
    command: ["./xmrblocks --daemon-url=monerod:18089 --enable-json-api --enable-autorefresh-option --enable-emission-monitor --enable-pusher"]

volumes:
  xmrdata:

To build this image, run the following:

git clone https://github.com/moneroexamples/onion-monero-blockchain-explorer.git
docker-compose build

Or build and run in one step via:

git clone https://github.com/moneroexamples/onion-monero-blockchain-explorer.git
docker-compose up -d

When running via Docker, please use something like Traefik or enable SSL to secure communications.

The explorer's command line options

xmrblocks, Onion Monero Blockchain Explorer:
  -h [ --help ] [=arg(=1)] (=0)         produce help message
  -t [ --testnet ] [=arg(=1)] (=0)      use testnet blockchain
  -s [ --stagenet ] [=arg(=1)] (=0)     use stagenet blockchain
  --enable-pusher [=arg(=1)] (=0)       enable signed transaction pusher
  --enable-mixin-details [=arg(=1)] (=0)
                                        enable mixin details for key images,
                                        e.g., timescale, mixin of mixins, in tx
                                        context
  --enable-key-image-checker [=arg(=1)] (=0)
                                        enable key images file checker
  --enable-output-key-checker [=arg(=1)] (=0)
                                        enable outputs key file checker
  --enable-json-api [=arg(=1)] (=0)     enable JSON REST api
  --enable-as-hex [=arg(=1)] (=0)       enable links to provide hex
                                        represtations of a tx and a block
  --enable-autorefresh-option [=arg(=1)] (=0)
                                        enable users to have the index page on
                                        autorefresh
  --enable-emission-monitor [=arg(=1)] (=0)
                                        enable Monero total emission monitoring
                                        thread
  -p [ --port ] arg (=8081)             default explorer port
  -x [ --bindaddr ] arg (=0.0.0.0)      default bind address for the explorer
  --testnet-url arg                     you can specify testnet url, if you run
                                        it on mainnet or stagenet. link will
                                        show on front page to testnet explorer
  --stagenet-url arg                    you can specify stagenet url, if you
                                        run it on mainnet or testnet. link will
                                        show on front page to stagenet explorer
  --mainnet-url arg                     you can specify mainnet url, if you run
                                        it on testnet or stagenet. link will
                                        show on front page to mainnet explorer
  --no-blocks-on-index arg (=10)        number of last blocks to be shown on
                                        index page
  --mempool-info-timeout arg (=5000)    maximum time, in milliseconds, to wait
                                        for mempool data for the front page
  --mempool-refresh-time arg (=5)       time, in seconds, for each refresh of
                                        mempool state
  -c [ --concurrency ] arg (=0)         number of threads handling http
                                        queries. Default is 0 which means it is
                                        based you on the cpu
  -b [ --bc-path ] arg                  path to lmdb folder of the blockchain,
                                        e.g., ~/.bitmonero/lmdb
  --ssl-crt-file arg                    path to crt file for ssl (https)
                                        functionality
  --ssl-key-file arg                    path to key file for ssl (https)
                                        functionality
  -d [ --daemon-url ] arg (=http:://127.0.0.1:18081)
                                        Monero daemon url
  --daemon-login arg                    Specify username[:password] for daemon 
                                        RPC client
  --enable-mixin-guess [=arg(=1)] (=0)  enable guessing real outputs in key

Example usage, defined as bash aliases.

# for mainnet explorer
alias xmrblocksmainnet='~/onion-monero-blockchain-explorer/build/xmrblocks    --port 8081 --testnet-url "http://139.162.32.245:8082" --enable-pusher --enable-emission-monitor'

# for testnet explorer
alias xmrblockstestnet='~/onion-monero-blockchain-explorer/build/xmrblocks -t --port 8082 --mainnet-url "http://139.162.32.245:8081" --enable-pusher --enable-emission-monitor'

Example usage when running via Docker:

# Run in foreground
docker run -it -v <path-to-monero-blockckain-on-the-host>:/home/monero/.bitmonero -p 8081:8081  xmrblocks "./xmrblocks --daemon-url=node.sethforprivacy.com:18089 --enable-json-api --enable-autorefresh-option --enable-emission-monitor --enable-pusher"

# Run in background
docker run -it -d -v <path-to-monero-blockchain-on-the-host>:/home/monero/.bitmonero -p 8081:8081  xmrblocks "./xmrblocks --daemon-url=node.sethforprivacy.com:18089 --enable-json-api --enable-autorefresh-option --enable-emission-monitor --enable-pusher"

Make sure to always start the portion of command line flags with ./xmrblocks and set any flags you would like after that, as shown above.

Enable Monero emission

Obtaining current Monero emission amount is not straight forward. Thus, by default it is disabled. To enable it use --enable-emission-monitor flag, e.g.,

xmrblocks --enable-emission-monitor

This flag will enable emission monitoring thread. When started, the thread will initially scan the entire blockchain, and calculate the cumulative emission based on each block. Since it is a separate thread, the explorer will work as usual during this time. Every 10000 blocks, the thread will save current emission in a file, by default, in ~/.bitmonero/lmdb/emission_amount.txt. For testnet or stagenet networks, it is ~/.bitmonero/testnet/lmdb/emission_amount.txt or ~/.bitmonero/stagenet/lmdb/emission_amount.txt. This file is used so that we don't need to rescan entire blockchain whenever the explorer is restarted. When the explorer restarts, the thread will first check if ~/.bitmonero/lmdb/emission_amount.txt is present, read its values, and continue from there if possible. Subsequently, only the initial use of the thread is time consuming. Once the thread scans the entire blockchain, it updates the emission amount using new blocks as they come. Since the explorer writes this file, there can be only one instance of it running for mainnet, testnet and stagenet. Thus, for example, you can't have two explorers for mainnet running at the same time, as they will be trying to write and read the same file at the same time, leading to unexpected results. Off course having one instance for mainnet and one instance for testnet is fine, as they write to different files.

When the emission monitor is enabled, information about current emission of coinbase and fees is displayed on the front page, e.g., :

Monero emission (fees) is 14485540.430 (52545.373) as of 1313448 block

The values given, can be checked using Monero daemon's print_coinbase_tx_sum command. For example, for the above example: print_coinbase_tx_sum 0 1313449.

To disable the monitor, simply restart the explorer without --enable-emission-monitor flag.

Enable SSL (https)

By default, the explorer does not use ssl. But it has such a functionality.

As an example, you can generate your own ssl certificates as follows:

cd /tmp # example folder
openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt

Having the crt and key files, run xmrblocks in the following way:

./xmrblocks --ssl-crt-file=/tmp/server.crt --ssl-key-file=/tmp/server.key

Note: Because we generated our own certificate, modern browsers will complain about it as they can't verify the signatures against any third party. So probably for any practical use need to have properly issued ssl certificates.

JSON API

The explorer has JSON api. For the API, it uses conventions defined by JSend. By default the api is disabled. To enable it, use --enable-json-api flag, e.g.,

./xmrblocks --enable-json-api

api/transaction/<tx_hash>

curl  -w "\n" -X GET "http://127.0.0.1:8081/api/transaction/6093260dbe79fd6277694d14789dc8718f1bd54457df8bab338c2efa3bb0f03d"

Partial results shown:

{
  "data": {
    "block_height": 1268252,
    "coinbase": false,
    "confirmations": 1057855,
    "current_height": 2326107,
    "extra": "01be23e277aed6b5f41f66b05244bf994c13108347366ec678ae16657f0fc3a22b",
    "inputs": [
      {
        "amount": 0,
        "key_image": "67838fd0ffd79f13e735830d3ec60412aed59e53e1f997feb6f73d088b949611",
        "mixins": [
          {
            "block_no": 1238623,
            "public_key": "0a5b853c55303c10e1326acfb085b9e246e088b1ccac7e37f7a810d46a28a914",
            "tx_hash": "686555fb053dd53f6f9eb79449e2bdcd377221f823f508158d70d4a1966fe955"
          },
          {
            "block_no": 1246942,
            "public_key": "527cf86f5abbfb006c970f7c6eb40493786d4751306f8985c6a43f98a88c0dff",
            "tx_hash": "4fa1999f9e0d2ad031dbe5594f2e8336651b6cad19dd3cee7980a01c47600f91"
          }
        ]
      }
    ],
    "mixin": 9,
    "outputs": [
      {
        "amount": 0,
        "public_key": "525779873776e4a42f517fd79b72e7c31c3ba03e730fc32287f6414fb702c1d7"
      },
      {
        "amount": 0,
        "public_key": "e25f00fceb77af841d780b68647618812695b4ca6ebe338faba6e077f758ac30"
      }
    ],
    "payment_id": "",
    "payment_id8": "",
    "rct_type": 1,
    "timestamp": 1489753456,
    "timestamp_utc": "2017-03-17 12:24:16",
    "tx_fee": 12517785574,
    "tx_hash": "6093260dbe79fd6277694d14789dc8718f1bd54457df8bab338c2efa3bb0f03d",
    "tx_size": 13323,
    "tx_version": 2,
    "xmr_inputs": 0,
    "xmr_outputs": 0
  },
  "status": "success"
}

api/transactions

Transactions in last 25 blocks

curl  -w "\n" -X GET "http://127.0.0.1:8081/api/transactions"

Partial results shown:

{
  "data": {
    "blocks": [
      {
        "age": "33:16:49:53",
        "height": 1268252,
        "size": 105390000000000000,
        "timestamp": 1489753456,
        "timestamp_utc": "2017-03-17 12:24:16",
        "txs": [
          {
            "coinbase": true,
            "mixin": 0,
            "outputs": 8491554678365,
            "rct_type": 0,
            "tx_fee": 0,
            "tx_hash": "7c4286f64544568265bb5418df84ae69afaa3567749210e46f8340c247f4803f",
            "tx_size": 151000000000000,
            "tx_version": 2
          },
          {
            "coinbase": false,
            "mixin": 5,
            "outputs": 0,
            "rct_type": 2,
            "tx_fee": 17882516700,
            "tx_hash": "2bfbccb918ee5f050808dd040ce03943b7315b81788e9cdee59cf86b557ba48c",
            "tx_size": 19586000000000000,
            "tx_version": 2
          }
        ]
      }
    ],
    "limit": 25,
    "page": 0
  },
  "status": "success"
}

api/transactions?page=<page_no>&limit=<tx_per_page>

curl  -w "\n" -X GET "http://127.0.0.1:8081/api/transactions?page=2&limit=10"

Result analogical to the one above.

api/block/<block_number|block_hash>

curl  -w "\n" -X GET "http://139.162.32.245:8081/api/block/1293257"

Partial results shown:

{
  "data": {
    "block_height": 1293257,
    "block_reward": 0,
    "current_height": 1293264,
    "hash": "9ef6bb8f9b8bd253fc6390e5c2cdc45c8ee99fad16447437108bf301fe6bd6e1",
    "size": 141244,
    "timestamp": 1492761974,
    "timestamp_utc": "2017-04-21 08:06:14",
    "txs": [
      {
        "coinbase": true,
        "extra": "018ae9560eb85d5ebd22d3beaed55c21d469eab430c5e3cac61b3fe2f5ad156770020800000001a9030800",
        "mixin": 0,
        "payment_id": "",
        "payment_id8": "",
        "rct_type": 0,
        "tx_fee": 0,
        "tx_hash": "3ff71b65bec34c9261e01a856e6a03594cf0472acf6b77db3f17ebd18eaa30bf",
        "tx_size": 95,
        "tx_version": 2,
        "xmr_inputs": 0,
        "xmr_outputs": 8025365394426
      }
    ]
  },
  "status": "success"
}

api/mempool

Return all txs in the mempool.

curl  -w "\n" -X GET "http://127.0.0.1:8081/api/mempool"

Partial results shown:

{
  "data": {
    "limit": 100000000,
    "page": 0,
    "total_page_no": 0,
    "txs": [
      {
        "coinbase": false,
        "extra": "022100325f677d96f94155a4840a84d8e0c905f7a4697a25744633bcb438feb1e51fb2012eda81bf552c53c2168f4130dbe0265c3a7898f3a7eee7c1fed955a778167b5d",
        "mixin": 3,
        "payment_id": "325f677d96f94155a4840a84d8e0c905f7a4697a25744633bcb438feb1e51fb2",
        "payment_id8": "",
        "rct_type": 2,
        "timestamp": 1494470894,
        "timestamp_utc": "2017-05-11 02:48:14",
        "tx_fee": 15894840000,
        "tx_hash": "9f3374f8ac67febaab153eab297937a3d0d2c706601e496bf5028146da0c9aef",
        "tx_size": 13291,
        "tx_version": 2,
        "xmr_inputs": 0,
        "xmr_outputs": 0
      }
    ],
    "txs_no": 7
  },
  "status": "success"
}

Limit of 100000000 is just default value above to ensure that all mempool txs are fetched if no specific limit given.

api/mempool?limit=<no_of_top_txs>

Return number of newest mempool txs, e.g., only 10.

curl  -w "\n" -X GET "http://127.0.0.1:8081/api/mempool?limit=10"

Result analogical to the one above.

api/search/<block_number|tx_hash|block_hash>

curl  -w "\n" -X GET "http://127.0.0.1:8081/api/search/1293669"

Partial results shown:

{
  "data": {
    "block_height": 1293669,
    "current_height": 1293670,
    "hash": "5d55b8fabf85b0b4c959d66ad509eb92ddfe5c2b0e84e1760abcb090195c1913",
    "size": 118026,
    "timestamp": 1492815321,
    "timestamp_utc": "2017-04-21 22:55:21",
    "title": "block",
    "txs": [
      {
        "coinbase": true,
        "extra": "01cb7fda09033a5fa06dc601b9295ef3790397cf3c645e958e34cf7ab699d2f5230208000000027f030200",
        "mixin": 0,
        "payment_id": "",
        "payment_id8": "",
        "rct_type": 0,
        "tx_fee": 0,
        "tx_hash": "479ba432f5c88736b438dd4446a11a13046a752d469f7828151f5c5b86be4e9a",
        "tx_size": 95,
        "tx_version": 2,
        "xmr_inputs": 0,
        "xmr_outputs": 7992697599717
      }
    ]
  },
  "status": "success"
}

api/outputs?txhash=<tx_hash>&address=&viewkey=&txprove=<0|1>

For txprove=0 we check which outputs belong to given address and corresponding viewkey. For txprove=1 we use to prove to the recipient that we sent them founds. For this, we use recipient's address and our tx private key as a viewkey value, i.e., viewkey=<tx_private_key>

Checking outputs:

# we use here official Monero project's donation address as an example
curl  -w "\n" -X GET "http://127.0.0.1:8081/api/outputs?txhash=17049bc5f2d9fbca1ce8dae443bbbbed2fc02f1ee003ffdd0571996905faa831&address=44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A&viewkey=f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501&txprove=0"
{
  "data": {
    "address": "42f18fc61586554095b0799b5c4b6f00cdeb26a93b20540d366932c6001617b75db35109fbba7d5f275fef4b9c49e0cc1c84b219ec6ff652fda54f89f7f63c88",
    "outputs": [
      {
        "amount": 34980000000000,
        "match": true,
        "output_idx": 0,
        "output_pubkey": "35d7200229e725c2bce0da3a2f20ef0720d242ecf88bfcb71eff2025c2501fdb"
      },
      {
        "amount": 0,
        "match": false,
        "output_idx": 1,
        "output_pubkey": "44efccab9f9b42e83c12da7988785d6c4eb3ec6e7aa2ae1234e2f0f7cb9ed6dd"
      }
    ],
    "tx_hash": "17049bc5f2d9fbca1ce8dae443bbbbed2fc02f1ee003ffdd0571996905faa831",
    "tx_prove": false,
    "viewkey": "f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501"
  },
  "status": "success"
}

Proving transfer:

We use recipient's address (i.e. not our address from which we sent xmr to recipient). For the viewkey, we use tx_private_key (although the GET variable is still called viewkey) that we obtained by sending this txs.

# this is for testnet transaction
curl  -w "\n" -X GET "http://127.0.0.1:8082/api/outputs?txhash=94782a8c0aa8d8768afa0c040ef0544b63eb5148ca971a024ac402cad313d3b3&address=9wUf8UcPUtb2huK7RphBw5PFCyKosKxqtGxbcKBDnzTCPrdNfJjLjtuht87zhTgsffCB21qmjxjj18Pw7cBnRctcKHrUB7N&viewkey=e94b5bfc599d2f741d6f07e3ab2a83f915e96fb374dfb2cd3dbe730e34ecb40b&txprove=1"
{
  "data": {
    "address": "71bef5945b70bc0a31dbbe6cd0bd5884fe694bbfd18fff5f68f709438554fb88a51b1291e378e2f46a0155108782c242cc1be78af229242c36d4f4d1c4f72da2",
    "outputs": [
      {
        "amount": 1000000000000,
        "match": true,
        "output_idx": 0,
        "output_pubkey": "c1bf4dd020b5f0ab70bd672d2f9e800ea7b8ab108b080825c1d6cfc0b7f7ee00"
      },
      {
        "amount": 0,
        "match": false,
        "output_idx": 1,
        "output_pubkey": "8c61fae6ada2a103565dfdd307c7145b2479ddb1dab1eaadfa6c34db65d189d5"
      }
    ],
    "tx_hash": "94782a8c0aa8d8768afa0c040ef0544b63eb5148ca971a024ac402cad313d3b3",
    "tx_prove": true,
    "viewkey": "e94b5bfc599d2f741d6f07e3ab2a83f915e96fb374dfb2cd3dbe730e34ecb40b"
  },
  "status": "success"
}

Result analogical to the one above.

api/networkinfo

curl  -w "\n" -X GET "http://127.0.0.1:8081/api/networkinfo"
{
  "data": {
    "alt_blocks_count": 0,
    "block_size_limit": 600000,
    "cumulative_difficulty": 2091549555696348,
    "difficulty": 7941560081,
    "fee_per_kb": 303970000,
    "grey_peerlist_size": 4991,
    "hash_rate": 66179667,
    "height": 1310423,
    "incoming_connections_count": 0,
    "outgoing_connections_count": 5,
    "start_time": 1494822692,
    "status": "OK",
    "target": 120,
    "target_height": 0,
    "testnet": false,
    "top_block_hash": "76f9e85d62415312758bc09e0b9b48fd2b005231ad1eee435a8081e551203f82",
    "tx_count": 1219048,
    "tx_pool_size": 2,
    "white_peerlist_size": 1000
  },
  "status": "success"
}

api/outputsblocks

Search for our outputs in last few blocks (up to 5 blocks), using provided address and viewkey.

# testnet address
curl  -w "\n" -X GET http://127.0.0.1:8081/api/outputsblocks?address=9sDyNU82ih1gdhDgrqHbEcfSDFASjFgxL9B9v5f1AytFUrYsVEj7bD9Pyx5Sw2qLk8HgGdFM8qj5DNecqGhm24Ce6QwEGDi&viewkey=807079280293998634d66e745562edaaca45c0a75c8290603578b54e9397e90a&limit=5&mempool=1

Example result:

{
  "data": {
    "address": "0182d5be0f708cecf2b6f9889738bde5c930fad846d5b530e021afd1ae7e24a687ad50af3a5d38896655669079ad0163b4a369f6c852cc816dace5fc7792b72f",
    "height": 960526,
    "limit": "5",
    "mempool": true,
    "outputs": [
      {
        "amount": 33000000000000,
        "block_no": 0,
        "in_mempool": true,
        "output_idx": 1,
        "output_pubkey": "2417b24fc99b2cbd9459278b532b37f15eab6b09bbfc44f9d17e15cd25d5b44f",
        "payment_id": "",
        "tx_hash": "9233708004c51d15f44e86ac1a3b99582ed2bede4aaac6e2dd71424a9147b06f"
      },
      {
        "amount": 2000000000000,
        "block_no": 960525,
        "in_mempool": false,
        "output_idx": 0,
        "output_pubkey": "9984101f5471dda461f091962f1f970b122d4469077aed6b978a910dc3ed4576",
        "payment_id": "0000000000000055",
        "tx_hash": "37825d0feb2e96cd10fa9ec0b990ac2e97d2648c0f23e4f7d68d2298996acefd"
      },
      {
        "amount": 96947454120000,
        "block_no": 960525,
        "in_mempool": false,
        "output_idx": 1,
        "output_pubkey": "e4bded8e2a9ec4d41682a34d0a37596ec62742b28e74b897fcc00a47fcaa8629",
        "payment_id": "0000000000000000000000000000000000000000000000000000000000001234",
        "tx_hash": "4fad5f2bdb6dbd7efc2ce7efa3dd20edbd2a91640ce35e54c6887f0ee5a1a679"
      }
    ],
    "viewkey": "807079280293998634d66e745562edaaca45c0a75c8290603578b54e9397e90a"
  },
  "status": "success"
}

api/emission

curl  -w "\n" -X GET "http://127.0.0.1:8081/api/emission"
{
  "data": {
    "blk_no": 1313969,
    "coinbase": 14489473877253413000,
    "fee": 52601974988641130
  },
  "status": "success"
}

Emission only works when the emission monitoring thread is enabled.

api/version

curl  -w "\n" -X GET "http://127.0.0.1:8081/api/version"
{
  "data": {
    "api": 65536,
    "blockchain_height": 1357031,
    "git_branch_name": "update_to_current_monero",
    "last_git_commit_date": "2017-07-25",
    "last_git_commit_hash": "a549f25",
    "monero_version_full": "0.10.3.1-ab594cfe"
  },
  "status": "success"
}

api number is store as uint32_t. In this case 65536 represents major version 1 and minor version 0. In JavaScript to get these numbers, one can do as follows:

var api_major = response.data.api >> 16;
var api_minor = response.data.api & 0xffff;

api/rawblock/<block_number|block_hash>

Return raw json block data, as represented in Monero.

curl  -w "\n" -X GET "http://139.162.32.245:8081/api/rawblock/1293257"

Example result not shown.

api/rawtransaction/<tx_hash>

Return raw json tx data, as represented in Monero.

curl  -w "\n" -X GET "http://139.162.32.245:8081/api/rawtransaction/6093260dbe79fd6277694d14789dc8718f1bd54457df8bab338c2efa3bb0f03d"

Example result not shown.

Other monero examples

Other examples can be found on github. Please know that some of the examples/repositories are not finished and may not work as intended.

How can you help?

Constructive criticism, code and website edits are always good. They can be made through github.

onion-monero-blockchain-explorer's People

Contributors

atilioa avatar bigreddmachine avatar dawe35 avatar dudecheckitout avatar erciccione avatar fuwa25519 avatar gingeropolous avatar j-berman avatar jmacxx avatar jonathancross avatar jroelofs avatar kenshi84 avatar moneroexamples avatar normoes avatar plowsof avatar selsta avatar stoffu avatar suhz avatar victoru avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

onion-monero-blockchain-explorer's Issues

get network info

Hi, I've notice a recent commit that provides Monero Network info via json api.

I am wondering if I can get and display that info in index2.html or header.html?

Web UI: Value Parameter Fuzzing leads to Null Pointer

Darwin server.local 17.3.0 Darwin Kernel Version 17.3.0: Thu Nov 9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64 x86_64

lldb

target create --no-dependents xmrblocks

process launch --environment MallocStackLogging=1 --environment MallocScribble=1 --environment MALLOC_PERMIT_INSANE_REQUESTS=22

Process 95780 stopped

  • thread #2, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x00007fff7ed3d432 libsystem_c.dylibstrlen + 18 libsystem_c.dylibstrlen:
    -> 0x7fff7ed3d432 <+18>: pcmpeqb (%rdi), %xmm0
    0x7fff7ed3d436 <+22>: pmovmskb %xmm0, %esi
    0x7fff7ed3d43a <+26>: andq $0xf, %rcx
    0x7fff7ed3d43e <+30>: orq $-0x1, %rax
    Target 0: (xmrblocks) stopped.
    (lldb) bt
  • thread #2, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    • frame #0: 0x00007fff7ed3d432 libsystem_c.dylibstrlen + 18 frame #1: 0x0000000100046145 xmrblocksstd::__1::char_traits::length(char const*) + 21
      frame #2: 0x0000000100247677 xmrblocksmain::$_16::operator()(crow::request const&) const + 375 frame #3: 0x0000000100247452 xmrblocksstd::__1::enable_if<(!(black_magic::CallHelper<main::$_16, crow::black_magic::S<> >::value)) && (black_magic::CallHelper<main::$_16, crow::black_magic::Scrow::request >::value), void>::type crow::TaggedRule<>::operator()main::$_16(main::$_16&&)::'lambda'(crow::request const&, crow::response&)::operator()(crow::request const&, crow::response&) const + 82
      frame #4: 0x00000001002473ed xmrblocksvoid std::__1::__invoke_void_return_wrapper<void>::__call<std::__1::enable_if<(!(black_magic::CallHelper<main::$_16, crow::black_magic::S<> >::value)) && (black_magic::CallHelper<main::$_16, crow::black_magic::S<crow::request> >::value), void>::type crow::TaggedRule<>::operator()<main::$_16>(main::$_16&&)::'lambda'(crow::request const&, crow::response&)&, crow::request const&, crow::response&>(std::__1::enable_if<(!(black_magic::CallHelper<main::$_16, crow::black_magic::S<> >::value)) && (black_magic::CallHelper<main::$_16, crow::black_magic::S<crow::request> >::value), void>::type crow::TaggedRule<>::operator()<main::$_16>(main::$_16&&)::'lambda'(crow::request const&, crow::response&)&&&, crow::request const&&&, crow::response&&&) + 109 frame #5: 0x00000001002472c9 xmrblocksstd::__1::__function::__func<std::__1::enable_if<(!(black_magic::CallHelper<main::$_16, crow::black_magic::S<> >::value)) && (black_magic::CallHelper<main::$_16, crow::black_magic::Scrow::request >::value), void>::type crow::TaggedRule<>::operator()main::$_16(main::$_16&&)::'lambda'(crow::request const&, crow::response&), std::__1::allocator<std::__1::enable_if<(!(black_magic::CallHelper<main::$_16, crow::black_magic::S<> >::value)) && (black_magic::CallHelper<main::$_16, crow::black_magic::Scrow::request >::value), void>::type crow::TaggedRule<>::operator()main::$_16(main::$_16&&)::'lambda'(crow::request const&, crow::response&)>, void (crow::request const&, crow::response&)>::operator()(crow::request const&, crow::response&) + 73
      frame #6: 0x00000001000c61d2 xmrblocksstd::__1::function<void (crow::request const&, crow::response&)>::operator()(crow::request const&, crow::response&) const + 178 frame #7: 0x00000001000c6110 xmrblockscrow::detail::routing_handler_call_helper::call<crow::detail::routing_handler_call_helper::call_params<std::__1::function<void (crow::request const&, crow::response&)> >, 0, 0, 0, 0, crow::black_magic::S<>, crow::black_magic::S<> >::operator()(crow::detail::routing_handler_call_helper::call_params<std::__1::function<void (crow::request const&, crow::response&)> >) + 32
      frame #8: 0x00000001000c5a9e xmrblockscrow::TaggedRule<>::handle(crow::request const&, crow::response&, crow::routing_params const&) + 110 frame #9: 0x0000000100318a1b xmrblockscrow::Router::handle(crow::request const&, crow::response&) + 6699
      frame #10: 0x00000001002fa374 xmrblockscrow::Crow<>::handle(crow::request const&, crow::response&) + 52 frame #11: 0x0000000100334d51 xmrblockscrow::Connection<crow::SocketAdaptor, crow::Crow<> >::handle() + 5105
      frame #12: 0x000000010033394c xmrblockscrow::HTTPParser<crow::Connection<crow::SocketAdaptor, crow::Crow<> > >::process_message() + 28 frame #13: 0x0000000100330c17 xmrblockscrow::HTTPParser<crow::Connection<crow::SocketAdaptor, crow::Crow<> > >::on_message_complete(http_parser*) + 2071
      frame #14: 0x00000001002eb562 xmrblockshttp_parser_execute + 15986 frame #15: 0x000000010032f461 xmrblockscrow::HTTPParser<crow::Connection<crow::SocketAdaptor, crow::Crow<> > >::feed(char const*, int) + 49
      frame #16: 0x000000010032f1cb xmrblockscrow::Connection<crow::SocketAdaptor, crow::Crow<> >::do_read()::'lambda'(boost::system::error_code const&, unsigned long)::operator()(boost::system::error_code const&, unsigned long) const + 123 frame #17: 0x000000010032f143 xmrblocksboost::asio::detail::binder2<crow::Connection<crow::SocketAdaptor, crow::Crow<> >::do_read()::'lambda'(boost::system::error_code const&, unsigned long), boost::system::error_code, unsigned long>::operator()() + 35
      frame #18: 0x000000010032f115 xmrblocksvoid boost::asio::asio_handler_invoke<boost::asio::detail::binder2<crow::Connection<crow::SocketAdaptor, crow::Crow<> >::do_read()::'lambda'(boost::system::error_code const&, unsigned long), boost::system::error_code, unsigned long> >(boost::asio::detail::binder2<crow::Connection<crow::SocketAdaptor, crow::Crow<> >::do_read()::'lambda'(boost::system::error_code const&, unsigned long), boost::system::error_code, unsigned long>&, ...) + 21 frame #19: 0x000000010032f067 xmrblocksvoid boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<crow::Connection<crow::SocketAdaptor, crow::Crow<> >::do_read()::'lambda'(boost::system::error_code const&, unsigned long), boost::system::error_code, unsigned long>, crow::Connection<crow::SocketAdaptor, crow::Crow<> >::do_read()::'lambda'(boost::system::error_code const&, unsigned long)>(boost::asio::detail::binder2<crow::Connection<crow::SocketAdaptor, crow::Crow<> >::do_read()::'lambda'(boost::system::error_code const&, unsigned long), boost::system::error_code, unsigned long>&, crow::Connection<crow::SocketAdaptor, crow::Crow<> >::do_read()::'lambda'(boost::system::error_code const&, unsigned long)&) + 39
      frame #20: 0x000000010032ef34 xmrblocksboost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, crow::Connection<crow::SocketAdaptor, crow::Crow<> >::do_read()::'lambda'(boost::system::error_code const&, unsigned long)>::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) + 196 frame #21: 0x00000001002d0dd7 xmrblocksboost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service&, boost::system::error_code const&, unsigned long) + 71
      frame #22: 0x00000001002d0334 xmrblocksboost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) + 500 frame #23: 0x00000001002cff74 xmrblocksboost::asio::detail::task_io_service::run(boost::system::error_code&) + 372
      frame #24: 0x00000001002c28f1 xmrblocksboost::asio::io_service::run() + 49 frame #25: 0x000000010032677c xmrblockscrow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::'lambda'()::operator()() const + 1452
      frame #26: 0x00000001003261bd xmrblocksvoid std::__1::__async_func<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::'lambda'()>::__execute<>(std::__1::__tuple_indices<>) + 61 frame #27: 0x0000000100326175 xmrblocksstd::__1::__async_func<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::'lambda'()>::operator()() + 21
      frame #28: 0x00000001003260c5 xmrblocksstd::__1::__async_assoc_state<void, std::__1::__async_func<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::'lambda'()> >::__execute() + 37 frame #29: 0x000000010032a62f xmrblocksvoid* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_deletestd::__1::__thread_struct >, void (std::__1::__async_assoc_state<void, std::__1::__async_func<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::'lambda'()> >::)(), std::__1::__async_assoc_state<void, std::__1::__async_func<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::'lambda'()> >> >(void*) + 687
      frame #30: 0x00007fff7ef786c1 libsystem_pthread.dylib_pthread_body + 340 frame #31: 0x00007fff7ef7856d libsystem_pthread.dylib_pthread_start + 377
      frame #32: 0x00007fff7ef77c5d libsystem_pthread.dylib`thread_start + 13

(lldb) register read
General Purpose Registers:
rax = 0x0000000000000000
rbx = 0x0000001062945000
rcx = 0x0000000000000000
rdx = 0x0000000000000000
rdi = 0x0000000000000000
rsi = 0x00000010a68c7f68
rbp = 0x00000010629415b0
rsp = 0x00000010629415b0
r8 = 0x0000000000000002
r9 = 0x000000010074379f "value"
r10 = 0x0000000000000000
r11 = 0x0000000f621fdea2
r12 = 0x000000010032a380 xmrblocksvoid* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (std::__1::__async_assoc_state<void, std::__1::__async_func<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::'lambda'()> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::'lambda'()> >*> >(void*) r13 = 0x0000000000000000 r14 = 0x0000001062945000 r15 = 0x0000000000000000 rip = 0x00007fff7ed3d432 libsystem_c.dylibstrlen + 18
rflags = 0x0000000000010246
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000

[Feature] Allow forward-navigation of outputs

It would be very useful to be able to look at transactions and see when and where the tx output is used. Right now they can only trace backwards, seeing where an input came from. Going forwards would let people see how often they get used in transactions and give people a more tangible sense of Monero's privacy.

Feature request - look up by date

Can you pretty please add a feature to look up a block by the timestamp?

Timestamp [UCT]: 2016-11-13 08:51:43

I dunno which format would be best, but the data seems to be in there.

Setting up ssl

Do you know how to set up ssl for crow? I can't find any documentation. I will be using lets encrypt, of course.

Unable to see transaction details in the tx pusher

I tried to use the tx pusher hosted by moneroworld.com, but couldn't get expected results. Am I doing anything wrong?

My test transaction looks like this:

[wallet 4AkvYS]: sign_transfer
Loaded 1 transactions, for 3.007000000000, fee 0.002000000000, sending 1.200000000000 to 44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A, 1.805000000000 change to 4AkvYSn5eRmVpN5xasoymZGP5mSDzaEAjMeTnBj97gde7mzot4Qd8E9L33ZzRAW2TcAv3gtvfXCQz8Tu4qr6TnMLUcZVkGi, with min mixin 4. 58 outputs to import. Is this okay? (Y/Yes/N/No): y

And here's the base64 encoding of unsigned_monero_tx:

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

The pusher's response message says:

Attempt failed

The data does not appear to be signed raw tx!

Here's the base64 encoding of signed_monero_tx:

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

And the pusher's response:

Attempt failed

Pushing disabled! Run explorer with --enable-pusher flag to enable it.

Thank you very much @Gingeropolous for hosting the service, by the way!

Integrate Monero as Submodule similar to Monero-Core

It would be great for higher-level language developers (like me) who aren't as familiar with C++ to be able to build the blockchain explorer with a one-time script.

Could something similar to the build.sh that Monero-Core has be implemented? This appears to rely on having Monero as a submodule, which I think would be beneficial even without the build script.

Eager to hear your thoughts on this.

Compilation problem with epee after recent Monero PRs

/home/mwo/onion-monero-blockchain-explorer/src/rpccalls.h:67:22: error: ‘invoke_http_json_remote_command2’ is not a member of ‘epee::net_utils’
             bool r = epee::net_utils::invoke_http_json_remote_command2(
                      ^~~~
/home/mwo/onion-monero-blockchain-explorer/src/rpccalls.h: In member function ‘bool xmreg::rpccalls::get_mempool(std::vector<cryptonote::tx_info>&)’:
/home/mwo/onion-monero-blockchain-explorer/src/rpccalls.h:93:22: error: ‘invoke_http_json_remote_command2’ is not a member of ‘epee::net_utils’
             bool r = epee::net_utils::invoke_http_json_remote_command2(
                      ^~~~
/home/mwo/onion-monero-blockchain-explorer/src/rpccalls.h: In member function ‘bool xmreg::rpccalls::commit_tx(tools::wallet2::pending_tx&, std::__cxx11::string&)’:
/home/mwo/onion-monero-blockchain-explorer/src/rpccalls.h:125:22: error: ‘invoke_http_json_remote_command2’ is not a member of ‘epee::net_utils’
             bool r = epee::net_utils::invoke_http_json_remote_command2(deamon_url
                      ^~~~
make[2]: *** [src/CMakeFiles/myxrm.dir/build.make:135: src/CMakeFiles/myxrm.dir/rpccalls.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:255: src/CMakeFiles/myxrm.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

Full page not delivered on i2p

I don't know if its crow, the explorer code, or the i2p functions that are making this weird. But basically, if you visit monerotools.i2p , sometimes the page isn't rendered, and its because the html it receives is partial (usually the footer is missing).

Perhaps there's a way to make crow pause before it finally servers up the page? Or to check that the footer is attached to the final product?

transaction not being displayed

A super ring size transaction shows up on moneroblocks but not xmrchain: https://xmrchain.net/search?value=1292610 , http://moneroblocks.info/search/1c51a4a70873fae13695fd9a0fd7127a3e9b5b9c771def7c3740b23a7ec4ccb5

And I get this from the output of xmrblocks (hard to tell if its exactly this because servers getting requests from others)

Apr 20 12:13:17 iof1006e clearnet_exp.sh[25793]: 2017-04-20 12:13:17.237 7f63bc651700 WARN blockchain.db.lmdb src/blockchain_db/lmdb/db_lmdb.cpp:71 Attempt to get block from height 1292619 failed -- block not in db
Apr 20 12:13:17 iof1006e clearnet_exp.sh[25793]: xmreg::timestamp_to_str: Unable to get Timezone database version from /home/monerosupport/Downloads/tzdata/
Apr 20 12:13:17 iof1006e clearnet_exp.sh[25793]: Seems cant convert to UTC timezone using date library. So just use local timezone.
Apr 20 12:13:17 iof1006e clearnet_exp.sh[25793]: Block of height 1292619 not found in the blockchain!Attempt to get block from height 1292619 failed -- block not in db
Apr 20 12:13:17 iof1006e clearnet_exp.sh[25793]: Cant get block: 1292619

Is my DB corrupt?

Can't get tx in mempool

whenever I tried to view a tx that is in mempool. I will always get this error message

Cant get tx: fe559b0872c1bd679a3bb1c9de4393fa6a6269e9bdc04f19de2ecac05dfb5e68

In console

tx with hash fe559b0872c1bd679a3bb1c9de4393fa6a6269e9bdc04f19de2ecac05dfb5e68 not found in db
Cant get tx in blockchain: .
Check mempool now
(2016-07-27 01:03:21) [INFO ] Response: 0x7f7850005d00 /tx/fe559b0872c1bd679a3bb1c9de4393fa6a6269e9bdc04f19de2ecac05dfb5e68 200 0

Any idea?

Show privacy-relevant recent transaction stats

It would be really swell if we could quickly see a summary of privacy relevant stats: ringsize, payment ID presence, fee (as the multiplier). Ideally this would show the top 10 combinations. It doesn't help to know ringsize 41 is popular, if the fees are a strange value only used by one type of wallet. And maybe it should throw out uncommon in/out values. For instance the group doing a bunch of 38/38 transactions. It does not matter if they started to use ringsize 9, an outsider will never fit in with those transactions.

Using the last 2-3 days of transactions is enough. Although maybe it should separate by time of day eventually if it results that certain attributes are more common at specific times. For instance a group using a certain config might only be online during the UK daytime.

The end goal is to allow people to stay more private by sticking with a couple of the most common publicly-visible attributes, yet be able to take advantage of larger ringsize when feasible.

"link to this page" generates broken link with localhost:8888 as hostname

When proving a transaction (https://xmrchain.net/prove) or decoding (https://xmrchain.net/myoutputs/) there is a link at the bottom:

"link to this page"

This generates the appropriate URL, with one exception: it uses localhost:8888 instead of the TLD https://xmrchain.net causing the link to be broken. Seem like it would be an easy fix. The link works if you put in the https://xmrchain.net instead of localhost:8888. Thanks.

Decode extra as asci

This tx has text in extra: https://testnet.xmrchain.com/tx/6ea88f70d06fbdfca83c74f9b85f478ab0f1e79f70f6de8225db700e0af39d40

The Extra field is: 01ae8ef40638c92d6df95a26acd06a900f7be5f379f550835aed10056a66b9caf302210054686973207478207761732067656e65726174656420627920436f696e6f6d69
Use a hex to ascii decoder:
®�ô8É-mùZ&¬Ðj�{åóyõP�Zíjf¹Êó!This tx was generated by Coinomi

https://www.reddit.com/r/Monero/comments/7068ng/just_saw_that_tweet_from_coinomi_not_sure_what_it/

So showing extra as ascii could be useful.

This is done by encoding ascii text to hex as payment id.

new mods break things

(2016-11-24 03:23:38) [INFO ] Request: 100.43.90.11:51051 0x7fb65c0047e0 HTTP/1.1 GET /block/557794
2016-Nov-23 22:23:40.166357 Exception: std::runtime_error
2016-Nov-23 22:23:40.166397 Unwinded call stack:
2016-Nov-23 22:23:40.167219 1 0xc18850 __cxa_throw + 0x70
2016-Nov-23 22:23:40.167848 2 0xc9bb52 date::init_tzdb() + 0x19c
2016-Nov-23 22:23:40.168522 3 0xc9c5d7 date::get_tzdb() + 0x51
2016-Nov-23 22:23:40.169174 4 0xc72d2a std::chrono::time_point<date::utc_clock, std::common_type<std::chrono::duration<long, std::ratio<1l, 1000000000l> >, std::chrono::duration<long, std::ratio<1l, 1l> > >::type> date::to_utc_time<std::chrono::duration<long, std::ratio<1l, 1000000000l> > >(std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > > const&) + 0x27
2016-Nov-23 22:23:40.169828 5 0xc6d06f xmreg::timestamp_to_str[abi:cxx11](long, char const*) + 0x4f
2016-Nov-23 22:23:40.170518 6 0xa4189f xmreg::page::show_block[abi:cxx11](unsigned long) + 0x4e5

2016-Nov-23 22:23:40.171316 7 0xa04403 main::{lambda(crow::request const&, unsigned long)#3}::operator()(crow::request co
nst&, unsigned long) const + 0x41
2016-Nov-23 22:23:40.172270 8 0xa073d2 std::enable_if<(!crow::black_magic::CallHelper<main::{lambda(crow::request const&,
unsigned long)#3}, std::enable_if::S >::value)&&crow::black_magic<crow::black_magic::CallHelper, main::{lambda(crow::request co
nst&, unsigned long)#3}<crow::request, unsigned long> >::value, void>::type crow::TaggedRule::operator()<main::{lambda(crow::req
uest const&, unsigned long)#3}>(crow::black_magic::CallHelper&&)::{lambda(crow::request const&, crow::response&, unsigned long)#1}::operator()(
crow::request const&, crow::response, unsigned long) const + 0x5a
2016-Nov-23 22:23:40.172965 9 0xa09907 std::_Function_handler<void (crow::request const&, crow::response&, unsigned long)
, std::enable_if<(!crow::black_magic::CallHelper<main::{lambda(crow::request const&, unsigned long)#3}, std::enable_if::S >::val
ue)&&crow::black_magic<crow::black_magic::CallHelper, main::{lambda(crow::request const&, unsigned long)#3}<crow::request, unsigned long> >::va
lue, void>::type crow::TaggedRule::operator()<main::{lambda(crow::request const&, unsigned long)#3}>(crow::black_magic::CallHelp
er&&)::{lambda(crow::request const&, crow::response&, unsigned long)#1}>::_M_invoke(std::_Any_data const&, crow::request const&, crow::response
&, unsigned long&&) + 0x67
2016-Nov-23 22:23:40.173585 10 0xb94c9c std::function<void (crow::request const&, crow::response&, unsigned long)>::operat
or()(crow::request const&, crow::response&, unsigned long) const + 0x76
2016-Nov-23 22:23:40.174239 11 0xb9498c crow::detail::routing_handler_call_helper::call<crow::detail::routing_handler_call
_helper::call_params<std::function<void (crow::request const&, crow::response&, unsigned long)> >, 0, 1, 0, 0, crow::black_magic::S<>, crow::bl
ack_magic::S<crow::detail::routing_handler_call_helper::call_pair<unsigned long, 0> > >::operator()(crow::detail::routing_handler_call_helper::
call_params<std::function<void (crow::request const&, crow::response&, unsigned long)> >) + 0x34
2016-Nov-23 22:23:40.174944 12 0xb94519 crow::detail::routing_handler_call_helper::call<crow::detail::routing_handler_call
_helper::call_params<std::function<void (crow::request const&, crow::response&, unsigned long)> >, 0, 0, 0, 0, crow::black_magic::S, crow::black_magic::S<> >::operator()(crow::detail::routing_handler_call_helper::call_params<std::function<void (crow::request const&, crow
::response&, unsigned long)> >) + 0x33
2016-Nov-23 22:23:40.175570 13 0xb93203 crow::TaggedRule::handle(crow::request const&, crow::response&, cro
w::routing_params const&) + 0x63
2016-Nov-23 22:23:40.176239 14 0xa1fe1b crow::Router::handle(crow::request const&, crow::response&) + 0x9bb
2016-Nov-23 22:23:40.177228 15 0xb29cb5 crow::Crow<>::handle(crow::request const&, crow::response&) + 0x2f
2016-Nov-23 22:23:40.177966 16 0xb1ae58 crow::Connection<crow::SocketAdaptor, crow::Crow<>>::handle() + 0x8d6
2016-Nov-23 22:23:40.178662 17 0xb0d1ed crow::HTTPParser<crow::Connection<crow::SocketAdaptor, crow::Crow<>> >::process_me
ssage() + 0x1f
2016-Nov-23 22:23:40.179354 18 0xaff328 crow::HTTPParser<crow::Connection<crow::SocketAdaptor, crow::Crow<>> >::on_message
_complete(http_parser*) + 0xf1
2016-Nov-23 22:23:40.184224 19 0xa235d8 http_parser_execute + 0x2e2b
2016-Nov-23 22:23:40.184942 20 0xaebd1a crow::HTTPParser<crow::Connection<crow::SocketAdaptor, crow::Crow<>> >::feed(char
const*, int) + 0x2e
2016-Nov-23 22:23:40.185567 21 0xad9c47 crow::Connection<crow::SocketAdaptor, crow::Crow<>>::do_read()::{lambda(boost::sys
tem::error_code const&, unsigned long)#1}::operator()(boost::system::error_code const&, unsigned long) const + 0x8d
2016-Nov-23 22:23:40.186265 22 0xb41250 boost::asio::detail::binder2<crow::Connection<crow::SocketAdaptor, crow::Crow<>>::
do_read()::{lambda(boost::system::error_code const&, unsigned long)#1}, boost::system::error_code, unsigned long>::operator()() + 0x2e
2016-Nov-23 22:23:40.186938 23 0xb3af6f void boost::asio::asio_handler_invoke<boost::asio::detail::binder2<crow::Connectio
n<crow::SocketAdaptor, crow::Crow<>>::do_read()::{lambda(boost::system::error_code const&, unsigned long)#1}, boost::system::error_code, unsign
ed long> >(boost::asio::detail::binder2<crow::Connection<crow::SocketAdaptor, crow::Crow<>>::do_read()::{lambda(boost::system::error_code const
&, unsigned long)#1}, boost::system::error_code, unsigned long>&, ...) + 0x68

2016-Nov-23 22:23:40.188264 25 0xb29e17 boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, crow:
:Connection<crow::SocketAdaptor, crow::Crow<>>::do_read()::{lambda(boost::system::error_code const&, unsigned long)#1}>::do_complete(boost::asi
o::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) + 0xc8
2016-Nov-23 22:23:40.188925 26 0xa125b0 boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task
_io_service&, boost::system::error_code const&, unsigned long) + 0x32
2016-Nov-23 22:23:40.189522 27 0xa14a21 boost::asio::detail::epoll_reactor::descriptor_state::do_complete(boost::asio::det
ail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) + 0x63
2016-Nov-23 22:23:40.190197 28 0xa125b0 boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task
_io_service&, boost::system::error_code const&, unsigned long) + 0x32
2016-Nov-23 22:23:40.190825 29 0xa15877 boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<
boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) + 0x1b7
2016-Nov-23 22:23:40.191447 30 0xa1506d boost::asio::detail::task_io_service::run(boost::system::error_code&) + 0xf1
2016-Nov-23 22:23:40.192094 31 0xa15b8e boost::asio::io_service::run() + 0x3e
2016-Nov-23 22:23:40.192711 32 0xa94bf2 crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1}::operator()()
const + 0x272
2016-Nov-23 22:23:40.193473 33 0xb5d264 void std::_Bind_simple<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{la
mbda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) + 0x28
2016-Nov-23 22:23:40.194235 34 0xb57202 std::_Bind_simple<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda(
)#1} ()>::operator()() + 0x2c
2016-Nov-23 22:23:40.194928 35 0xb5070c std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result
, std::__future_base::_Result_base::_Deleter>, std::_Bind_simple<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} ()>, void

::operator()() const + 0x30
2016-Nov-23 22:23:40.195605 36 0xb4bfb1 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__fu
ture_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result, std::__future_base::
_Result_base::_Deleter>, std::_Bind_simple<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} ()>, void> >::_M_invoke(std::_A
ny_data const&) + 0x3d
2016-Nov-23 22:23:40.196292 37 0xa5c5d2 std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base
::_Result_base::_Deleter> ()>::operator()() const + 0x4c
2016-Nov-23 22:23:40.197000 38 0xa0ddf8 std::__future_base::State_baseV2::M_do_set(std::function<std::unique_ptr<std::
future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) + 0x36
2016-Nov-23 22:23:40.197719 39 0xac775a void std::_Mem_fn_base<void (std::__future_base::_State_baseV2::)(std::function<s
td::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>
, bool*), true>::operator()<std::function<std:
:unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool, void>(std::__future_base::_State_baseV2*
, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>&&, bool&&) const + 0x94
2016-Nov-23 22:23:40.198501 40 0xab32cd void std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::)(st
d::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>
, bool*)> (std::__future_base::_S
tate_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool)>::_M_inv
oke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) + 0x7b
2016-Nov-23 22:23:40.199183 41 0xa95920 std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::)(std::fu
nction<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>
, bool*)> (std::__future_base::State
baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool)>::operator()(
) + 0x2c

2016-Nov-23 22:23:40.199935 42 0xa76333 void std::__once_call_impl<std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool)> >() + 0x17
2016-Nov-23 22:23:40.200365 43 0x7fb9f1668ae9 __pthread_once_slow + 0xa9
2016-Nov-23 22:23:40.201040 44 0xa0383d __gthread_once(int*, void ()()) + 0x31
2016-Nov-23 22:23:40.201693 45 0xa5c45c void std::call_once<void (std::__future_base::_State_baseV2::
)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool>(std::once_flag&, void (std::__future_base::_State_baseV2::&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>&&, bool&&) + 0xc1
2016-Nov-23 22:23:40.202330 46 0xa0db76 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) + 0xa0
2016-Nov-23 22:23:40.203005 47 0xb4030c std::__future_base::_Async_state_impl<std::_Bind_simple<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} ()>, void>::_Async_state_impl(crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} (&&)())::{lambda()#1}::operator()() const + 0x72
2016-Nov-23 22:23:40.203616 48 0xb9476e void std::_Bind_simple<std::__future_base::_Async_state_impl<std::_Bind_simple<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} ()>, void>::_Async_state_impl(crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} (&&)())::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) + 0x28
2016-Nov-23 22:23:40.204729 49 0xb937aa std::_Bind_simple<std::__future_base::_Async_state_impl<std::_Bind_simple<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} ()>, void>::_Async_state_impl(crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} (&&)())::{lambda()#1} ()>::operator()() + 0x2c
2016-Nov-23 22:23:40.205423 50 0xb90e34 std::thread::_Impl<std::_Bind_simple<std::__future_base::_Async_state_impl<std::_Bind_simple<crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} ()>, void>::_Async_state_impl(crow::Server<crow::Crow<>, crow::SocketAdaptor>::run()::{lambda()#1} (&&)())::{lambda()#1} ()> >::_M_run() + 0x1c
2016-Nov-23 22:23:40.205911 51 0x7fb9f0f06c80 std::this_thread::__sleep_for(std::chrono::duration<long, std::ratio<1l, 1l> >, std::chrono::duration<long, std::ratio<1l, 1000000000l> >) + 0x70
2016-Nov-23 22:23:40.206338 52 0x7fb9f166170a start_thread + 0xca
2016-Nov-23 22:23:40.206740 53 0x7fb9f088282d clone + 0x6d
2016-Nov-23 22:23:40.207144 54 0x0

(2016-11-24 03:23:40) [ERROR ] An uncaught exception occurred: Timezone database version "2016j" did not install correctly to "/home/monero/Downloads/tzdata"

Error building on Arch. easylogging++.h: no such file or directory

Scanning dependencies of target myxrm
[ 5%] Building CXX object src/CMakeFiles/myxrm.dir/MicroCore.cpp.o
In file included from /home/user/onion-monero-blockchain-explorer/src/MicroCore.h:10:0,
from /home/user/onion-monero-blockchain-explorer/src/MicroCore.cpp:5:
/home/user/onion-monero-blockchain-explorer/src/monero_headers.h:34:27: fatal error: easylogging++.h: No such file or directory
#include "easylogging++.h"

A bug in decoding inputs?

I like the new feature of decoding the inputs. While testing it, I'm confused at interpreting the result. Here's an example where

  • tx hash: bfb5bd5553dbdcbe9be81703456497aebc7a6af2fd54bbf1a0012b50ed2bb373
  • address: 9svHk1wHPo3ULf2AZykghzcye6sitaRE4MaDjPC6uanTHCynHjJHZaiAb922PojE1GexhhRt1LVf5DC43feyrRZMLXQr3mk
  • viewkey: 339673bb1187e2f73ba7841ab6841c5553f96e9f13f8fe6612e69318db4e9d0a

screen shot 2017-01-20 at 11 13 49 am

screen shot 2017-01-20 at 11 14 13 am

Why do I see only two keys under the "output public key" list in each decoded input? Also, the second output key in the first input 57dbf8a7bd816b50daeea054bbed8be39e69cd84db13da9be272f0ba71a945f8 was not in the input ring. Is this due to a bug?

can't compile on ubuntu 16

monero head compiles fine.

dunno why this is borkin

[ 94%] Building CXX object CMakeFiles/xmrblocks.dir/main.cpp.o
In file included from /home/user/onion-monero-blockchain-explorer/main.cpp:7:0:
/home/user/onion-monero-blockchain-explorer/src/page.h: In member function ‘std::__cxx11::string xmreg::page::show_checkcheckrawoutput(std::__cxx11::string, std::__cxx11::string)’:
/home/user/onion-monero-blockchain-explorer/src/page.h:2696:13: error: ‘portable_binary_iarchive’ is not a member of ‘boost::archive’
boost::archive::portable_binary_iarchive ar(iss);
^
/home/user/onion-monero-blockchain-explorer/src/page.h:2698:13: error: ‘ar’ was not declared in this scope
ar >> outputs;
^
CMakeFiles/xmrblocks.dir/build.make:62: recipe for target 'CMakeFiles/xmrblocks.dir/main.cpp.o' failed
make[2]: *** [CMakeFiles/xmrblocks.dir/main.cpp.o] Error 1
CMakeFiles/Makefile2:69: recipe for target 'CMakeFiles/xmrblocks.dir/all' failed
make[1]: *** [CMakeFiles/xmrblocks.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
user@z170e4:~/onion-monero-blockchain-explorer$

Error on make: fatal error: release/version/version.h: No such file or directory

With specifying the monero directory like the build states or without, this error happens:
root@grin:~/onion-monero-blockchain-explorer/build# make

[  5%] Building CXX object src/CMakeFiles/myxrm.dir/MicroCore.cpp.o
In file included from /root/onion-monero-blockchain-explorer/src/MicroCore.h:10:0,
                 from /root/onion-monero-blockchain-explorer/src/MicroCore.cpp:5:
/root/onion-monero-blockchain-explorer/src/monero_headers.h:19:37: fatal error: release/version/version.h: No such file or directory
compilation terminated.
src/CMakeFiles/myxrm.dir/build.make:62: recipe for target 'src/CMakeFiles/myxrm.dir/MicroCore.cpp.o' failed
make[2]: *** [src/CMakeFiles/myxrm.dir/MicroCore.cpp.o] Error 1
CMakeFiles/Makefile2:254: recipe for target 'src/CMakeFiles/myxrm.dir/all' failed
make[1]: *** [src/CMakeFiles/myxrm.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

CSS Updates

Would there be any interest in me spending some time improving the css?

I know not having JS is must, but there are still plenty of frameworks out there that support pure css.

Here's what I came up with after just an hour or so of playing around:

xmrchain net explore moneroworld com

Do you agree this is better? It's only a handful of lines changed outside of bringing in a single, minified css file (9kb) https://milligram.github.io/. Obviously there is a lot of room for improvement, but my goal here is to make helpful style updates with as little code changes as possible.

If this sounds good, I can have a PR up shortly.

Got further, but still can't compile

[100%] Building CXX object CMakeFiles/xmrblocks.dir/main.cpp.o
Linking CXX executable xmrblocks
/usr/bin/ld: _ZN5boost4asio6detail15keyword_tss_ptrINS1_10call_stackINS1_15task_io_serviceENS1_27task_io_service_thread_infoEE7contextEE6value_E: TLS definition in CMakeFiles/xmrblocks.dir/main.cpp.o section .tbss._ZN5boost4asio6detail15keyword_tss_ptrINS1_10call_stackINS1_15task_io_serviceENS1_27task_io_service_thread_infoEE7contextEE6value_E[_ZN5boost4asio6detail15keyword_tss_ptrINS1_10call_stackINS1_15task_io_serviceENS1_27task_io_service_thread_infoEE7contextEE6value_E] mismatches non-TLS definition in blockchain.cpp.o (symbol from plugin) section .gnu.linkonce.t._ZN5boost4asio6detail15keyword_tss_ptrINS1_10call_stackINS1_15task_io_serviceENS1_27task_io_service_thread_infoEE7contextEE6value_E
/opt/bitmonero-dev/libs/libcryptonote_core.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make[2]: *** [xmrblocks] Error 1
make[1]: *** [CMakeFiles/xmrblocks.dir/all] Error 2
make: *** [all] Error 2
bob@monkey-desktop:~/onion-monero-blockchain-explorer$

Any suggestions?

block height and key_offsets

hi,
Im programming my own explorer just for fun to understand monero and I had looked up much in your explorer and in www.moneroblocks.info .
it seems like your explorer has a small indication error: if you click on a transaction from e.g. block #x, then this transaction says that it's in block #(x-1).
and I had issues with key_offsets, your explorer shows other inputs than moneroblocks.info in every transaction. so I think that one of you two are doing a wrong indexing. but I dont know how to verify key_offsets, so I cannot say you who is wrong. if you know and like to help me, I would love to hear how I can check them.
I dont have a github account (Im not a real programmer, just sometimes for fun) so thats why I write you here. I hope this is okay.

by /u/-yara

Error: recipe for target 'xmrblocks' failed on Ubuntu 16.04

Getting on make:

~/onion-monero-blockchain-explorer/build# make
[ 35%] Built target myxrm
[ 50%] Built target myext
[ 90%] Built target mstch
[ 95%] Linking CXX executable xmrblocks
/usr/bin/ld: cannot find -lcurl
/usr/bin/ld: cannot find -lunwind
collect2: error: ld returned 1 exit status
CMakeFiles/xmrblocks.dir/build.make:130: recipe for target 'xmrblocks' failed
make[2]: *** [xmrblocks] Error 1
CMakeFiles/Makefile2:69: recipe for target 'CMakeFiles/xmrblocks.dir/all' failed
make[1]: *** [CMakeFiles/xmrblocks.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

Weird timestamps

https://xmrchain.net/ has weird timestamps, older blocks have smaller time differences than new blocks. i don't know if this is the same time stamping weirdness that we've always seen or if its unique to the explorer.

File not found src/monero_headers.h

I'm have problem on make:
all files, included in src/monero_headers.h not found. Folders like cryptonote_core/ or blockchain_db/ not exist too.
What it is files and how create\where download it? Thanks.

Example error
/home/user/onion-monero-blockchain-explorer/src/monero_headers.h:19:37: fatal error: release/version/version.h: File not found

Warning / Error on starting

When I run./xmrblocks

I get this error

2017-07-18 02:36:44.741 7f2acbeb2780 INFO global contrib/epee/src/mlog.cpp:145 New log categories: *:WARNING,net:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO
but the service loads on 8081

Same case when I run monerod --detach, I get this error

2017-07-18 02:38:30.704	    7fcdc60d9740	INFO 	global	contrib/epee/src/mlog.cpp:145	New log categories: *:WARNING,net:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO
2017-07-18 02:38:30.704	    7fcdc60d9740	INFO 	global	src/daemon/main.cpp:282	Monero 'Wolfram Warptangent' (v0.10.3.1-release)
Forking to background...

monero version shown is compiled version, not running deamon version

Monero version shown on explore is version of monero against which the explorer was compiled. Thus, later if updated monero, but not recompile explorer, the version will be wrong.

Proposed solution: get current version using rpc call to deamon. compiled version can still stay.

Latest code for dvwae436pd7nt4bc.onion ?

I am seeing mismatches between the code here and that being served from dvwae436pd7nt4bc.onion -- should they match?

As a simple sanity check, I compared the HTML titles:

  • header.html#L9 :
    <title>Onion Monero Blockchain Explorer</title>
  • dvwae436pd7nt4bc.onion :
    <title>Monero Explorer</title>

make fail

so, im on ubuntu 14.04 , I can compile monero, but managed to update gcc to 6, but still get an error

bob@monkey-desktop:/onion-monero-blockchain-explorer$ make
Scanning dependencies of target mstch
[ 6%] Building CXX object ext/mstch/src/CMakeFiles/mstch.dir/state/in_section.cpp.o
[ 12%] Building CXX object ext/mstch/src/CMakeFiles/mstch.dir/state/outside_section.cpp.o
[ 18%] Building CXX object ext/mstch/src/CMakeFiles/mstch.dir/mstch.cpp.o
[ 25%] Building CXX object ext/mstch/src/CMakeFiles/mstch.dir/render_context.cpp.o
[ 31%] Building CXX object ext/mstch/src/CMakeFiles/mstch.dir/template_type.cpp.o
[ 37%] Building CXX object ext/mstch/src/CMakeFiles/mstch.dir/token.cpp.o
[ 43%] Building CXX object ext/mstch/src/CMakeFiles/mstch.dir/utils.cpp.o
Linking CXX static library libmstch.a
[ 43%] Built target mstch
[ 50%] Building CXX object ext/CMakeFiles/myext.dir/format.cc.o
[ 56%] Building CXX object ext/CMakeFiles/myext.dir/dateparser.cpp.o
Linking CXX static library libmyext.a
[ 56%] Built target myext
[ 62%] Building CXX object src/CMakeFiles/myxrm.dir/MicroCore.cpp.o
In file included from /home/bob/onion-monero-blockchain-explorer/src/MicroCore.h:10:0,
from /home/bob/onion-monero-blockchain-explorer/src/MicroCore.cpp:5:
/home/bob/onion-monero-blockchain-explorer/src/monero_headers.h:12:27: fatal error: net/http_base.h: No such file or directory
#include "net/http_base.h"
^
compilation terminated.
make[2]: *** [src/CMakeFiles/myxrm.dir/MicroCore.cpp.o] Error 1
make[1]: *** [src/CMakeFiles/myxrm.dir/all] Error 2
make: *** [all] Error 2
bob@monkey-desktop:
/onion-monero-blockchain-explorer$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 6.1.1-3ubuntu1114.04.1' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=gcc4-compatible --disable-libstdcxx-dual-abi --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.1.1 20160511 (Ubuntu 6.1.1-3ubuntu11
14.04.1)
bob@monkey-desktop:~/onion-monero-blockchain-explorer$

Error: cannot find -lcryptoxmr

Trying to compile explorer on Ubuntu 16.04.3 LTS, with Monero, origin/release-v0.11.0.0 branch, but got following error at 100%...

[ 78%] Building CXX object ext/mstch/src/CMakeFiles/mstch.dir/token.cpp.o
[ 84%] Building CXX object ext/mstch/src/CMakeFiles/mstch.dir/utils.cpp.o
[ 89%] Linking CXX static library libmstch.a
[ 89%] Built target mstch
Scanning dependencies of target xmrblocks
[ 94%] Building CXX object CMakeFiles/xmrblocks.dir/main.cpp.o
[100%] Linking CXX executable xmrblocks
/usr/bin/ld: cannot find -lcryptoxmr
collect2: error: ld returned 1 exit status
CMakeFiles/xmrblocks.dir/build.make:127: recipe for target 'xmrblocks' failed
make[2]: *** [xmrblocks] Error 1
CMakeFiles/Makefile2:69: recipe for target 'CMakeFiles/xmrblocks.dir/all' failed
make[1]: *** [CMakeFiles/xmrblocks.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

mdb_env_open: Too many open files

xmrblocks kill itself. This happen everyday, any clue?

I am on Ubuntu 16.04

(2017-02-27 22:30:57) [INFO ] Response: 0x7ef82050dc40 / 200 0
(2017-02-27 22:31:22) [INFO ] Request: 127.0.0.1:38350 0x7ef820511840 HTTP/1.0 GET /tx/deb7a00f90c4c5e1c09ace7beda54be3f15d2f8139b9c2ac59ce580d467704a5
(2017-02-27 22:31:22) [INFO ] Response: 0x7ef820511840 /tx/deb7a00f90c4c5e1c09ace7beda54be3f15d2f8139b9c2ac59ce580d467704a5 200 0
(2017-02-27 22:34:53) [INFO ] Request: 127.0.0.1:38378 0x7ef820515440 HTTP/1.0 GET /tx/b90b7198d86cf321ce47fb0196e1a138b999bbe0786c98d219605aff28dafde0/1
mdb_env_open: Too many open files
(2017-02-27 22:34:53) [INFO ] Response: 0x7ef820515440 /tx/b90b7198d86cf321ce47fb0196e1a138b999bbe0786c98d219605aff28dafde0/1 200 0
Killed

(2017-02-28 22:44:16) [INFO ] Request: 127.0.0.1:56490 0x7fc62c510ec0 HTTP/1.0 GET /tx/d74f3367395934fc3c7ce1d7683631c1dcc8786069f065f40310ac14476cad07/1
(2017-02-28 22:44:16) [INFO ] Response: 0x7fc62c510ec0 /tx/d74f3367395934fc3c7ce1d7683631c1dcc8786069f065f40310ac14476cad07/1 200 0
(2017-02-28 22:45:16) [INFO ] Request: 127.0.0.1:56502 0x7fc62c514ac0 HTTP/1.0 GET /tx/4dbeb57856e3a61cf0684fe0f331ff03e97185aa617f95e52fd5c8ce93d1a671
mdb_env_open: Too many open files
mdb_env_open: Too many open files
mdb_env_open: Too many open files
mdb_env_open: Too many open files
(2017-02-28 22:45:16) [INFO ] Response: 0x7fc62c514ac0 /tx/4dbeb57856e3a61cf0684fe0f331ff03e97185aa617f95e52fd5c8ce93d1a671 200 0
Killed

JSON Web API

I'd like to create some some Web Apps based on the extremely performant and feature-rich back-end of this project. This will be much easier to do if there is a web-facing JSON API to interact with.

Ideally, the JSON API would expose the following endpoints (to start):

/api/v1/mempool
/api/v1/search?blkhash='blah'/?txhash/etc. Ideally all the supported search types of the main site.
/api/v1/transactions?page=1
/api/v1/transactions?page=2
/api/v1/tx/<tx_hash>

I'll work to develop the spec of the JSON response itself for each endpoint, but sane defaults will also be fine. Basically whatever is already being returned to the traditional back-end rendered template handlerbar/mustache engine would be great.

I'm not sure how much work this is, or how realistic it is to even ask for this, but I'm hoping that it can be fairly easily integrated given the existing architecture.

However, I also understand that this project has a focus on darknet support, which is not especially compatible with the type of service I am proposing. Perhaps a fork of this project is a better proposal?

Eager to hear your thoughts. This is probably an ambitious ask, so please let me know if I am overreaching.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.