Browse Source

more stuff

master
onryo 2 years ago
parent
commit
0bf4c9cce3
  1. 0
      var/www/explorer.hush.land/PID
  2. 9
      var/www/explorer.hush.land/bin/HOWTO
  3. 2
      var/www/explorer.hush.land/bin/Makefile
  4. 377
      var/www/explorer.hush.land/bin/backup/update_blocks_redis.pl
  5. 84
      var/www/explorer.hush.land/bin/balances.pl
  6. 57
      var/www/explorer.hush.land/bin/block-340k.json
  7. 337
      var/www/explorer.hush.land/bin/doesnotwork_update_addr.pl
  8. 102
      var/www/explorer.hush.land/bin/example.html
  9. 1
      var/www/explorer.hush.land/bin/nope/README
  10. 337
      var/www/explorer.hush.land/bin/nope/update_addresses.pl
  11. 7
      var/www/explorer.hush.land/bin/tmp.pl
  12. 74
      var/www/explorer.hush.land/bin/update.pl
  13. 375
      var/www/explorer.hush.land/bin/update_blocks.pl
  14. 408
      var/www/explorer.hush.land/bin/update_blocks_redis.pl
  15. 23
      var/www/explorer.hush.land/crons/README
  16. 13
      var/www/explorer.hush.land/update_api.sh
  17. 18
      var/www/explorer.hush.land/update_explorer_data.sh
  18. 12
      var/www/explorer.hush.land/var/www/explorer.hush.land/PID
  19. 84
      var/www/explorer.hush.land/var/www/explorer.hush.land/address/template.html
  20. 78
      var/www/explorer.hush.land/var/www/explorer.hush.land/addresses/template.html
  21. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/anonset.json
  22. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/coinsupply.json
  23. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/getblockchain.json
  24. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/getchaintips.json
  25. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/getchaintxstats.json
  26. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/getinfo.json
  27. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/getmininginfo.json
  28. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/gettxoutsetinfo.json
  29. 1
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/index.html
  30. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/snapshots/snapshot-old.json
  31. 0
      var/www/explorer.hush.land/var/www/explorer.hush.land/api/snapshots/snapshot.json
  32. 101
      var/www/explorer.hush.land/var/www/explorer.hush.land/block/template.html
  33. 77
      var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/template.html
  34. 125
      var/www/explorer.hush.land/var/www/explorer.hush.land/index-1.html
  35. 1
      var/www/explorer.hush.land/var/www/explorer.hush.land/index-new.html
  36. 142
      var/www/explorer.hush.land/var/www/explorer.hush.land/index-prev.html
  37. 125
      var/www/explorer.hush.land/var/www/explorer.hush.land/index.html
  38. 125
      var/www/explorer.hush.land/var/www/explorer.hush.land/template.html
  39. 85
      var/www/explorer.hush.land/var/www/explorer.hush.land/tx/template.html

0
var/www/explorer.hush.land/PID

9
var/www/explorer.hush.land/bin/HOWTO

@ -0,0 +1,9 @@
# Balances
Showing address balances is currently manual run once in a while, not via cron. It uses a lot of resources.
balances.pl generates addresses/index.html
# Makefile
run `make` to syntax check important files

2
var/www/explorer.hush.land/bin/Makefile

@ -0,0 +1,2 @@
check:
perl -wc update.pl && perl -wc update_blocks_redis.pl

377
var/www/explorer.hush.land/bin/backup/update_blocks_redis.pl

@ -0,0 +1,377 @@
#!/usr/bin/env perl
use strict;
use warnings;
use JSON::Any;
use Data::Dumper;
use Redis;
use 5.014;
my $STATS = {};
$|=1;
my $TX = {};
my $r = Redis->new;
my $j = JSON::Any->new;
#sleep 10;
# While Siona swims, we pave with bricks on the road she will run on...
my $dir = shift || '/var/www/explorer.hush.land/var/www/explorer.hush.land/api';
my $cli = "/home/hush/git/hush3/src/hush-cli";
my $getinfo = readfile("$dir/getinfo.json");
my $mining = readfile("$dir/getmininginfo.json");
my $template = readfile("/var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/template.html");
my $blocksdir = "/var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/";
if($getinfo =~ m/"blocks": (\d+)/){ $STATS->{BLOCKS} ||= $1; }
if($getinfo =~ m/"tls_connections": (\d+)/){ $STATS->{TLS_CONNECTIONS} ||= $1; }
if($getinfo =~ m/"connections": (\d+)/){ $STATS->{CONNECTIONS} ||= $1; }
if($getinfo =~ m/"protocolversion": (\d+)/){ $STATS->{PROTOCOLVERSION} ||= $1; }
my @symbols = qw/
TX_TABLE BLOCKS_TABLE TLS_CONNECTIONS CONNECTIONS PROTOCOLVERSION
/;
my @blocks = ();
my $height = $STATS->{BLOCKS} || 0;
$STATS->{BLOCKS_TABLE} = "";
$STATS->{TX_TABLE} = "";
my $mineraddress = "";
for my $h ($height-50 .. $height) {
#last if($h < 0);
my $thisminer = "";
# TODO: fix this garbage
my $reward = $h > 340000 ? "3.125 HUSH" : "12.5 HUSH";
my $block = get_block($h);
#die Dumper $block;
my $time = $block->{time};
die Dumper [ $block ] unless $block->{time} and $block->{tx};
my @txs = @{ $block->{tx} };
my $numtx = @txs;
# TODO: look on filesystem first? redis cache?
my $hash = qx!$cli getblockhash $h!;
chomp $hash;
my $root = "/var/www/explorer.hush.land";
my $blockdir = "$root/var/www/explorer.hush.land/block/$hash";
if (!-e "$root/block/$h") {
# make /block/HEIGHT work
my $cmd = "ln -s $blockdir $root/var/www/explorer.hush.land/block/$h";
qx{$cmd};
warn $cmd;
}
if (!-d $blockdir) {
# so explorer.hush.is/block/HASH works
my $cmd = "mkdir -p $blockdir";
qx{$cmd};
warn $cmd;
my $block_template_file = "/var/www/explorer.hush.land/var/www/explorer.hush.land/block/template.html";
my $new_block_file = "/var/www/explorer.hush.land/var/www/explorer.hush.land/block/$hash/index.html";
# TODO: process template with block details
my $block_template = readfile($block_template_file);
$block_template =~ s/#BLOCKS#/$h/g;
$block_template =~ s/#BLOCKHASH#/$hash/g;
$block_template =~ s/#PREVIOUSBLOCKHASH#/$block->{previousblockhash}/ge;
$block_template =~ s/#BLOCKTIME#/$time/g;
$block_template =~ s/#ANCHOR#/$block->{anchor}/ge;
$block_template =~ s/#VERSION#/$block->{version}/ge;
$block_template =~ s/#BITS#/$block->{bits}/ge;
$block_template =~ s/#BLOCKSIZE#/$block->{size}/ge;
$block_template =~ s/#CHAINWORK#/$block->{chainwork}/ge;
$block_template =~ s/#MERKLEROOT#/$block->{merkleroot}/ge;
$block_template =~ s/#FINALSAPLINGROOT#/$block->{finalsaplingroot}/ge;
# TODO
$block_template =~ s/#BLOCKREWARD#/3.125 HUSH/g;
$block_template =~ s/#BLOCKNONCE#/$block->{nonce}/ge;
$block_template =~ s/#DIFFICULTY#/$block->{difficulty}/ge;
$block_template =~ s/#NUM_TXS#/$numtx/g;
my $txtype = "";
# generate tx list table
$STATS->{TX_TABLE}=<<HTML;
HTML
my $txi = 0;
for my $tx (@txs) {
my $json = qx!$cli getrawtransaction $tx 1!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
# add tx json to Redis, indexed by txid
$r->set("tx:$tx", $json);
my $j = JSON::Any->new;
my $o;
eval {
$o = $j->decode($json);
};
next if $@;
$TX->{$tx} = $o;
my $tx_dir = "$root/var/www/explorer.hush.land/tx/$tx";
my $tx_file = "$root/var/www/explorer.hush.land/tx/$tx/index.html";
my $tx_template_file = "$root/var/www/explorer.hush.land/tx/template.html";
my $tx_template = readfile($tx_template_file);
my $txtime = localtime($o->{time});
#my $txsize = $o->{size} . " bytes";
$tx_template =~ s/#TXID#/$tx/ge;
$tx_template =~ s/#TXTIME#/$txtime/ge;
#$tx_template =~ s/#TXSIZE#/$txsize/g;
$tx_template =~ s/#BLOCKHEIGHT#/$h/ge;
$tx_template =~ s/#BLOCKHASH#/$hash/ge;
my ($vin,$vout,$zin,$zout) = ($o->{vin},$o->{vout},$o->{vShieldedSpend},$o->{vShieldedOutput});
my $expiryheight = $o->{expiryheight} == 0 ? "Default" : $o->{expiryheight};
my $locktime = localtime($o->{locktime});
my $valueBalance = $o->{valueBalance} || "?";
# "vShieldedOutput": [
# {
# "cv": "61e0fed3b97e08e442408c7efc4058a9116695e6e28a22c0fbf0987fdfbcdd27",
# "cmu": "25245041af3bbc5a03da1cd6d60665f7659cbb3bab1080a6e003f856d45998fc",
# "ephemeralKey": "bffefb4f55679610bbdbd43bfba64308842348ba70bb999fad00c67356eab998",
# "encCiphertext": "b685c9d4f6164102999e88e3e30fcca37d9c402fc72533185d495a9d64f1fca277ead03aefe960eeaf102c0c92686a75c792ae8662f40601287ff19635581279d9c9940ba3c29af36166620422c6
#49c4a7ca938734ceecb93a3abc8753ff3535950662ef46d8ed3a0608a61c65be5d0bdb1c262bd63fde759040eef74d4d81619ee154bbabe4fc0e27d82b19c6ed0d4cd806d5bc75ebbb13370ff3f19979ab3b74e859d9b88d3802
#bc7a2ce7ae4305c6beec2146b374bda7234395d0aa390337e69ef5d04eddef0087244292f358b46eeb3c2a5a6d3bd1c89aaa4ebfd8bab58d2d4771b1d106db1a5dcead3b09cfc9fc38b972ce98c53d3cd658b02e58b087c7c73e
#0bd7cb093f2b15ab397094be5bc98f5865045d1845e548249fc811545db1645beb2f044366ba9ae584074e6fa5c03d786757c88ed8eff2d81570d15e64f192707d7393ce40b0f2f767cfbeaa5f05a634fe527da982241c92c4c2
#9642f633115d34fe6791f00c8867e2242485de5f0bb87a8d4e6b375f557db6968f5ecc4f07b838b2dd85dd54e4e9ae2a28e9305bd1a6ae71adf75335d5f44cc046194fdbc91fb80202f06af9431716dc6627b2aa4723b0b8e4bb
#504649b6350ba9f020106d71248227ed8d7a10e2fbcbf64824c8923149822970b3c574614a8c32602106132c1209917974566b2990cf106666f985a2fa1f1409efdc457404700da210906b0f19be61c70d70eddc2f1cbffd94bb
#4c154a332fdd345ad06bd2ac86a339a93eae25db5eb3b4c6090d8483a8e5dd642231d17f3011b2f4b629ef72c08df1eeb6e7d06e",
# "outCiphertext": "53e3865f52101faf3218b60b7d58b9c426dc7c6cff009a8ceddd58031afe9802cae0f423a1085c2b36c776db29b57db8041e9bac42d6b445a0d69eb5a2f0ef61b4790595a68750c60889ff811dce
#8fbb",
# "proof": "82eda0f7de0936f6ca8208e63bda8db9970feb232ae64635e5bea67f16fdbe1b5e5e3a6bb7b7d2f0127c0d17de494834a82e899e8eecdfc71a59de8d1808a53df2989762bd54a855dadc535f2c5107d7b6da
#a732153c4dda4ac965be79ba2ecc030bd58e4c05d5ac7be283b3dc68af8a39231a31cccb54eae65c676760182bd22965f2e1c3685de44c0b93d84519bf138c7942222795dfdd0f683474b7c75221c9355109258805cc038ca43b
#26d5770bf25882326f4f508731b36a8632bc0012"
# }
# ],
my $vins = @$vin;
my $vouts = @$vout;
my $zins = @$zin;
my $zouts = @$zout;
my $coinbase = $vin->[0] ? $vin->[0]->{coinbase}." with sequence ".$vin->[0]->{sequence} : "False"; #($vin->[0] && $vin->[0]->{coinbase}) ? $vin->[0]{coinbase} . " with sequence " . $vin->{sequence} : "False";
# coinbase does not count as a transparent input
$vins-- if ($vin->[0] && $vin->[0]->{coinbase});
my $tx_data =<<DATA;
<tr>
<td style="font-size: 14px; width: 50%">Coinbase: $coinbase</td>
<td style="font-size: 14px; width: 50%">Locktime: $locktime</td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Transparent Inputs: $vins </td>
<td style="font-size: 14px; width: 50%">Transparent Outputs: $vouts </td>
</tr>
<tr>
<td style="font-size: 14px; width: 50%">Shielded Inputs: $zins </td>
<td style="font-size: 14px; width: 50%">Shielded Outputs: $zouts </td>
</tr>
DATA
$tx_template =~ s/#TX_DATA#/$tx_data/g;
my $cmd = "mkdir -p $tx_dir";
warn $cmd;
## create tx dir + page
qx{$cmd};
open(my $fh, '>', $tx_file) or die "$tx_file: $!";
print $fh $tx_template;
close $fh or die $!;
## create tx view on block page
my $from = $o->{vin}->[0] ? $o->{vin}->[0]->{address} : "zs1???";
#my $to = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "zs1???";
my $to2 = "";
# only look at coinbase tx's
if($txi == 0) {
# LEXICAL SCOPING BUG, MAN!
$mineraddress = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "";
$thisminer = $mineraddress;
}
# say "<!-- miner for $tx is $mineraddress -->";
my $to = $mineraddress ? $mineraddress : "zs1???";
if($o->{vout}->[1]) {
$to2 = $o->{vout}->[1]->{scriptPubKey}->{addresses}->[0];
}
$valueBalance = ($o->{vout}->[0]->{value} || 0) + ($o->{vout}->[1]->{value} || 0);
$valueBalance ||= "?";
$from ||= "";
$txtype = "Mining";
if($zins+$zouts>0) {
$txtype = "Shielded";
if($zins==0 && $zouts>0) { $txtype = "Shielding"; }
if($vins==0 && $vouts==0){ $txtype = "Fully Shielded" }
# this is prevented by consensus rule on HUSH mainnet
# but if we see it, ring the bell, lulz
if($zins>0 && $zouts==0) { $txtype = "De-Shielding!"; }
}
#if($vouts>0) { $txtype = "DPoW"; }
my $stuff;
if ($txtype eq "Mining") {
$stuff =<<STUFF;
=> $to
<br>
=> $to2
STUFF
} else {
#TODO: fix this shite
$stuff =<<STUFF;
$from => $to
<br>
$from => $to2
STUFF
}
my $tx_table = <<HTML;
<table>
<tr>
<td style="font-size: 14px"><a href="/tx/$tx" class="mainlinkexplorer">$tx</a></td>
<td style="font-size: 14px">vins: $vins, vouts: $vouts</td>
<td style="font-size: 14px">zins: $zins, zouts: $zouts</td>
</tr>
<tr>
<td style="font-size: 14px">$stuff</td>
<td style="font-size: 14px">$txtime</td>
<td style="font-size: 14px">$valueBalance HUSH</td>
</tr>
</table>
HTML
$STATS->{TX_TABLE} .= $tx_table;
$txi++;
}
# $STATS->{TX_TABLE} .= "</table>";
# $STATS->{TX_TABLE} .= "<pre>" . Dumper [ $vin ];''
$block_template =~ s/#TX_TABLE#/$STATS->{TX_TABLE}/ge;
# > ?
open(my $fh, '>>', $new_block_file) or die "$new_block_file: $!";
print $fh $block_template;
close $fh or die $!;
warn "wrote to $new_block_file ";
} else {
warn "block exists on disk, looking info up";
#TODO: error-checking for corrupt data
#warn Dumper $block;
my $lookuptx = $block->{tx}->[0];
my $o = get_raw($lookuptx);
$thisminer = $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0];
warn "thisminer=$thisminer";
}
my $blockduration = 0;
if($#blocks >= 0) {
$blockduration = $time - $blocks[$#blocks]->[3];
}
# give data to blocks after we have processed everything
my $b = [ $h, $hash, $reward,$time,$numtx,$thisminer, $blockduration ];
#warn Dumper $b;
push @blocks, $b;
;
}
sub get_raw {
my $tx = shift;
my $cmd = "$cli getrawtransaction $tx 1";
warn $cmd;
my $json = qx!$cmd!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
my $j = JSON::Any->new;
my $o = $j->decode($json);
return $o;
}
# render data
for my $b (reverse @blocks) {
my ($height,$hash,$reward,$time,$txs,$miner,$duration) = @$b;
$time = localtime($time);
# we can't calc the duration of the first block we look at, yet
$duration = "--" unless $duration;
$STATS->{BLOCKS_TABLE} .= <<"FUCK";
<table>
<tr>
<td style="font-size: 14px"><a href="/block/$height/" class="mainlinkexplorer">$height</a></td>
<td style="font-size: 14px"><a href="/block/$hash/" class="mainlinkexplorer">$hash</a></td>
<td style="font-size: 14px">$time</td>
</tr>
<tr>
<td style="font-size: 14px">${duration}s</td>
<td style="font-size: 14px">$miner + $reward</td>
<td style="font-size: 14px">Transactions: $txs</td>
</tr>
</table>
FUCK
}
for my $s (@symbols) {
if($s && $STATS->{$s}) { $template =~ s/#$s#/$STATS->{$s}/ge }
}
# derived stat
#my $zpct = sprintf "%.3f", $STATS->{SUPPLY} > 0 ? 100*($STATS->{ZFUNDS}/$STATS->{SUPPLY}) : "0.000";
#$template =~ s/#ZFUNDS_PERCENT#/$zpct/ge;
say $template;
###### functions
# get block at given height
sub get_block {
my $height = shift;
return if $height < 0;
my $block = $r->get("block:$height") || '';
# create data if it's not there
if( $block =~ m/^HASH/ || length($block) == 0 ) {
my $cmd = "$cli getblock $height";
warn $cmd;
$block = qx/$cmd/;
}
my $json = $block;
if($json) {
$block = $j->decode($json);
# cache in Redis
warn Dumper [ "redis set block:$height =>", $json ];
$r->set("block:$height",$json);
} else {
warn "empty block $height!!" unless $json;
warn Dumper [$json];
}
return $block;
}
sub readfile {
my $file = shift;
my $data = "";
open(my $fh, '<', $file) or die "$file: $!";
my $txlist = 0;
while(<$fh>){
$data.=$_
}
close($fh);
return $data;
}

84
var/www/explorer.hush.land/bin/balances.pl

@ -0,0 +1,84 @@
#!/usr/bin/env perl
use strict;
use warnings;
use 5.014;
use JSON::Any;
$|=1;
# While Siona swims, we pave with bricks on the road she will run on...
my $STATS = {};
my $dir = shift || '/var/www/explorer.hush.land/var/www/explorer.hush.land/api';
my $getinfo = readfile("$dir/getinfo.json");
my $coinsupply = readfile("$dir/coinsupply.json");
my $noprivacy = readfile("$dir/snapshots/snapshot.json");
my $template = readfile("/var/www/explorer.hush.land/var/www/explorer.hush.land/addresses/template.html");
my @symbols = qw/ BLOCKS CONNECTIONS TLS_CONNECTIONS TXCOUNT
PROTOCOLVERSION LONGESTCHAIN TIPTIME NOTARIZEDHASH
ADDRESS_DATA TOTAL_ADDRESSES TOTAL AVG UTXOS
/;
$STATS->{ADDRESS_DATA} = <<TABLE;
<table>
<tr>
<td style="font-size: 14px">Transparent Address</td>
<td style="font-size: 14px">Amount</td>
</tr>
TABLE
if ($noprivacy) {
my $j = JSON::Any->new;
my $o = $j->decode($noprivacy);
my $addresses = $o->{addresses};
$STATS->{AVG} = $o->{average};
$STATS->{TOTAL_ADDRESSES} = $o->{total_addresses};
$STATS->{UTXOS} = $o->{utxos};
$STATS->{TOTAL} = $o->{total};
for my $a (@$addresses) {
my ($addr,$amount) = ($a->{addr}, $a->{amount});
$STATS->{ADDRESS_DATA} .= <<ROW;
<tr>
<td style="font-size: 14px">$addr</td>
<td style="font-size: 14px">$amount HUSH</td>
</tr>
ROW
}
$STATS->{ADDRESS_DATA} .= "</table>";
for my $s (@symbols) {
if($s && $STATS->{$s}) { $template =~ s/#$s#/$STATS->{$s}/ge }
}
say $template;
}
sub readfile {
my $file = shift;
my $data = "";
open(my $fh, '<', $file) or die $!;
while(<$fh>){
$data.=$_;
# getinfo
if(m/"tls_connections": (\d+)/){ $STATS->{TLS_CONNECTIONS} ||= $1; }
if(m/"connections": (\d+)/){ $STATS->{CONNECTIONS} ||= $1; }
if(m/"blocks": (\d+)/){ $STATS->{BLOCKS} ||= $1; }
if(m/"notarized": (\d+)/){ $STATS->{NOTARIZED} ||= $1; }
if(m/"protocolversion": (\d+)/){ $STATS->{PROTOCOLVERSION} ||= $1; }
if(m/"longestchain": (\d+)/){ $STATS->{LONGESTCHAIN} ||= $1; }
if(m/"notarizedhash": "([a-z0-9]+)"/){ $STATS->{NOTARIZEDHASH} ||= $1; }
if(m/"tiptime": (\d+)/){ $STATS->{TIPTIME} ||= localtime($1) . "<!-- $1 -->"; }
# coinsupply
if(m/"zfunds": (\d+\.\d+)/){ $STATS->{ZFUNDS} ||= $1; }
if(m/"total": (\d+\.\d+)/){ $STATS->{SUPPLY} ||= $1; }
# getmininginfo
if(m/"difficulty": (\d+)/){ $STATS->{DIFFICULTY} ||= $1; }
if(m/"networksolps": (\d+)/){ $STATS->{NETWORKSOLPS} ||= sprintf("%.2f", $1 / 1_000_000); }
# getchaintxstats
if(m/"txcount": (\d+)/){ $STATS->{TXCOUNT} ||= $1; }
if(m/"txrate": (\d+\.\d+)/){ $STATS->{TXRATE} ||= sprintf("%.4f",$1*60); }
if(m/"window_final_block_hash": "([a-z0-9]+)"/){ $STATS->{BLOCKHASH} ||= $1; }
}
close($fh);
return $data;
}

57
var/www/explorer.hush.land/bin/block-340k.json

@ -0,0 +1,57 @@
{
"hex": "0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff050320300500ffffffff02d088c31000000000232102acb24edc1cb97c154773b24c30380ddb6ff3d8f4b9d73dcab18e07ed6b19ab64ac50d6dc01000000001976a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac2f7ec55f000000000000000000000000000000",
"txid": "d552f6312ef32decc2034ce14aa09020d167c756b8e9ae4f3734275a35010af8",
"overwintered": true,
"version": 4,
"last_notarized_height": 319432,
"versiongroupid": "892f2085",
"locktime": 1606778415,
"expiryheight": 0,
"vin": [
{
"coinbase": "0320300500",
"sequence": 4294967295
}
],
"vout": [
{
"value": 2.81250000,
"valueSat": 281250000,
"n": 0,
"scriptPubKey": {
"asm": "02acb24edc1cb97c154773b24c30380ddb6ff3d8f4b9d73dcab18e07ed6b19ab64 OP_CHECKSIG",
"hex": "2102acb24edc1cb97c154773b24c30380ddb6ff3d8f4b9d73dcab18e07ed6b19ab64ac",
"reqSigs": 1,
"type": "pubkey",
"addresses": [
"RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj"
]
}
},
{
"value": 0.31250000,
"valueSat": 31250000,
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 5eb10cf64f2bab1b457f1f25e658526155928fac OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn"
]
}
}
],
"valueBalance": 0.00000000,
"vShieldedSpend": [
],
"vShieldedOutput": [
],
"blockhash": "0000000051649db14dd1557ef4c5cc2bd8ea110e3f0c453f491efe4d21a31356",
"height": 340000,
"confirmations": 1,
"rawconfirmations": 50,
"time": 1606778445,
"blocktime": 1606778445
}

337
var/www/explorer.hush.land/bin/doesnotwork_update_addr.pl

@ -0,0 +1,337 @@
#!/usr/bin/env perl
use strict;
use warnings;
use JSON::Any;
use Data::Dumper;
use 5.014;
my $STATS = {};
$|=1;
my $ADDRS = {};
# While Siona swims, we pave with bricks on the road she will run on...
my $dir = shift || $ENV{HOME} . "/data";
my $cli = "/home/duke/git/hush3/src/hush-cli";
my $getinfo = readfile("$dir/getinfo.json");
my $template = readfile("/var/www/explorer.hush.is/address/template.html");
my $addrdir = "/var/www/explorer.hush.is/address/";
if($getinfo =~ m/"blocks": (\d+)/){ $STATS->{BLOCKS} ||= $1; }
if($getinfo =~ m/"tls_connections": (\d+)/){ $STATS->{TLS_CONNECTIONS} ||= $1; }
if($getinfo =~ m/"connections": (\d+)/){ $STATS->{CONNECTIONS} ||= $1; }
if($getinfo =~ m/"protocolversion": (\d+)/){ $STATS->{PROTOCOLVERSION} ||= $1; }
my @symbols = qw/
TX_TABLE ADDRESSES_TABLE TLS_CONNECTIONS CONNECTIONS PROTOCOLVERSION
/;
my @addresses;
my $height = $STATS->{BLOCKS};
$STATS->{ADDRESSES_TABLE} = "";
$STATS->{TX_TABLE} = "";
my $mineraddress = "";
for my $h ($height-50 .. $height) {
my $thisminer = "";
# TODO: fix this garbage
my $reward = $h > 340000 ? "3.125 HUSH" : "12.5 HUSH";
my $block = get_block($h);
#die Dumper $block;
my $time = localtime($block->{time}) . " UTC" || "";
my @txs = @{ $block->{tx} };
my $numtx = @txs;
# TODO: look on filesystem first? redis cache?
my $hash = qx!$cli getblockhash $h!;
chomp $hash;
my $root = "/var/www/explorer.hush.is";
my $blockdir = "$root/block/$hash";
if (!-e "$root/block/$h") {
# make /block/HEIGHT work
my $cmd = "ln -s $blockdir $root/block/$h";
qx{$cmd};
warn $cmd;
}
if (!-d $blockdir) {
# so explorer.hush.is/block/HASH works
my $cmd = "mkdir -p $blockdir";
qx{$cmd};
warn $cmd;
my $block_template_file = "$root/block/template.html";
my $new_block_file = "$root/block/$hash/index.html";
# TODO: process template with block details
my $block_template = readfile($block_template_file);
$block_template =~ s/#BLOCKS#/$h/g;
$block_template =~ s/#BLOCKHASH#/$hash/g;
$block_template =~ s/#PREVIOUSBLOCKHASH#/$block->{previousblockhash}/ge;
$block_template =~ s/#BLOCKTIME#/$time/g;
$block_template =~ s/#ANCHOR#/$block->{anchor}/ge;
$block_template =~ s/#VERSION#/$block->{version}/ge;
$block_template =~ s/#BITS#/$block->{bits}/ge;
$block_template =~ s/#BLOCKSIZE#/$block->{size}/ge;
$block_template =~ s/#CHAINWORK#/$block->{chainwork}/ge;
$block_template =~ s/#MERKLEROOT#/$block->{merkleroot}/ge;
$block_template =~ s/#FINALSAPLINGROOT#/$block->{finalsaplingroot}/ge;
# TODO
$block_template =~ s/#BLOCKREWARD#/3.125 HUSH/g;
$block_template =~ s/#BLOCKNONCE#/$block->{nonce}/ge;
$block_template =~ s/#DIFFICULTY#/$block->{difficulty}/ge;
$block_template =~ s/#NUM_TXS#/$numtx/g;
my $txtype = "";
# generate tx list table
$STATS->{TX_TABLE}=<<HTML;
<table border=1>
<tr><th>Transaction ID (txid)</th><th>Type</th><th>Inputs</th>
<th>Outputs</th><th>Shielded Inputs</th><th>Shielded Outputs</th>
<th>Addresses</th>
<th>Amount</th>
<th>Transaction Time</th>
<!--
<th>Expiry Height</th>
<th>Lock Time</th>
-->
</tr>
HTML
my $txi = 0;
for my $tx (@txs) {
my $json = qx!$cli getrawtransaction $tx 1!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
my $j = JSON::Any->new;
my $o = $j->decode($json);
$TX->{$tx} = $o;
my $tx_dir = "$root/tx/$tx";
my $tx_file = "$root/tx/$tx/index.html";
my $tx_template_file = "$root/tx/template.html";
my $tx_template = readfile($tx_template_file);
my $txtime = localtime($o->{time}) . " UTC ( " . $o->{time} . " )";
#my $txsize = $o->{size} . " bytes";
$tx_template =~ s/#TXID#/$tx/ge;
$tx_template =~ s/#TXTIME#/$txtime/ge;
#$tx_template =~ s/#TXSIZE#/$txsize/g;
$tx_template =~ s/#BLOCKHEIGHT#/$h/ge;
$tx_template =~ s/#BLOCKHASH#/$hash/ge;
my ($vin,$vout,$zin,$zout) = ($o->{vin},$o->{vout},$o->{vShieldedSpend},$o->{vShieldedOutput});
my $expiryheight = $o->{expiryheight} == 0 ? "Default" : $o->{expiryheight};
my $locktime = localtime($o->{locktime}) . " UTC ( " . $o->{locktime} . " )";
my $valueBalance = $o->{valueBalance} || "?";
my $vins = @$vin;
my $vouts = @$vout;
my $zins = @$zin;
my $zouts = @$zout;
my $coinbase = $vin->[0] ? $vin->[0]->{coinbase}." with sequence ".$vin->[0]->{sequence} : "False"; #($vin->[0] && $vin->[0]->{coinbase}) ? $vin->[0]{coinbase} . " with sequence " . $vin->{sequence} : "False";
# coinbase does not count as a transparent input
$vins-- if ($vin->[0] && $vin->[0]->{coinbase});
my $tx_data =<<DATA;
<table border=1>
<tr><th>Coinbase</th><td align=center>$coinbase</td></tr>
<tr><th>Expiry Height</th><td align=center>$expiryheight</td></tr>
<tr><th>Transparent Inputs</th><td align=center> $vins </td></tr>
<tr><th>Transparent Outputs</th><td align=center> $vouts </td></tr>
<tr><th>Shielded Inputs</th><td align=center> $zins </td></tr>
<tr><th>Shielded Outputs</th><td align=center> $zouts </td></tr>
<tr><th>Locktime</th><td align=center>$locktime</td></tr>
</table>
DATA
$tx_template =~ s/#TX_DATA#/$tx_data/g;
my $cmd = "mkdir -p $tx_dir";
warn $cmd;
## create tx dir + page
qx{$cmd};
open(my $fh, '>', $tx_file) or die "$tx_file: $!";
print $fh $tx_template;
close $fh or die $!;
## create tx view on block page
my $from = $o->{vin}->[0] ? $o->{vin}->[0]->{address} : "zs1???";
#my $to = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "zs1???";
my $to2 = "";
# only look at coinbase tx's
if($txi == 0) {
# LEXICAL SCOPING BUG, MAN!
$mineraddress = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "";
$thisminer = $mineraddress;
}
say "<!-- miner for $tx is $mineraddress -->";
my $to = $mineraddress ? $mineraddress : "zs1???";
if($o->{vout}->[1]) {
$to2 = $o->{vout}->[1]->{scriptPubKey}->{addresses}->[0];
}
$valueBalance = ($o->{vout}->[0]->{value} || 0) + ($o->{vout}->[1]->{value} || 0);
$valueBalance ||= "?";
$from ||= "";
$txtype = "Mining";
if($zins+$zouts>0) {
$txtype = "Shielded";
if($zins==0 && $zouts>0) { $txtype = "Shielding"; }
if($vins==0 && $vouts==0){ $txtype = "Fully Shielded" }
# this is prevented by consensus rule on HUSH mainnet
# but if we see it, ring the bell, lulz
if($zins>0 && $zouts==0) { $txtype = "De-Shielding!"; }
}
#if($vouts>0) { $txtype = "DPoW"; }
my $stuff;
if ($txtype eq "Mining") {
$stuff =<<STUFF;
<pre>
=> $to
=> $to2
</pre>
<br/>
STUFF
} else {
#TODO: fix this shite
$stuff =<<STUFF;
<pre>
$from => $to
$from => $to2
</pre>
<br/>
STUFF
}
my $tx_table = <<HTML;
<tr>
<td><a href="/tx/$tx">$tx</a></td>
<td>$txtype</td>
<td align=center>$vins</td>
<td align=center>$vouts</td>
<td align=center>$zins</td>
<td align=center>$zouts</td>
<td>$stuff</td>
<td>$valueBalance HUSH</td>
<td>$txtime</td>
<!--
<td>$expiryheight</td>
<td>$locktime</td>
-->
</tr>
HTML
$STATS->{TX_TABLE} .= $tx_table;
$txi++;
}
$STATS->{TX_TABLE} .= "</table>";
# $STATS->{TX_TABLE} .= "<pre>" . Dumper [ $vin ];''
$block_template =~ s/#TX_TABLE#/$STATS->{TX_TABLE}/ge;
# > ?
open(my $fh, '>>', $new_block_file) or die "$new_block_file: $!";
print $fh $block_template;
close $fh or die $!;
warn "wrote to $new_block_file ";
} else {
warn "block exists on disk, looking info up";
#TODO: error-checking for corrupt data
#warn Dumper $block;
my $lookuptx = $block->{tx}->[0];
my $o = get_raw($lookuptx);
$thisminer = $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0];
warn "thisminer=$thisminer";
}
# give data to blocks after we have processed everything
my $b = [ $h, $hash, $reward,$time,$numtx,$thisminer,0 ];
#warn Dumper $b;
push @addresses, $b;
}
sub get_raw {
my $tx = shift;
my $cmd = "$cli getrawtransaction $tx 1";
warn $cmd;
my $json = qx!$cmd!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
my $j = JSON::Any->new;
my $o = $j->decode($json);
return $o;
}
# render data
for my $b (reverse @addresses) {
$STATS->{ADDRESSES_TABLE} .= <<"FUCK";
<tr>
<td align=center><a href="/block/$b->[0]">$b->[0]</a></td>
<td align=center><a href="/block/$b->[1]">$b->[1]</a></td>
<td align=center>$b->[2]</td>
<td align=center>$b->[3]</td>
<td align=center>$b->[4]</td>
<td align=center>$b->[5]</td>
</tr>
FUCK
}
for my $s (@symbols) {
if($s && $STATS->{$s}) { $template =~ s/#$s#/$STATS->{$s}/ge }
}
say $template;
###### functions
sub get_block {
my $height = shift;
my $dir = "/home/duke/data/blocks/";
my $file = "$dir/block-$height.json";
my $stats = {};
my $block;
# create data if it's not there
if( (!-e $file) || (-s $file == 0)) {
# logging?
my $cmd = "$cli getblock $height > /home/duke/data/blocks/block-$height.json";
warn $cmd;
qx/$cmd/;
# let the file sync to disk
sleep 1;
}
my $json = readfile($file);
if($json) {
my $j = JSON::Any->new;
$block = $j->decode($json);
} else {
warn "empty block $height!!" unless $json;
warn Dumper [$json];
}
return $block;
}
sub readfile {
my $file = shift;
my $data = "";
open(my $fh, '<', $file) or die "$file: $!";
my $txlist = 0;
while(<$fh>){
$data.=$_
}
close($fh);
return $data;
}

102
var/www/explorer.hush.land/bin/example.html

@ -0,0 +1,102 @@
While Siona swims, we lack the bricks on the road she will run on...
<!DOCTYPE html>
<html>
<head>
<title>Hush Explorer: Speak And Transact Freely</title>
<style>
body {
width: 66em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
<!-- this explorer must be hosted at / or this needs to be changed.
Not specifying a hostname makes it compatible with Tor/i2p/etc and other mirrors
- Duke
-->
<meta http-equiv="refresh" content="120; URL=/">
</head>
<!--
"Fuck Blockchain Analysts"
- Duke Leto and The Hush Developers
-->
<body>
<h1>HUSH Blockchain Explorer</h1>
<div id=stats>
<table width="100%" border=1>
<tr>
<td>
<table>
<tr><th>Current Height</th><td>339797</td></tr>
<tr><th>Notarized Height</th><td> 319432</td></tr>
<tr><th>Total Transactions</th><td> 636565</td></tr>
<!--<tr><th>Transactions Per Day</th><td> #TXS_PER_DAY#</td></tr> -->
<tr><th>Difficulty</th><td> 48982331</td></tr>
<tr><th>Network Solution Rate (Hashrate)</th><td> 5.988313 MegaSols/s</td></tr>
<tr><th>Circulating Supply</th><td> 10424467.60612515 HUSH</td></tr>
<tr><th>Shielded Supply</th><td> 3201461.20925607 HUSH (30.711 %)</td></tr>
</table>
</td>
<td valign=top>
<table>
<tr><th>Blockhash</th><th>Block height</th><th>Transactions</th><th>Shielded Transactions</th></tr>
<tr><td><a href="/block/#BLOCK01_HASH#">#BLOCK01_HASH#</a></td><td>#BLOCK01_HEIGHT#</td><td>#BLOCK01_TXS#</td><td>#BLOCK01_ZTXS#</tr>
<tr><td><a href="/block/#BLOCK02_HASH#">#BLOCK02_HASH#</a></td><td>#BLOCK02_HEIGHT#</td><td>#BLOCK02_TXS#</td><td>#BLOCK02_ZTXS#</tr>
<tr><td><a href="/block/#BLOCK03_HASH#">#BLOCK03_HASH#</a></td><td>#BLOCK03_HEIGHT#</td><td>#BLOCK03_TXS#</td><td>#BLOCK03_ZTXS#</tr>
<tr><td><a href="/block/#BLOCK04_HASH#">#BLOCK04_HASH#</a></td><td>#BLOCK04_HEIGHT#</td><td>#BLOCK04_TXS#</td><td>#BLOCK04_ZTXS#</tr>
<tr><td><a href="/block/#BLOCK05_HASH#">#BLOCK05_HASH#</a></td><td>#BLOCK05_HEIGHT#</td><td>#BLOCK05_TXS#</td><td>#BLOCK05_ZTXS#</tr>
<tr><td><a href="/block/#BLOCK06_HASH#">#BLOCK06_HASH#</a></td><td>#BLOCK06_HEIGHT#</td><td>#BLOCK06_TXS#</td><td>#BLOCK06_ZTXS#</tr>
<tr><td><a href="/block/#BLOCK07_HASH#">#BLOCK07_HASH#</a></td><td>#BLOCK07_HEIGHT#</td><td>#BLOCK07_TXS#</td><td>#BLOCK07_ZTXS#</tr>
<tr><td><a href="/block/#BLOCK08_HASH#">#BLOCK08_HASH#</a></td><td>#BLOCK08_HEIGHT#</td><td>#BLOCK08_TXS#</td><td>#BLOCK08_ZTXS#</tr>
<tr><td><a href="/block/#BLOCK09_HASH#">#BLOCK09_HASH#</a></td><td>#BLOCK09_HEIGHT#</td><td>#BLOCK09_TXS#</td><td>#BLOCK09_ZTXS#</tr>
<tr><td><a href="/block/#BLOCK10_HASH#">#BLOCK10_HASH#</a></td><td>#BLOCK10_HEIGHT#</td><td>#BLOCK10_TXS#</td><td>#BLOCK10_ZTXS#</tr>
</table>
</td>
</tr>
</table>
</div>
<br>
<h1>About This Extreme Explorer</h1>
This Explorer doesn't snoop on your privacy! There is no Javascript or images for that reason.
Either could be used to steal your privacy.
<h1>License</h1>
GPLv3
<br>
<a href="https://hush.is/twitter">Twitter</a>
|
<a href="https://hush.is/tg">Telegram</a>
|
<a href="https://hush.is/telegram_support">Telegram Support</a>
|
<a href="https://hush.is/telegram_mining">Telegram Mining</a>
|
<a href="https://hush.is/reddit">Reddit</a>
|
<a href="https://hush.is/youtube">YouTube</a>
|
<a href="https://hush.is/bitcointalk">BitcoinTalk</a>
|
<a href="https://hush.is/mastodon">Mastodon</a>
|
<a href="https://hush.is/matrix">Matrix</a>
<br/>
<br/>
<br/>
</body>
</html>

1
var/www/explorer.hush.land/bin/nope/README

@ -0,0 +1 @@
This is some old version of the code for historical purposes.

337
var/www/explorer.hush.land/bin/nope/update_addresses.pl

@ -0,0 +1,337 @@
#!/usr/bin/env perl
use strict;
use warnings;
use JSON::Any;
use Data::Dumper;
use 5.014;
my $STATS = {};
$|=1;
my $ADDRS = {};
# While Siona swims, we pave with bricks on the road she will run on...
my $dir = shift || $ENV{HOME} . "/data";
my $cli = "/home/duke/git/hush3/src/hush-cli";
my $getinfo = readfile("$dir/getinfo.json");
my $template = readfile("/var/www/explorer.hush.is/address/template.html");
my $addrdir = "/var/www/explorer.hush.is/address/";
if($getinfo =~ m/"blocks": (\d+)/){ $STATS->{BLOCKS} ||= $1; }
if($getinfo =~ m/"tls_connections": (\d+)/){ $STATS->{TLS_CONNECTIONS} ||= $1; }
if($getinfo =~ m/"connections": (\d+)/){ $STATS->{CONNECTIONS} ||= $1; }
if($getinfo =~ m/"protocolversion": (\d+)/){ $STATS->{PROTOCOLVERSION} ||= $1; }
my @symbols = qw/
TX_TABLE ADDRESSES_TABLE TLS_CONNECTIONS CONNECTIONS PROTOCOLVERSION
/;
my @addresses;
my $height = $STATS->{BLOCKS};
$STATS->{ADDRESSES_TABLE} = "";
$STATS->{TX_TABLE} = "";
my $mineraddress = "";
for my $h ($height-50 .. $height) {
my $thisminer = "";
# TODO: fix this garbage
my $reward = $h > 340000 ? "3.125 HUSH" : "12.5 HUSH";
my $block = get_block($h);
#die Dumper $block;
my $time = localtime($block->{time}) . " UTC" || "";
my @txs = @{ $block->{tx} };
my $numtx = @txs;
# TODO: look on filesystem first? redis cache?
my $hash = qx!$cli getblockhash $h!;
chomp $hash;
my $root = "/var/www/explorer.hush.is";
my $blockdir = "$root/block/$hash";
if (!-e "$root/block/$h") {
# make /block/HEIGHT work
my $cmd = "ln -s $blockdir $root/block/$h";
qx{$cmd};
warn $cmd;
}
if (!-d $blockdir) {
# so explorer.hush.is/block/HASH works
my $cmd = "mkdir -p $blockdir";
qx{$cmd};
warn $cmd;
my $block_template_file = "$root/block/template.html";
my $new_block_file = "$root/block/$hash/index.html";
# TODO: process template with block details
my $block_template = readfile($block_template_file);
$block_template =~ s/#BLOCKS#/$h/g;
$block_template =~ s/#BLOCKHASH#/$hash/g;
$block_template =~ s/#PREVIOUSBLOCKHASH#/$block->{previousblockhash}/ge;
$block_template =~ s/#BLOCKTIME#/$time/g;
$block_template =~ s/#ANCHOR#/$block->{anchor}/ge;
$block_template =~ s/#VERSION#/$block->{version}/ge;
$block_template =~ s/#BITS#/$block->{bits}/ge;
$block_template =~ s/#BLOCKSIZE#/$block->{size}/ge;
$block_template =~ s/#CHAINWORK#/$block->{chainwork}/ge;
$block_template =~ s/#MERKLEROOT#/$block->{merkleroot}/ge;
$block_template =~ s/#FINALSAPLINGROOT#/$block->{finalsaplingroot}/ge;
# TODO
$block_template =~ s/#BLOCKREWARD#/3.125 HUSH/g;
$block_template =~ s/#BLOCKNONCE#/$block->{nonce}/ge;
$block_template =~ s/#DIFFICULTY#/$block->{difficulty}/ge;
$block_template =~ s/#NUM_TXS#/$numtx/g;
my $txtype = "";
# generate tx list table
$STATS->{TX_TABLE}=<<HTML;
<table border=1>
<tr><th>Transaction ID (txid)</th><th>Type</th><th>Inputs</th>
<th>Outputs</th><th>Shielded Inputs</th><th>Shielded Outputs</th>
<th>Addresses</th>
<th>Amount</th>
<th>Transaction Time</th>
<!--
<th>Expiry Height</th>
<th>Lock Time</th>
-->
</tr>
HTML
my $txi = 0;
for my $tx (@txs) {
my $json = qx!$cli getrawtransaction $tx 1!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
my $j = JSON::Any->new;
my $o = $j->decode($json);
$TX->{$tx} = $o;
my $tx_dir = "$root/tx/$tx";
my $tx_file = "$root/tx/$tx/index.html";
my $tx_template_file = "$root/tx/template.html";
my $tx_template = readfile($tx_template_file);
my $txtime = localtime($o->{time}) . " UTC ( " . $o->{time} . " )";
#my $txsize = $o->{size} . " bytes";
$tx_template =~ s/#TXID#/$tx/ge;
$tx_template =~ s/#TXTIME#/$txtime/ge;
#$tx_template =~ s/#TXSIZE#/$txsize/g;
$tx_template =~ s/#BLOCKHEIGHT#/$h/ge;
$tx_template =~ s/#BLOCKHASH#/$hash/ge;
my ($vin,$vout,$zin,$zout) = ($o->{vin},$o->{vout},$o->{vShieldedSpend},$o->{vShieldedOutput});
my $expiryheight = $o->{expiryheight} == 0 ? "Default" : $o->{expiryheight};
my $locktime = localtime($o->{locktime}) . " UTC ( " . $o->{locktime} . " )";
my $valueBalance = $o->{valueBalance} || "?";
my $vins = @$vin;
my $vouts = @$vout;
my $zins = @$zin;
my $zouts = @$zout;
my $coinbase = $vin->[0] ? $vin->[0]->{coinbase}." with sequence ".$vin->[0]->{sequence} : "False"; #($vin->[0] && $vin->[0]->{coinbase}) ? $vin->[0]{coinbase} . " with sequence " . $vin->{sequence} : "False";
# coinbase does not count as a transparent input
$vins-- if ($vin->[0] && $vin->[0]->{coinbase});
my $tx_data =<<DATA;
<table border=1>
<tr><th>Coinbase</th><td align=center>$coinbase</td></tr>
<tr><th>Expiry Height</th><td align=center>$expiryheight</td></tr>
<tr><th>Transparent Inputs</th><td align=center> $vins </td></tr>
<tr><th>Transparent Outputs</th><td align=center> $vouts </td></tr>
<tr><th>Shielded Inputs</th><td align=center> $zins </td></tr>
<tr><th>Shielded Outputs</th><td align=center> $zouts </td></tr>
<tr><th>Locktime</th><td align=center>$locktime</td></tr>
</table>
DATA
$tx_template =~ s/#TX_DATA#/$tx_data/g;
my $cmd = "mkdir -p $tx_dir";
warn $cmd;
## create tx dir + page
qx{$cmd};
open(my $fh, '>', $tx_file) or die "$tx_file: $!";
print $fh $tx_template;
close $fh or die $!;
## create tx view on block page
my $from = $o->{vin}->[0] ? $o->{vin}->[0]->{address} : "zs1???";
#my $to = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "zs1???";
my $to2 = "";
# only look at coinbase tx's
if($txi == 0) {
# LEXICAL SCOPING BUG, MAN!
$mineraddress = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "";
$thisminer = $mineraddress;
}
say "<!-- miner for $tx is $mineraddress -->";
my $to = $mineraddress ? $mineraddress : "zs1???";
if($o->{vout}->[1]) {
$to2 = $o->{vout}->[1]->{scriptPubKey}->{addresses}->[0];
}
$valueBalance = ($o->{vout}->[0]->{value} || 0) + ($o->{vout}->[1]->{value} || 0);
$valueBalance ||= "?";
$from ||= "";
$txtype = "Mining";
if($zins+$zouts>0) {
$txtype = "Shielded";
if($zins==0 && $zouts>0) { $txtype = "Shielding"; }
if($vins==0 && $vouts==0){ $txtype = "Fully Shielded" }
# this is prevented by consensus rule on HUSH mainnet
# but if we see it, ring the bell, lulz
if($zins>0 && $zouts==0) { $txtype = "De-Shielding!"; }
}
#if($vouts>0) { $txtype = "DPoW"; }
my $stuff;
if ($txtype eq "Mining") {
$stuff =<<STUFF;
<pre>
=> $to
=> $to2
</pre>
<br/>
STUFF
} else {
#TODO: fix this shite
$stuff =<<STUFF;
<pre>
$from => $to
$from => $to2
</pre>
<br/>
STUFF
}
my $tx_table = <<HTML;
<tr>
<td><a href="/tx/$tx">$tx</a></td>
<td>$txtype</td>
<td align=center>$vins</td>
<td align=center>$vouts</td>
<td align=center>$zins</td>
<td align=center>$zouts</td>
<td>$stuff</td>
<td>$valueBalance HUSH</td>
<td>$txtime</td>
<!--
<td>$expiryheight</td>
<td>$locktime</td>
-->
</tr>
HTML
$STATS->{TX_TABLE} .= $tx_table;
$txi++;
}
$STATS->{TX_TABLE} .= "</table>";
# $STATS->{TX_TABLE} .= "<pre>" . Dumper [ $vin ];''
$block_template =~ s/#TX_TABLE#/$STATS->{TX_TABLE}/ge;
# > ?
open(my $fh, '>>', $new_block_file) or die "$new_block_file: $!";
print $fh $block_template;
close $fh or die $!;
warn "wrote to $new_block_file ";
} else {
warn "block exists on disk, looking info up";
#TODO: error-checking for corrupt data
#warn Dumper $block;
my $lookuptx = $block->{tx}->[0];
my $o = get_raw($lookuptx);
$thisminer = $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0];
warn "thisminer=$thisminer";
}
# give data to blocks after we have processed everything
my $b = [ $h, $hash, $reward,$time,$numtx,$thisminer,0 ];
#warn Dumper $b;
push @addresses, $b;
}
sub get_raw {
my $tx = shift;
my $cmd = "$cli getrawtransaction $tx 1";
warn $cmd;
my $json = qx!$cmd!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
my $j = JSON::Any->new;
my $o = $j->decode($json);
return $o;
}
# render data
for my $b (reverse @addresses) {
$STATS->{ADDRESSES_TABLE} .= <<"FUCK";
<tr>
<td align=center><a href="/block/$b->[0]">$b->[0]</a></td>
<td align=center><a href="/block/$b->[1]">$b->[1]</a></td>
<td align=center>$b->[2]</td>
<td align=center>$b->[3]</td>
<td align=center>$b->[4]</td>
<td align=center>$b->[5]</td>
</tr>
FUCK
}
for my $s (@symbols) {
if($s && $STATS->{$s}) { $template =~ s/#$s#/$STATS->{$s}/ge }
}
say $template;
###### functions
sub get_block {
my $height = shift;
my $dir = "/home/duke/data/blocks/";
my $file = "$dir/block-$height.json";
my $stats = {};
my $block;
# create data if it's not there
if( (!-e $file) || (-s $file == 0)) {
# logging?
my $cmd = "$cli getblock $height > /home/duke/data/blocks/block-$height.json";
warn $cmd;
qx/$cmd/;
# let the file sync to disk
sleep 1;
}
my $json = readfile($file);
if($json) {
my $j = JSON::Any->new;
$block = $j->decode($json);
} else {
warn "empty block $height!!" unless $json;
warn Dumper [$json];
}
return $block;
}
sub readfile {
my $file = shift;
my $data = "";
open(my $fh, '<', $file) or die "$file: $!";
my $txlist = 0;
while(<$fh>){
$data.=$_
}
close($fh);
return $data;
}

7
var/www/explorer.hush.land/bin/tmp.pl

@ -0,0 +1,7 @@
#!/usr/bin/perl
use strict;
use warnings;
use Redis;
my $r = Redis->new;
$r->set("test:123","fuck");

74
var/www/explorer.hush.land/bin/update.pl

@ -0,0 +1,74 @@
#!/usr/bin/env perl
use strict;
use warnings;
use 5.014;
my $STATS = {};
$|=1;
# give rpc's a chance to finish before us in cron
sleep 30;
# While Siona swims, we pave with bricks on the road she will run on...
# my $dir = shift || $ENV{HOME} . "/data";
my $dir = shift || '/var/www/explorer.hush.land/var/www/explorer.hush.land/api';
my $getinfo = readfile("$dir/getinfo.json");
my $mining = readfile("$dir/getmininginfo.json");
my $txstats = readfile("$dir/getchaintxstats.json");
# run the slowest last so the RPC interface isn't juggling
my $coinsupply = readfile("$dir/coinsupply.json");
my $template = readfile("/var/www/explorer.hush.land/var/www/explorer.hush.land/template.html");
#say $template;
#warn "<!--" . $STATS->{TLS_CONNECTIONS} . "/" . $STATS->{CONNECTIONS} . " peers connected via TLS -->";
my @symbols = qw/
BLOCKS CONNECTIONS TLS_CONNECTIONS TXCOUNT
NOTARIZED ZFUNDS SUPPLY DIFFICULTY NETWORKSOLPS
PROTOCOLVERSION LONGESTCHAIN TIPTIME NOTARIZEDHASH
NOTARIZEDHEIGHT BLOCKHASH TXRATE
/;
#if ($getinfo && $mining && $txstats && $coinsupply) {
for my $s (@symbols) {
if($s && $STATS->{$s}) { $template =~ s/#$s#/$STATS->{$s}/ge }
}
# derived stat
my $zpct = sprintf "%.3f", ($STATS->{SUPPLY} || 0) > 0 ? 100*($STATS->{ZFUNDS}/$STATS->{SUPPLY}) : "0.000";
$template =~ s/#ZFUNDS_PERCENT#/$zpct/ge;
say $template;
#}
sub readfile {
my $file = shift;
my $data = "";
open(my $fh, '<', $file) or die $!;
while(<$fh>){
$data.=$_;
# getinfo
if(m/"tls_connections": (\d+)/){ $STATS->{TLS_CONNECTIONS} ||= $1; }
if(m/"connections": (\d+)/){ $STATS->{CONNECTIONS} ||= $1; }
if(m/"blocks": (\d+)/){ $STATS->{BLOCKS} ||= $1; }
if(m/"notarized": (\d+)/){ $STATS->{NOTARIZED} ||= $1; }
if(m/"protocolversion": (\d+)/){ $STATS->{PROTOCOLVERSION} ||= $1; }
if(m/"longestchain": (\d+)/){ $STATS->{LONGESTCHAIN} ||= $1; }
if(m/"notarizedhash": "([a-z0-9]+)"/){ $STATS->{NOTARIZEDHASH} ||= $1; }
if(m/"tiptime": (\d+)/){ $STATS->{TIPTIME} ||= localtime($1) . "<!-- $1 -->"; }
# coinsupply
if(m/"zfunds": (\d+\.\d+)/){ $STATS->{ZFUNDS} ||= sprintf("%8.8f", $1); }
if(m/"total": (\d+\.\d+)/){ $STATS->{SUPPLY} ||= sprintf("%8.8f", $1); }
# getmininginfo
if(m/"difficulty": (\d+)/){ $STATS->{DIFFICULTY} ||= $1; }
if(m/"networksolps": (\d+)/){ $STATS->{NETWORKSOLPS} ||= sprintf("%.2f", $1 / 1_000_000); }
# getchaintxstats
if(m/"txcount": (\d+)/){ $STATS->{TXCOUNT} ||= $1; }
if(m/"txrate": (\d+\.\d+)/){ $STATS->{TXRATE} ||= sprintf("%.4f",$1*60); }
if(m/"window_final_block_hash": "([a-z0-9]+)"/){ $STATS->{BLOCKHASH} ||= $1; }
}
close($fh);
return $data;
}
# "connections": 48,
# "tls_connections": 28,

375
var/www/explorer.hush.land/bin/update_blocks.pl

@ -0,0 +1,375 @@
#!/usr/bin/env perl
use strict;
use warnings;
use JSON::Any;
use Data::Dumper;
use 5.014;
my $STATS = {};
$|=1;
my $TX = {};
#sleep 10;
# While Siona swims, we pave with bricks on the road she will run on...
my $dir = shift || '/var/www/explorer.hush.is/api/';
my $cli = "/home/duke/git/hush3/src/hush-cli";
my $getinfo = readfile("$dir/getinfo.json");
my $mining = readfile("$dir/getmininginfo.json");
my $template = readfile("/var/www/explorer.hush.is/blocks/template.html");
my $blocksdir = "/var/www/explorer.hush.is/blocks/";
if($getinfo =~ m/"blocks": (\d+)/){ $STATS->{BLOCKS} ||= $1; }
if($getinfo =~ m/"tls_connections": (\d+)/){ $STATS->{TLS_CONNECTIONS} ||= $1; }
if($getinfo =~ m/"connections": (\d+)/){ $STATS->{CONNECTIONS} ||= $1; }
if($getinfo =~ m/"protocolversion": (\d+)/){ $STATS->{PROTOCOLVERSION} ||= $1; }
my @symbols = qw/
TX_TABLE BLOCKS_TABLE TLS_CONNECTIONS CONNECTIONS PROTOCOLVERSION
/;
my @blocks = ();
my $height = $STATS->{BLOCKS};
$STATS->{BLOCKS_TABLE} = "";
$STATS->{TX_TABLE} = "";
my $NUM_BLOCKS = 50;
my $mineraddress = "";
for my $h ($height-$NUM_BLOCKS .. $height) {
my $thisminer = "";
# TODO: fix this garbage
my $reward = $h > 340000 ? "3.125 HUSH" : "12.5 HUSH";
my $block = get_block($h);
#die Dumper $block;
my $time = $block->{time};
my @txs = @{ $block->{tx} };
my $numtx = @txs;
# TODO: look on filesystem first? redis cache?
my $hash = qx!$cli getblockhash $h!;
chomp $hash;
my $root = "/var/www/explorer.hush.is";
my $blockdir = "$root/block/$hash";
if (!-e "$root/block/$h") {
# make /block/HEIGHT work
my $cmd = "ln -s $blockdir $root/block/$h";
qx{$cmd};
warn $cmd;
}
if (!-d $blockdir) {
# so explorer.hush.is/block/HASH works
my $cmd = "mkdir -p $blockdir";
qx{$cmd};
warn $cmd;
my $block_template_file = "$root/block/template.html";
my $new_block_file = "$root/block/$hash/index.html";
# TODO: process template with block details
my $block_template = readfile($block_template_file);
$block_template =~ s/#BLOCKS#/$h/g;
$block_template =~ s/#BLOCKHASH#/$hash/g;
$block_template =~ s/#PREVIOUSBLOCKHASH#/$block->{previousblockhash}/ge;
$block_template =~ s/#BLOCKTIME#/$time/g;
$block_template =~ s/#ANCHOR#/$block->{anchor}/ge;
$block_template =~ s/#VERSION#/$block->{version}/ge;
$block_template =~ s/#BITS#/$block->{bits}/ge;
$block_template =~ s/#BLOCKSIZE#/$block->{size}/ge;
$block_template =~ s/#CHAINWORK#/$block->{chainwork}/ge;
$block_template =~ s/#MERKLEROOT#/$block->{merkleroot}/ge;
$block_template =~ s/#FINALSAPLINGROOT#/$block->{finalsaplingroot}/ge;
# TODO
$block_template =~ s/#BLOCKREWARD#/3.125 HUSH/g;
$block_template =~ s/#BLOCKNONCE#/$block->{nonce}/ge;
$block_template =~ s/#DIFFICULTY#/$block->{difficulty}/ge;
$block_template =~ s/#NUM_TXS#/$numtx/g;
my $txtype = "";
# generate tx list table
$STATS->{TX_TABLE}=<<HTML;
<table border=1>
<tr><th>Transaction ID (txid)</th><th>Type</th><th>Inputs</th>
<th>Outputs</th><th>Shielded Inputs</th><th>Shielded Outputs</th>
<th>Addresses</th>
<th>Amount</th>
<th>Transaction Time</th>
<!--
<th>Expiry Height</th>
<th>Lock Time</th>
-->
</tr>
HTML
my $txi = 0;
for my $tx (@txs) {
my $json = qx!$cli getrawtransaction $tx 1!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
my $j = JSON::Any->new;
my $o = $j->decode($json);
$TX->{$tx} = $o;
my $tx_dir = "$root/tx/$tx";
my $tx_file = "$root/tx/$tx/index.html";
my $tx_template_file = "$root/tx/template.html";
my $tx_template = readfile($tx_template_file);
my $txtime = localtime($o->{time}) . " UTC ( " . $o->{time} . " )";
#my $txsize = $o->{size} . " bytes";
$tx_template =~ s/#TXID#/$tx/ge;
$tx_template =~ s/#TXTIME#/$txtime/ge;
#$tx_template =~ s/#TXSIZE#/$txsize/g;
$tx_template =~ s/#BLOCKHEIGHT#/$h/ge;
$tx_template =~ s/#BLOCKHASH#/$hash/ge;
my ($vin,$vout,$zin,$zout) = ($o->{vin},$o->{vout},$o->{vShieldedSpend},$o->{vShieldedOutput});
my $expiryheight = $o->{expiryheight} == 0 ? "Default" : $o->{expiryheight};
my $locktime = localtime($o->{locktime}) . " UTC ( " . $o->{locktime} . " )";
my $valueBalance = $o->{valueBalance} || "?";
# "vShieldedOutput": [
# {
# "cv": "61e0fed3b97e08e442408c7efc4058a9116695e6e28a22c0fbf0987fdfbcdd27",
# "cmu": "25245041af3bbc5a03da1cd6d60665f7659cbb3bab1080a6e003f856d45998fc",
# "ephemeralKey": "bffefb4f55679610bbdbd43bfba64308842348ba70bb999fad00c67356eab998",
# "encCiphertext": "b685c9d4f6164102999e88e3e30fcca37d9c402fc72533185d495a9d64f1fca277ead03aefe960eeaf102c0c92686a75c792ae8662f40601287ff19635581279d9c9940ba3c29af36166620422c6
#49c4a7ca938734ceecb93a3abc8753ff3535950662ef46d8ed3a0608a61c65be5d0bdb1c262bd63fde759040eef74d4d81619ee154bbabe4fc0e27d82b19c6ed0d4cd806d5bc75ebbb13370ff3f19979ab3b74e859d9b88d3802
#bc7a2ce7ae4305c6beec2146b374bda7234395d0aa390337e69ef5d04eddef0087244292f358b46eeb3c2a5a6d3bd1c89aaa4ebfd8bab58d2d4771b1d106db1a5dcead3b09cfc9fc38b972ce98c53d3cd658b02e58b087c7c73e
#0bd7cb093f2b15ab397094be5bc98f5865045d1845e548249fc811545db1645beb2f044366ba9ae584074e6fa5c03d786757c88ed8eff2d81570d15e64f192707d7393ce40b0f2f767cfbeaa5f05a634fe527da982241c92c4c2
#9642f633115d34fe6791f00c8867e2242485de5f0bb87a8d4e6b375f557db6968f5ecc4f07b838b2dd85dd54e4e9ae2a28e9305bd1a6ae71adf75335d5f44cc046194fdbc91fb80202f06af9431716dc6627b2aa4723b0b8e4bb
#504649b6350ba9f020106d71248227ed8d7a10e2fbcbf64824c8923149822970b3c574614a8c32602106132c1209917974566b2990cf106666f985a2fa1f1409efdc457404700da210906b0f19be61c70d70eddc2f1cbffd94bb
#4c154a332fdd345ad06bd2ac86a339a93eae25db5eb3b4c6090d8483a8e5dd642231d17f3011b2f4b629ef72c08df1eeb6e7d06e",
# "outCiphertext": "53e3865f52101faf3218b60b7d58b9c426dc7c6cff009a8ceddd58031afe9802cae0f423a1085c2b36c776db29b57db8041e9bac42d6b445a0d69eb5a2f0ef61b4790595a68750c60889ff811dce
#8fbb",
# "proof": "82eda0f7de0936f6ca8208e63bda8db9970feb232ae64635e5bea67f16fdbe1b5e5e3a6bb7b7d2f0127c0d17de494834a82e899e8eecdfc71a59de8d1808a53df2989762bd54a855dadc535f2c5107d7b6da
#a732153c4dda4ac965be79ba2ecc030bd58e4c05d5ac7be283b3dc68af8a39231a31cccb54eae65c676760182bd22965f2e1c3685de44c0b93d84519bf138c7942222795dfdd0f683474b7c75221c9355109258805cc038ca43b
#26d5770bf25882326f4f508731b36a8632bc0012"
# }
# ],
my $vins = @$vin;
my $vouts = @$vout;
my $zins = @$zin;
my $zouts = @$zout;
my $coinbase = $vin->[0] ? $vin->[0]->{coinbase}." with sequence ".$vin->[0]->{sequence} : "False"; #($vin->[0] && $vin->[0]->{coinbase}) ? $vin->[0]{coinbase} . " with sequence " . $vin->{sequence} : "False";
# coinbase does not count as a transparent input
$vins-- if ($vin->[0] && $vin->[0]->{coinbase});
my $tx_data =<<DATA;
<table border=1>
<tr><th>Coinbase</th><td align=center>$coinbase</td></tr>
<tr><th>Expiry Height</th><td align=center>$expiryheight</td></tr>
<tr><th>Transparent Inputs</th><td align=center> $vins </td></tr>
<tr><th>Transparent Outputs</th><td align=center> $vouts </td></tr>
<tr><th>Shielded Inputs</th><td align=center> $zins </td></tr>
<tr><th>Shielded Outputs</th><td align=center> $zouts </td></tr>
<tr><th>Locktime</th><td align=center>$locktime</td></tr>
</table>
DATA
$tx_template =~ s/#TX_DATA#/$tx_data/g;
my $cmd = "mkdir -p $tx_dir";
warn $cmd;
## create tx dir + page
qx{$cmd};
open(my $fh, '>', $tx_file) or die "$tx_file: $!";
print $fh $tx_template;
close $fh or die $!;
## create tx view on block page
my $from = $o->{vin}->[0] ? $o->{vin}->[0]->{address} : "zs1???";
#my $to = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "zs1???";
my $to2 = "";
# only look at coinbase tx's
if($txi == 0) {
# LEXICAL SCOPING BUG, MAN!
$mineraddress = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "";
$thisminer = $mineraddress;
}
# say "<!-- miner for $tx is $mineraddress -->";
my $to = $mineraddress ? $mineraddress : "zs1???";
if($o->{vout}->[1]) {
$to2 = $o->{vout}->[1]->{scriptPubKey}->{addresses}->[0];
}
$valueBalance = ($o->{vout}->[0]->{value} || 0) + ($o->{vout}->[1]->{value} || 0);
$valueBalance ||= "?";
$from ||= "";
$txtype = "Mining";
if($zins+$zouts>0) {
$txtype = "Shielded";
if($zins==0 && $zouts>0) { $txtype = "Shielding"; }
if($vins==0 && $vouts==0){ $txtype = "Fully Shielded" }
# this is prevented by consensus rule on HUSH mainnet
# but if we see it, ring the bell, lulz
if($zins>0 && $zouts==0) { $txtype = "De-Shielding!"; }
}
#if($vouts>0) { $txtype = "DPoW"; }
my $stuff;
if ($txtype eq "Mining") {
$stuff =<<STUFF;
<pre>
=> $to
=> $to2
</pre>
<br/>
STUFF
} else {
#TODO: fix this shite
$stuff =<<STUFF;
<pre>
$from => $to
$from => $to2
</pre>
<br/>
STUFF
}
my $tx_table = <<HTML;
<tr>
<td><a href="/tx/$tx">$tx</a></td>
<td>$txtype</td>
<td align=center>$vins</td>
<td align=center>$vouts</td>
<td align=center>$zins</td>
<td align=center>$zouts</td>
<td>$stuff</td>
<td>$valueBalance HUSH</td>
<td>$txtime</td>
<!--
<td>$expiryheight</td>
<td>$locktime</td>
-->
</tr>
HTML
$STATS->{TX_TABLE} .= $tx_table;
$txi++;
}
$STATS->{TX_TABLE} .= "</table>";
# $STATS->{TX_TABLE} .= "<pre>" . Dumper [ $vin ];''
$block_template =~ s/#TX_TABLE#/$STATS->{TX_TABLE}/ge;
# > ?
open(my $fh, '>>', $new_block_file) or die "$new_block_file: $!";
print $fh $block_template;
close $fh or die $!;
warn "wrote to $new_block_file ";
} else {
warn "block exists on disk, looking info up";
#TODO: error-checking for corrupt data
#warn Dumper $block;
my $lookuptx = $block->{tx}->[0];
my $o = get_raw($lookuptx);
$thisminer = $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0];
warn "thisminer=$thisminer";
}
my $blockduration = 0;
if($#blocks >= 0) {
$blockduration = $time - $blocks[$#blocks]->[3];
}
# give data to blocks after we have processed everything
my $b = [ $h, $hash, $reward,$time,$numtx,$thisminer, $blockduration ];
#warn Dumper $b;
push @blocks, $b;
}
sub get_raw {
my $tx = shift;
my $cmd = "$cli getrawtransaction $tx 1";
warn $cmd;
my $json = qx!$cmd!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
my $j = JSON::Any->new;
my $o = $j->decode($json);
return $o;
}
# render data
for my $b (reverse @blocks) {
my ($height,$hash,$reward,$time,$txs,$miner,$duration) = @$b;
$time = localtime($time);
# we can't calc the duration of the first block we look at, yet
$duration = "--" unless $duration;
$STATS->{BLOCKS_TABLE} .= <<"FUCK";
<tr>
<td align=center><a href="/block/$height">$height</a></td>
<td align=center><a href="/block/$hash">$hash</a></td>
<td align=center>$time UTC</td>
<td align=center>$duration s</td>
<td align=center>$miner</td>
<td align=center>$reward</td>
<td align=center>$txs</td>
</tr>
FUCK
}
for my $s (@symbols) {
if($s && $STATS->{$s}) { $template =~ s/#$s#/$STATS->{$s}/ge }
}
# derived stat
#my $zpct = sprintf "%.3f", $STATS->{SUPPLY} > 0 ? 100*($STATS->{ZFUNDS}/$STATS->{SUPPLY}) : "0.000";
#$template =~ s/#ZFUNDS_PERCENT#/$zpct/ge;
say $template;
###### functions
sub get_block {
my $height = shift;
my $dir = "/home/duke/data/blocks/";
my $file = "$dir/block-$height.json";
my $stats = {};
my $block;
# create data if it's not there
if( (!-e $file) || (-s $file == 0)) {
# logging?
my $cmd = "$cli getblock $height > /home/duke/data/blocks/block-$height.json";
warn $cmd;
qx/$cmd/;
# let the file sync to disk
sleep 1;
}
my $json = readfile($file);
if($json) {
my $j = JSON::Any->new;
$block = $j->decode($json);
} else {
warn "empty block $height!!" unless $json;
warn Dumper [$json];
}
return $block;
}
sub readfile {
my $file = shift;
my $data = "";
open(my $fh, '<', $file) or die "$file: $!";
my $txlist = 0;
while(<$fh>){
$data.=$_
}
close($fh);
return $data;
}

408
var/www/explorer.hush.land/bin/update_blocks_redis.pl

@ -0,0 +1,408 @@
#!/usr/bin/env perl
use strict;
use warnings;
use JSON::Any;
use Data::Dumper;
use Redis;
use 5.014;
my $STATS = {};
$|=1;
my $TX = {};
my $r = Redis->new;
my $j = JSON::Any->new;
#sleep 10;
# While Siona swims, we pave with bricks on the road she will run on...
my $dir = shift || '/var/www/explorer.hush.land/var/www/explorer.hush.land/api';
my $cli = "/home/hush/git/hush3/src/hush-cli";
my $getinfo = readfile("$dir/getinfo.json");
my $mining = readfile("$dir/getmininginfo.json");
my $template = readfile("/var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/template.html");
my $blocksdir = "/var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/";
if($getinfo =~ m/"blocks": (\d+)/){ $STATS->{BLOCKS} ||= $1; }
if($getinfo =~ m/"tls_connections": (\d+)/){ $STATS->{TLS_CONNECTIONS} ||= $1; }
if($getinfo =~ m/"connections": (\d+)/){ $STATS->{CONNECTIONS} ||= $1; }
if($getinfo =~ m/"protocolversion": (\d+)/){ $STATS->{PROTOCOLVERSION} ||= $1; }
my @symbols = qw/
TX_TABLE BLOCKS_TABLE TLS_CONNECTIONS CONNECTIONS PROTOCOLVERSION
/;
my @blocks = ();
my $height = $STATS->{BLOCKS} || 0;
$STATS->{BLOCKS_TABLE} = "";
$STATS->{TX_TABLE} = "";
my $mineraddress = "";
for my $h ($height-80 .. $height) {
#for my $h (910265 .. 910270) {
#last if($h < 0);
my $thisminer = "";
# TODO: fix this garbage
my $reward = $h > 340000 ? "3.125 HUSH" : "12.5 HUSH";
my $block = get_block($h);
#die Dumper $block;
my $time = $block->{time};
die Dumper [ $block ] unless $block->{time} and $block->{tx};
my @txs = @{ $block->{tx} };
my $numtx = @txs;
# TODO: look on filesystem first? redis cache?
my $hash = qx!$cli getblockhash $h!;
chomp $hash;
my $root = "/var/www/explorer.hush.land";
my $blockdir = "$root/var/www/explorer.hush.land/block/$hash";
if (!-e "$root/block/$h") {
# make /block/HEIGHT work
my $cmd = "ln -s $blockdir $root/var/www/explorer.hush.land/block/$h";
qx{$cmd};
warn $cmd;
}
if (!-d $blockdir) {
# so explorer.hush.is/block/HASH works
my $cmd = "mkdir -p $blockdir";
qx{$cmd};
warn $cmd;
my $block_template_file = "/var/www/explorer.hush.land/var/www/explorer.hush.land/block/template.html";
my $new_block_file = "/var/www/explorer.hush.land/var/www/explorer.hush.land/block/$hash/index.html";
# TODO: process template with block details
my $block_template = readfile($block_template_file);
$block_template =~ s/#BLOCKS#/$h/g;
$block_template =~ s/#BLOCKHASH#/$hash/g;
$block_template =~ s/#PREVIOUSBLOCKHASH#/$block->{previousblockhash}/ge;
$block_template =~ s/#BLOCKTIME#/$time/g;
$block_template =~ s/#ANCHOR#/$block->{anchor}/ge;
$block_template =~ s/#VERSION#/$block->{version}/ge;
$block_template =~ s/#BITS#/$block->{bits}/ge;
$block_template =~ s/#BLOCKSIZE#/$block->{size}/ge;
$block_template =~ s/#CHAINWORK#/$block->{chainwork}/ge;
$block_template =~ s/#MERKLEROOT#/$block->{merkleroot}/ge;
$block_template =~ s/#FINALSAPLINGROOT#/$block->{finalsaplingroot}/ge;
# TODO
$block_template =~ s/#BLOCKREWARD#/3.125 HUSH/g;
$block_template =~ s/#BLOCKNONCE#/$block->{nonce}/ge;
$block_template =~ s/#DIFFICULTY#/$block->{difficulty}/ge;
$block_template =~ s/#NUM_TXS#/$numtx/g;
my $txtype = "";
# generate tx list table
$STATS->{TX_TABLE}=<<HTML;
HTML
my $txi = 0;
for my $tx (@txs) {
my $json = qx!$cli getrawtransaction $tx 1!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
# add tx json to Redis, indexed by txid
$r->set("tx:$tx", $json);
my $j = JSON::Any->new;
my $o;
eval {
$o = $j->decode($json);
};
next if $@;
$TX->{$tx} = $o;
my $tx_dir = "$root/var/www/explorer.hush.land/tx/$tx";
my $tx_file = "$root/var/www/explorer.hush.land/tx/$tx/index.html";
my $tx_template_file = "$root/var/www/explorer.hush.land/tx/template.html";
my $tx_template = readfile($tx_template_file);
my $txtime = localtime($o->{time});
#my $txsize = $o->{size} . " bytes";
$tx_template =~ s/#TXID#/$tx/ge;
$tx_template =~ s/#TXTIME#/$txtime/ge;
#$tx_template =~ s/#TXSIZE#/$txsize/g;
$tx_template =~ s/#BLOCKHEIGHT#/$h/ge;
$tx_template =~ s/#BLOCKHASH#/$hash/ge;
my ($vin,$vout,$zin,$zout) = ($o->{vin},$o->{vout},$o->{vShieldedSpend},$o->{vShieldedOutput});
my $expiryheight = $o->{expiryheight} == 0 ? "Default" : $o->{expiryheight};
my $locktime = localtime($o->{locktime});
my $valueBalance = $o->{valueBalance} || "?";
my $valueBalanceSecond = $o->{valueBalance};
my $valueBalanceThird = abs($valueBalanceSecond);
# "vShieldedOutput": [
# {
# "cv": "61e0fed3b97e08e442408c7efc4058a9116695e6e28a22c0fbf0987fdfbcdd27",
# "cmu": "25245041af3bbc5a03da1cd6d60665f7659cbb3bab1080a6e003f856d45998fc",
# "ephemeralKey": "bffefb4f55679610bbdbd43bfba64308842348ba70bb999fad00c67356eab998",
# "encCiphertext": "b685c9d4f6164102999e88e3e30fcca37d9c402fc72533185d495a9d64f1fca277ead03aefe960eeaf102c0c92686a75c792ae8662f40601287ff19635581279d9c9940ba3c29af36166620422c6
#49c4a7ca938734ceecb93a3abc8753ff3535950662ef46d8ed3a0608a61c65be5d0bdb1c262bd63fde759040eef74d4d81619ee154bbabe4fc0e27d82b19c6ed0d4cd806d5bc75ebbb13370ff3f19979ab3b74e859d9b88d3802
#bc7a2ce7ae4305c6beec2146b374bda7234395d0aa390337e69ef5d04eddef0087244292f358b46eeb3c2a5a6d3bd1c89aaa4ebfd8bab58d2d4771b1d106db1a5dcead3b09cfc9fc38b972ce98c53d3cd658b02e58b087c7c73e
#0bd7cb093f2b15ab397094be5bc98f5865045d1845e548249fc811545db1645beb2f044366ba9ae584074e6fa5c03d786757c88ed8eff2d81570d15e64f192707d7393ce40b0f2f767cfbeaa5f05a634fe527da982241c92c4c2
#9642f633115d34fe6791f00c8867e2242485de5f0bb87a8d4e6b375f557db6968f5ecc4f07b838b2dd85dd54e4e9ae2a28e9305bd1a6ae71adf75335d5f44cc046194fdbc91fb80202f06af9431716dc6627b2aa4723b0b8e4bb
#504649b6350ba9f020106d71248227ed8d7a10e2fbcbf64824c8923149822970b3c574614a8c32602106132c1209917974566b2990cf106666f985a2fa1f1409efdc457404700da210906b0f19be61c70d70eddc2f1cbffd94bb
#4c154a332fdd345ad06bd2ac86a339a93eae25db5eb3b4c6090d8483a8e5dd642231d17f3011b2f4b629ef72c08df1eeb6e7d06e",
# "outCiphertext": "53e3865f52101faf3218b60b7d58b9c426dc7c6cff009a8ceddd58031afe9802cae0f423a1085c2b36c776db29b57db8041e9bac42d6b445a0d69eb5a2f0ef61b4790595a68750c60889ff811dce
#8fbb",
# "proof": "82eda0f7de0936f6ca8208e63bda8db9970feb232ae64635e5bea67f16fdbe1b5e5e3a6bb7b7d2f0127c0d17de494834a82e899e8eecdfc71a59de8d1808a53df2989762bd54a855dadc535f2c5107d7b6da
#a732153c4dda4ac965be79ba2ecc030bd58e4c05d5ac7be283b3dc68af8a39231a31cccb54eae65c676760182bd22965f2e1c3685de44c0b93d84519bf138c7942222795dfdd0f683474b7c75221c9355109258805cc038ca43b
#26d5770bf25882326f4f508731b36a8632bc0012"
# }
# ],
my $vins = @$vin;
my $vouts = @$vout;
my $zins = @$zin;
my $zouts = @$zout;
my $coinbase = $vin->[0] ? $vin->[0]->{coinbase}." with sequence ".$vin->[0]->{sequence} : "False"; #($vin->[0] && $vin->[0]->{coinbase}) ? $vin->[0]{coinbase} . " with sequence " . $vin->{sequence} : "False";
# coinbase does not count as a transparent input
$vins-- if ($vin->[0] && $vin->[0]->{coinbase});
my $tx_data =<<DATA;
<tr>
<td style="font-size: 14px; width: 50%">Coinbase: $coinbase</td>
<td style="font-size: 14px; width: 50%">Locktime: $locktime</td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Transparent Inputs: $vins </td>
<td style="font-size: 14px; width: 50%">Transparent Outputs: $vouts </td>
</tr>
<tr>
<td style="font-size: 14px; width: 50%">Shielded Inputs: $zins </td>
<td style="font-size: 14px; width: 50%">Shielded Outputs: $zouts </td>
</tr>
DATA
$tx_template =~ s/#TX_DATA#/$tx_data/g;
my $cmd = "mkdir -p $tx_dir";
warn $cmd;
## create tx dir + page
qx{$cmd};
open(my $fh, '>', $tx_file) or die "$tx_file: $!";
print $fh $tx_template;
close $fh or die $!;
## create tx view on block page
my $from = $o->{vin}->[0] ? $o->{vin}->[0]->{address} : "zs1???";
#my $to = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "zs1???";
my $to2 = "";
my $to3 = "";
# only look at coinbase tx's
if($txi == 0) {
# LEXICAL SCOPING BUG, MAN!
$mineraddress = $o->{vout}->[0] ? $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0] : "";
$thisminer = $mineraddress;
}
# say "<!-- miner for $tx is $mineraddress -->";
my $to = $mineraddress ? $mineraddress : "zs1???";
if($o->{vout}->[1]) {
$to2 = $o->{vout}->[1]->{scriptPubKey}->{addresses}->[0];
}
if($o->{vout}->[0]) {
$to3 = $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0];
}
$valueBalance = ($o->{vout}->[0]->{value} || 0) + ($o->{vout}->[1]->{value} || 0);
$valueBalance ||= "?";
$from ||= "";
$txtype = "Mining";
if($zins+$zouts>0) {
$txtype = "Shielded";
if($zins==0 && $zouts>0) { $txtype = "Shielding"; }
if($vins==0 && $vouts==1 && $zins==1 && $zouts==8){ $txtype = "Notary" }
if($vins==1 && $vouts==14 && $zins==0 && $zouts==0){ $txtype = "dPoW" }
if($vins==0 && $vouts==0){ $txtype = "Fully Shielded" }
# this is prevented by consensus rule on HUSH mainnet
# but if we see it, ring the bell, lulz
if($zins>0 && $zouts==0) { $txtype = "De-Shielding!"; }
}
#if($vouts>0) { $txtype = "DPoW"; }
my $stuff;
if ($txtype eq "Mining") {
$stuff =<<STUFF;
=> $to (miner)
<br>
=> $to2 (FR address)
STUFF
} elsif ($txtype eq "Shielding") {
$stuff =<<STUFF;
$from ($valueBalanceThird HUSH) => zs1??? (shielding)
STUFF
} elsif ($txtype eq "Notary") {
$stuff =<<STUFF;
zs1??? => $to3 (notary)
<br>
zs1??? => zs1??? (shielded change)
STUFF
} elsif ($txtype eq "dPoW") {
$stuff =<<STUFF;
=> $to2 (FR address)
<br>
=> $to2 (notary)
STUFF
} else {
$stuff =<<STUFF;
$from => zs1??? (fully shielded)
STUFF
}
my $tx_table = <<HTML;
<table>
<tr>
<td style="font-size: 14px"><a href="/tx/$tx" class="mainlinkexplorer">$tx</a></td>
<td style="font-size: 14px">vins: $vins, vouts: $vouts</td>
<td style="font-size: 14px">zins: $zins, zouts: $zouts</td>
</tr>
<tr>
<td style="font-size: 14px">$stuff</td>
<td style="font-size: 14px">$txtime</td>
<td style="font-size: 14px">$valueBalance HUSH</td>
</tr>
</table>
HTML
$STATS->{TX_TABLE} .= $tx_table;
$txi++;
}
# $STATS->{TX_TABLE} .= "</table>";
# $STATS->{TX_TABLE} .= "<pre>" . Dumper [ $vin ];''
$block_template =~ s/#TX_TABLE#/$STATS->{TX_TABLE}/ge;
# > ?
open(my $fh, '>>', $new_block_file) or die "$new_block_file: $!";
print $fh $block_template;
close $fh or die $!;
warn "wrote to $new_block_file ";
} else {
warn "block exists on disk, looking info up";
#TODO: error-checking for corrupt data
#warn Dumper $block;
my $lookuptx = $block->{tx}->[0];
my $o = get_raw($lookuptx);
$thisminer = $o->{vout}->[0]->{scriptPubKey}->{addresses}->[0];
warn "thisminer=$thisminer";
}
my $blockduration = 0;
if($#blocks >= 0) {
$blockduration = $time - $blocks[$#blocks]->[3];
}
# give data to blocks after we have processed everything
my $b = [ $h, $hash, $reward,$time,$numtx,$thisminer, $blockduration ];
#warn Dumper $b;
push @blocks, $b;
;
}
sub get_raw {
my $tx = shift;
my $cmd = "$cli getrawtransaction $tx 1";
warn $cmd;
my $json = qx!$cmd!;
# "vout": 0,
# "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj",
# address is duplicated in the JSON of getrawtransaction !! fuck.
# KMD or ZEC upstream bug?
$json =~ s/"vout": 0,\w*"address": "([a-z0-9]+)",/"vout": 0,/mg;
# Satoshi Forgive Me
$json =~ s/"address":\w+"([a-z0-9]+)"(.+)"address":\w+"\g1"(.+)/"address": "$1"$2/mg;
warn "decoding tx=$tx"; # with json=$json";
my $j = JSON::Any->new;
my $o = $j->decode($json);
return $o;
}
# render data
for my $b (reverse @blocks) {
my ($height,$hash,$reward,$time,$txs,$miner,$duration) = @$b;
$time = localtime($time);
# we can't calc the duration of the first block we look at, yet
$duration = "--" unless $duration;
$STATS->{BLOCKS_TABLE} .= <<"FUCK";
<table>
<tr>
<td style="font-size: 14px"><a href="/block/$height/" class="mainlinkexplorer">$height</a></td>
<td style="font-size: 14px"><a href="/block/$hash/" class="mainlinkexplorer">$hash</a></td>
<td style="font-size: 14px">$time</td>
</tr>
<tr>
<td style="font-size: 14px">${duration}s</td>
<td style="font-size: 14px">$miner + $reward</td>
<td style="font-size: 14px">Transactions: $txs</td>
</tr>
</table>
FUCK
}
for my $s (@symbols) {
if($s && $STATS->{$s}) { $template =~ s/#$s#/$STATS->{$s}/ge }
}
# derived stat
#my $zpct = sprintf "%.3f", $STATS->{SUPPLY} > 0 ? 100*($STATS->{ZFUNDS}/$STATS->{SUPPLY}) : "0.000";
#$template =~ s/#ZFUNDS_PERCENT#/$zpct/ge;
say $template;
###### functions
# get block at given height
sub get_block {
my $height = shift;
return if $height < 0;
my $block = $r->get("block:$height") || '';
# create data if it's not there
if( $block =~ m/^HASH/ || length($block) == 0 ) {
my $cmd = "$cli getblock $height";
warn $cmd;
$block = qx/$cmd/;
}
my $json = $block;
if($json) {
$block = $j->decode($json);
# cache in Redis
warn Dumper [ "redis set block:$height =>", $json ];
$r->set("block:$height",$json);
} else {
warn "empty block $height!!" unless $json;
warn Dumper [$json];
}
return $block;
}
sub readfile {
my $file = shift;
my $data = "";
open(my $fh, '<', $file) or die "$file: $!";
my $txlist = 0;
while(<$fh>){
$data.=$_
}
close($fh);
return $data;
}

23
var/www/explorer.hush.land/crons/README

@ -0,0 +1,23 @@
# cron jobs to run explorer
```
# m h dom mon dow command
*/7 * * * * ./update_explorer_data.sh
*/5 * * * * ./update_api.sh
#*/7 * * * * ./hush_cron.sh
# restart hushd every 4 hours
# start it if it's not running
20 */4 * * * ./restart-hushd.sh
*/10 * * * * /var/www/explorer.hush.land/update.sh
```
Restarting hushd used to be needed before the LOCK bug fixed in dev (which will be in 3.9.1), so
that is optional if you are using the latest code.
The times the cronjobs run are specifically chosen to try and run in a specific order, since
the output of one cron is used in another.

13
var/www/explorer.hush.land/update_api.sh

@ -0,0 +1,13 @@
#!/bin/bash
DIR=/var/www/explorer.hush.land/var/www/explorer.hush.land/api
# TODO: remove IP info from getpeerinfo
#~/git/hush3/src/hush-cli getpeerinfo > $DIR/getpeerinfo.json
~/git/hush3/src/hush-cli getinfo &> $DIR/getinfo.json
~/git/hush3/src/hush-cli getmininginfo &> $DIR/getmininginfo.json
~/git/hush3/src/hush-cli getblockchaininfo &> $DIR/getblockchain.json
~/git/hush3/src/hush-cli getchaintxstats &> $DIR/getchaintxstats.json
~/git/hush3/src/hush-cli gettxoutsetinfo &> $DIR/gettxoutsetinfo.json
~/git/hush3/src/hush-cli coinsupply &> $DIR/coinsupply.json
~/git/hush3/src/hush-cli getchaintips &> $DIR/getchaintips.json
~/git/hush3/src/hush-cli getchaintxstats &> $DIR/getchaintxstats.json

18
var/www/explorer.hush.land/update_explorer_data.sh

@ -0,0 +1,18 @@
#!/bin/bash
cli=~/git/hush3/src/hush-cli
# only ask for data if we don't have it
#if [ -s ~/data/blocks/block-$HEIGHT.json ]; then
# HEIGHT=$($cli getblockcount); $cli getblock $HEIGHT > ~/data/blocks/block-$HEIGHT.json
#fi
NEWFILE=/var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/index.new.html
INDEXFILE=/var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/index.html
# reads data from /var/www/explorer.hush.is/api
#~/git/explorer.hush.is/bin/update_blocks.pl > $NEWFILE
/var/www/explorer.hush.land/bin/update_blocks_redis.pl > $NEWFILE
if [ -s $NEWFILE ]; then
cp $NEWFILE $INDEXFILE
fi

12
var/www/explorer.hush.land/var/www/explorer.hush.land/PID

@ -0,0 +1,12 @@
226212
226355
226361
226664
227090
227309
227738
227933
228039
228062
228077
228090

84
var/www/explorer.hush.land/var/www/explorer.hush.land/address/template.html

@ -0,0 +1,84 @@
<!DOCTYPE html>
<html>
<head>
<title>Hush Explorer: Speak And Transact Freely</title>
<style>
body {
width: 95%;
margin: 5 auto;
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
background: #111111;
color: #cccccc;
}
a:link { color: #888888; }
a:visited { color: #888888; }
a:hover { color: #554200; }
a:active { color: #550000; }
</style>
<!--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{ Fuck Blockchain Analysts }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\ ^__^
\ (@@)\_______
(__)\ )\/\
||----w |
|| ||
- Duke Leto and The Hush Developers
-->
</head>
<body>
<center>
<br/>
<br/>
<a href="https://hush.is">Hush</a> | <a href="https://explorer.hush.is">Explorer</a>
| <a href="https://hush.is/twitter">Twitter</a> | <a href="https://hush.is/tg">Telegram</a> |
<a href="https://hush.is/telegram_support">Telegram Support</a> | <a href="https://hush.is/telegram_mining">Telegram Mining</a>
| <a href="https://hush.is/reddit">Reddit</a> | <a href="https://hush.is/youtube">YouTube</a>
| <a href="https://hush.is/bitcointalk">BitcoinTalk</a> | <a href="https://hush.is/mastodon">Mastodon</a>
| <a href="https://hush.is/matrix">Matrix</a>
<br/>
<h1>HUSH Blockchain Explorer</h1>
<div id=navbar>
<a href="/blocks/">Blocks</a>
</div>
<div id=stats>
<table width="100%" border=1>
<tr>
<td align=center>
<table>
<tr><th>Address</th><td><a href="/address/#ADDRESS#">#ADDRESS#</a></td></tr>
<tr><th>Transactions</th><td>#TXS#</td></tr>
</table>
</td>
</tr>
<tr>
<td align=center>
#ADDRESS_DATA#
</td>
</tr>
</table>
</div>
<br>
</center>
<font color=red>
<pre>
_____________
< Extreme!!!! >
-------------
\ ^__^
\ (@@)\_______
(__)\ )\/\
||----w |
|| ||
</pre>
</font>
</body>
</html>

78
var/www/explorer.hush.land/var/www/explorer.hush.land/addresses/template.html

@ -0,0 +1,78 @@
<!doctype html>
<head>
<title>Home | Hush - Transact and Speak Freely</title>
<style>
body { background-color: #101010; max-width: 850px; margin: auto; font-family: 'Ubuntu Mono'; color: #b3b3b3; text-align: center }
table { width: 100%; border-collapse: collapse; margin-top: 15px }
td { border: 1px solid #1a1a1a; font-size: 16px; padding: 0.5em }
td:hover { background-color: #1a1a1a }
pre { background-color: #0d0d0d; border: 1px solid #1a1a1a; font-size: 6px; padding: 15px; color: #e6e6e6 }
details { cursor: pointer; background-color: #0d0d0d; text-align: left; margin-top: 15px; padding: 0.5em; border: 1px solid #1a1a1a; font-size: 13px; word-wrap: break-word }
summary { outline: none; padding: 0.4em }
.blockt { border: 1px solid #1a1a1a; padding: 0.15em; background-color: #0d0d0d; margin-top: 15px; text-align: left; font-size: 13px; word-wrap: break-word }
.blockt p { padding-left: 0.7em; padding-right: 0.7em }
.button:link { float: right; font-size: 11px }
.mainlinkexplorer:link { text-decoration: dotted underline; text-underline-position: under }
.mainlinkexplorer:hover { text-decoration: none; color: #595959 }
.links { margin: 15px; font-size: 13px }
a:link { color: #b3b3b3; text-decoration: none }
a:visited { color: #b3b3b3 }
a:hover { color: #b3b3b3 }
* { scrollbar-width: thin; scrollbar-color: #333333 #101010 }
::-webkit-scrollbar { width: 6px }
::-webkit-scrollbar-thumb { background: #333333 }
@font-face { font-family: 'Ubuntu Mono'; src: url('../UbuntuMono.ttf') format('truetype') }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>Hush - Speak and Transact Freely</h2>
<h3>Private Cryptocurrency and Messenger using Zero Knowledge Mathematics</h3>
<pre>
&&&&
&&&& &&&&&& &&&&
&&&&&& &&&&&& &&&&&&
&&& &&&&&& &&&& &&&&&& &&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&& &&&&&
&&&&& &&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&
&&&&& &&&& &&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&& &&&&&& && && &&&&&& &&&
&&&&&& &&&&&& &&&&&&
&&&& &&&&&& &&&&
&&&&&&
&&&& <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="button">.onion</a>
</pre>
<table>
<tr>
<td><a href="https://hush.land">Why Hush</a></td>
<td><a href="https://hush.land/hushchat.html">HushChat</a></td>
<td><a href="https://hushpool.is">HushPool</a></td>
<td><a href="https://git.hush.is/onryo/hush-box">HushBox</a></td>
</tr>
<tr>
<td><a href="https://explorer.hush.land">Explorer</a></td>
<td><a href="https://git.hush.is/hush">Gitea</a></td>
<td><a href="https://hush.land/faq.html">F.A.Q</a></td>
<td><a href="https://hush.land/team.html">Team</a></td>
</tr>
</table>
<div class="blockt"><p>These addresses have NO PRIVACY! They really should move funds to a zaddr!</p></div>
#ADDRESS_DATA#
<div class="links">
<a href="https://hush.is/matrix"><span style="color: #262626">[</span> matrix <span style="color: #262626">]</span></a>
<a href="https://hush.is/mastodon"><span style="color: #262626">[</span> mastodon <span style="color: #262626">]</span></a>
<a href="https://videos.hush.is"><span style="color: #262626">[</span> peertube <span style="color: #262626">]</span></a>
<a href="https://t.me/hush_main"><span style="color: #262626">[</span> telegram <span style="color: #262626">]</span></a>
</div>
</body>
</html>

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/anonset.json

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/coinsupply.json

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/getblockchain.json

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/getchaintips.json

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/getchaintxstats.json

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/getinfo.json

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/getmininginfo.json

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/gettxoutsetinfo.json

1
var/www/explorer.hush.land/var/www/explorer.hush.land/api/index.html

@ -0,0 +1 @@
Hush Explorer API

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/snapshots/snapshot-old.json

0
var/www/explorer.hush.land/var/www/explorer.hush.land/api/snapshots/snapshot.json

101
var/www/explorer.hush.land/var/www/explorer.hush.land/block/template.html

@ -0,0 +1,101 @@
<!doctype html>
<head>
<title>Home | Hush - Transact and Speak Freely</title>
<style>
body { background-color: #101010; max-width: 850px; margin: auto; font-family: 'Ubuntu Mono'; color: #b3b3b3; text-align: center }
table { width: 100%; border-collapse: collapse; margin-top: 15px }
td { border: 1px solid #1a1a1a; font-size: 16px; padding: 0.5em }
td:hover { background-color: #1a1a1a }
pre { background-color: #0d0d0d; border: 1px solid #1a1a1a; font-size: 6px; padding: 15px; color: #e6e6e6 }
details { cursor: pointer; background-color: #0d0d0d; text-align: left; margin-top: 15px; padding: 0.5em; border: 1px solid #1a1a1a; font-size: 13px; word-wrap: break-word }
summary { outline: none; padding: 0.4em }
.blockt { border: 1px solid #1a1a1a; padding: 0.15em; background-color: #0d0d0d; margin-top: 15px; text-align: left; font-size: 13px; word-wrap: break-word }
.blockt p { padding-left: 0.7em; padding-right: 0.7em }
.button:link { float: right; font-size: 11px }
.mainlinkexplorer:link { text-decoration: dotted underline; text-underline-position: under }
.mainlinkexplorer:hover { text-decoration: none; color: #595959 }
.links { margin: 15px; font-size: 13px }
a:link { color: #b3b3b3; text-decoration: none }
a:visited { color: #b3b3b3 }
a:hover { color: #b3b3b3 }
* { scrollbar-width: thin; scrollbar-color: #333333 #101010 }
::-webkit-scrollbar { width: 6px }
::-webkit-scrollbar-thumb { background: #333333 }
@font-face { font-family: 'Ubuntu Mono'; src: url('../../UbuntuMono.ttf') format('truetype') }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>Hush - Speak and Transact Freely</h2>
<h3>Private Cryptocurrency and Messenger using Zero Knowledge Mathematics</h3>
<pre>
&&&&
&&&& &&&&&& &&&&
&&&&&& &&&&&& &&&&&&
&&& &&&&&& &&&& &&&&&& &&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&& &&&&&
&&&&& &&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&
&&&&& &&&& &&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&& &&&&&& && && &&&&&& &&&
&&&&&& &&&&&& &&&&&&
&&&& &&&&&& &&&&
&&&&&&
&&&& <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="button">.onion</a>
</pre>
<table>
<tr>
<td><a href="https://hush.land">Why Hush</a></td>
<td><a href="https://hush.land/hushchat.html">HushChat</a></td>
<td><a href="https://hushpool.is">HushPool</a></td>
<td><a href="https://git.hush.is/onryo/hush-box">HushBox</a></td>
</tr>
<tr>
<td><a href="https://explorer.hush.land">Explorer</a></td>
<td><a href="https://git.hush.is/hush">Gitea</a></td>
<td><a href="https://hush.land/faq.html">F.A.Q</a></td>
<td><a href="https://hush.land/team.html">Team</a></td>
</tr>
</table>
<table>
<tr><td style="font-size: 14px"><a href="/block/#BLOCKS#" class="mainlinkexplorer">Block Height: #BLOCKS#</a></td></tr>
<tr><td style="font-size: 14px"><a href="/block/#BLOCKHASH#" class="mainlinkexplorer">Block Hash: #BLOCKHASH#</a></td></tr>
<tr><td style="font-size: 14px"><a href="/block/#PREVIOUSBLOCKHASH#" class="mainlinkexplorer">Previous Block Hash: #PREVIOUSBLOCKHASH#</a></td></tr>
</table>
<table>
<tr>
<td style="font-size: 14px">Block Reward: #BLOCKREWARD#</td>
<td style="font-size: 14px">Block Time: #BLOCKTIME#</td>
<td style="font-size: 14px">Block Difficulty: #DIFFICULTY#</td>
</tr>
<tr>
<td style="font-size: 14px">Block size: #BLOCKSIZE# bytes</td>
<td style="font-size: 14px">Block Version: #VERSION#</td>
<td style="font-size: 14px">Block Bits: #BITS#</td>
</tr>
</table>
<table>
<tr><td style="font-size: 14px">Block Nonce: #BLOCKNONCE#</td></tr>
<tr><td style="font-size: 14px">Block Anchor: #ANCHOR#</td></tr>
<tr><td style="font-size: 14px">Chainwork: #CHAINWORK#</td></tr>
<tr><td style="font-size: 14px">Merkle Root: #MERKLEROOT#</td></tr>
<tr><td style="font-size: 14px">Final Sapling Root: #FINALSAPLINGROOT#</td></tr>
</table>
#TX_TABLE#
<div class="links">
<a href="https://hush.is/matrix"><span style="color: #262626">[</span> matrix <span style="color: #262626">]</span></a>
<a href="https://hush.is/mastodon"><span style="color: #262626">[</span> mastodon <span style="color: #262626">]</span></a>
<a href="https://videos.hush.is"><span style="color: #262626">[</span> peertube <span style="color: #262626">]</span></a>
<a href="https://t.me/hush_main"><span style="color: #262626">[</span> telegram <span style="color: #262626">]</span></a>
</div>
</body>
</html>

77
var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/template.html

@ -0,0 +1,77 @@
<!doctype html>
<head>
<title>Home | Hush - Transact and Speak Freely</title>
<style>
body { background-color: #101010; max-width: 850px; margin: auto; font-family: 'Ubuntu Mono'; color: #b3b3b3; text-align: center }
table { width: 100%; border-collapse: collapse; margin-top: 15px }
td { border: 1px solid #1a1a1a; font-size: 16px; padding: 0.5em }
td:hover { background-color: #1a1a1a }
pre { background-color: #0d0d0d; border: 1px solid #1a1a1a; font-size: 6px; padding: 15px; color: #e6e6e6 }
details { cursor: pointer; background-color: #0d0d0d; text-align: left; margin-top: 15px; padding: 0.5em; border: 1px solid #1a1a1a; font-size: 13px; word-wrap: break-word }
summary { outline: none; padding: 0.4em }
.blockt { border: 1px solid #1a1a1a; padding: 0.15em; background-color: #0d0d0d; margin-top: 15px; text-align: left; font-size: 13px; word-wrap: break-word }
.blockt p { padding-left: 0.7em; padding-right: 0.7em }
.button:link { float: right; font-size: 11px }
.mainlinkexplorer:link { text-decoration: dotted underline; text-underline-position: under }
.mainlinkexplorer:hover { text-decoration: none; color: #595959 }
.links { margin: 15px; font-size: 13px }
a:link { color: #b3b3b3; text-decoration: none }
a:visited { color: #b3b3b3 }
a:hover { color: #b3b3b3 }
* { scrollbar-width: thin; scrollbar-color: #333333 #101010 }
::-webkit-scrollbar { width: 6px }
::-webkit-scrollbar-thumb { background: #333333 }
@font-face { font-family: 'Ubuntu Mono'; src: url('../UbuntuMono.ttf') format('truetype') }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>Hush - Speak and Transact Freely</h2>
<h3>Private Cryptocurrency and Messenger using Zero Knowledge Mathematics</h3>
<pre>
&&&&
&&&& &&&&&& &&&&
&&&&&& &&&&&& &&&&&&
&&& &&&&&& &&&& &&&&&& &&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&& &&&&&
&&&&& &&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&
&&&&& &&&& &&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&& &&&&&& && && &&&&&& &&&
&&&&&& &&&&&& &&&&&&
&&&& &&&&&& &&&&
&&&&&&
&&&& <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="button">.onion</a>
</pre>
<table>
<tr>
<td><a href="https://hush.land">Why Hush</a></td>
<td><a href="https://hush.land/hushchat.html">HushChat</a></td>
<td><a href="https://hushpool.is">HushPool</a></td>
<td><a href="https://git.hush.is/onryo/hush-box">HushBox</a></td>
</tr>
<tr>
<td><a href="https://explorer.hush.land">Explorer</a></td>
<td><a href="https://git.hush.is/hush">Gitea</a></td>
<td><a href="https://hush.land/faq.html">F.A.Q</a></td>
<td><a href="https://hush.land/team.html">Team</a></td>
</tr>
</table>
#BLOCKS_TABLE#
<div class="links">
<a href="https://hush.is/matrix"><span style="color: #262626">[</span> matrix <span style="color: #262626">]</span></a>
<a href="https://hush.is/mastodon"><span style="color: #262626">[</span> mastodon <span style="color: #262626">]</span></a>
<a href="https://videos.hush.is"><span style="color: #262626">[</span> peertube <span style="color: #262626">]</span></a>
<a href="https://t.me/hush_main"><span style="color: #262626">[</span> telegram <span style="color: #262626">]</span></a>
</div>
</body>
</html>

125
var/www/explorer.hush.land/var/www/explorer.hush.land/index-1.html

@ -0,0 +1,125 @@
<!doctype html>
<head>
<title>Home | Hush - Transact and Speak Freely</title>
<style>
body { background-color: #101010; max-width: 850px; margin: auto; font-family: 'Ubuntu Mono'; color: #b3b3b3; text-align: center }
table { width: 100%; border-collapse: collapse; margin-top: 15px }
td { border: 1px solid #1a1a1a; font-size: 16px; padding: 0.5em }
td:hover { background-color: #1a1a1a }
pre { background-color: #0d0d0d; border: 1px solid #1a1a1a; font-size: 6px; padding: 15px; color: #e6e6e6 }
details { cursor: pointer; background-color: #0d0d0d; text-align: left; margin-top: 15px; padding: 0.5em; border: 1px solid #1a1a1a; font-size: 13px; word-wrap: break-word }
summary { outline: none; padding: 0.4em }
.blockt { border: 1px solid #1a1a1a; padding: 0.15em; background-color: #0d0d0d; margin-top: 15px; text-align: left; font-size: 13px; word-wrap: break-word }
.blockt p { padding-left: 0.7em; padding-right: 0.7em }
.button:link { float: right; font-size: 11px }
.mainlink:link { text-decoration: dotted underline; text-underline-position: under }
.mainlink:hover { text-decoration: none; color: #595959 }
.mainlinkexplorer:link { text-decoration: dotted underline; text-underline-position: under }
.mainlinkexplorer:hover { text-decoration: none; color: #595959 }
.links { margin: 15px; font-size: 13px }
a:link { color: #b3b3b3; text-decoration: none }
a:visited { color: #b3b3b3 }
a:hover { color: #b3b3b3 }
* { scrollbar-width: thin; scrollbar-color: #333333 #101010 }
::-webkit-scrollbar { width: 6px }
::-webkit-scrollbar-thumb { background: #333333 }
@font-face { font-family: 'Ubuntu Mono'; src: url('UbuntuMono.ttf') format('truetype') }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>Hush - Speak and Transact Freely</h2>
<h3>Private Cryptocurrency and Messenger using Zero Knowledge Mathematics</h3>
<pre>
&&&&
&&&& &&&&&& &&&&
&&&&&& &&&&&& &&&&&&
&&& &&&&&& &&&& &&&&&& &&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&& &&&&&
&&&&& &&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&
&&&&& &&&& &&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&& &&&&&& && && &&&&&& &&&
&&&&&& &&&&&& &&&&&&
&&&& &&&&&& &&&&
&&&&&&
&&&& <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="button">.onion</a>
</pre>
<table>
<tr>
<td><a href="https://hush.land">Why Hush</a></td>
<td><a href="https://hush.land/hushchat.html">HushChat</a></td>
<td><a href="https://hushpool.is">HushPool</a></td>
<td><a href="https://git.hush.is/onryo/hush-box">HushBox</a></td>
</tr>
<tr>
<td><a href="https://explorer.hush.land">Explorer</a></td>
<td><a href="https://git.hush.is/hush">Gitea</a></td>
<td><a href="https://hush.land/faq.html">F.A.Q</a></td>
<td><a href="https://hush.land/team.html">Team</a></td>
</tr>
</table>
<div class="blockt"><p>This is the most private and secure Blockchain Explorer in Zcash World, inspiration goes to <a href="https://xmrchain.net" class="mainlink">xmrchain.net</a>! There is no Javascript both client or server-side, it has no cookies, web analytics trackers, no images, no external CSS, visited and unvisited links are the same color so screenshots do not leak metadata, likewise it is available as a <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="mainlink">Tor hidden service</a>.</p></div>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Thu Sep 29 17:23:39 2022<!-- 1664472219 --></td>
<td style="font-size: 14px; width: 50%"><a href="/blocks/" class="mainlinkexplorer">Blocks list</a></td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%"><a href="/blocks/" class="mainlinkexplorer">Block Height: 1099008 </a></td>
<td style="font-size: 14px; width: 50%"><a href="https://git.hush.is/hush/anonsets" class="mainlinkexplorer">Anonymity Set</a>:<span class='anonset'> 2410752 </span></td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Total Transactions: 1810407</td>
<td style="font-size: 14px; width: 50%">Transaction Rate: 2.1093 per minute </td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Hashrate: 11.19 MSol/s</td>
<td style="font-size: 14px; width: 50%">Difficulty: 49283696</td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Circulating Supply: 12798895.34523515 HUSH</td>
<td style="font-size: 14px; width: 50%">Shielded Supply: 6850551.72538454 HUSH</td>
</tr>
</table>
<table>
<td style="font-size: 14px; width: 50%">Price:<span class='price'> 0.00000273 BTC</span></td>
<td style="font-size: 14px; width: 50%">Total Volume:<span class='volume'> .0077033708 BTC </span></td>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Percent Shielded: 53.525 </td>
<td style="font-size: 14px; width: 50%"><a href="/addresses/" class="mainlinkexplorer">T-addresses list</a></td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">29 peers connected via TLS 1.3</td>
<td style="font-size: 14px; width: 50%">Protocol Version: 1987424</td>
</tr>
</table>
<div class="links">
<a href="https://hush.is/matrix"><span style="color: #262626">[</span> matrix <span style="color: #262626">]</span></a>
<a href="https://hush.is/mastodon"><span style="color: #262626">[</span> mastodon <span style="color: #262626">]</span></a>
<a href="https://videos.hush.is"><span style="color: #262626">[</span> peertube <span style="color: #262626">]</span></a>
<a href="https://t.me/hush_main"><span style="color: #262626">[</span> telegram <span style="color: #262626">]</span></a>
</div>
</body>
</html>

1
var/www/explorer.hush.land/var/www/explorer.hush.land/index-new.html

@ -0,0 +1 @@
No such file or directory at /var/www/explorer.hush.land/bin/update.pl line 47.

142
var/www/explorer.hush.land/var/www/explorer.hush.land/index-prev.html

@ -0,0 +1,142 @@
<!DOCTYPE html>
<html>
<head>
<title>Hush Explorer: Speak And Transact Freely</title>
<style>
body {
width: 87%;
margin: 5 auto;
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
background: #111111;
color: #cccccc;
}
a:link { color: #888888; }
a:visited { color: #888888; }
a:hover { color: #554200; }
a:active { color: #550000; }
</style>
<!--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{ Fuck Blockchain Analysts }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\ ^__^
\ (@@)\_______
(__)\ )\/\
||----w |
|| ||
- Duke Leto and The Hush Developers
-->
<!-- this explorer must be hosted at / or this needs to be changed.
Not specifying a hostname makes it compatible with Tor/i2p/etc and other mirrors
- Duke
-->
<meta http-equiv="refresh" content="120; URL=/">
</head>
<body>
<center>
<br/>
<br/>
<a href="https://hush.is">Hush</a>
|
<a href="https://explorer.hush.is">Explorer</a>
|
<a href="https://hush.is/twitter">Twitter</a>
|
<a href="https://hush.is/tg">Telegram</a>
|
<a href="https://hush.is/telegram_support">Telegram Support</a>
|
<a href="https://hush.is/telegram_mining">Telegram Mining</a>
|
<a href="https://hush.is/reddit">Reddit</a>
|
<a href="https://hush.is/youtube">YouTube</a>
|
<a href="https://hush.is/bitcointalk">BitcoinTalk</a>
|
<a href="https://hush.is/mastodon">Mastodon</a>
|
<a href="https://hush.is/matrix">Matrix</a>
<br/>
<h1>HUSH Blockchain Explorer</h1>
<div id=navbar>
<a href="/blocks/">Blocks</a> |
<a href="/addresses/">Addresses</a>
</div>
<div id=stats>
<table width="100%" border=1>
<tr>
<td align=center>
<table>
<tr><th>Block Height</th><td><a href="/block/00000007235bcfad2de9c91c13a895263644b362a50efa0e9d91d79ccffcf13b">798463</a></td></tr>
<tr><th>Block Hash</th><td><a href="/block/00000007235bcfad2de9c91c13a895263644b362a50efa0e9d91d79ccffcf13b">00000007235bcfad2de9c91c13a895263644b362a50efa0e9d91d79ccffcf13b</a></td></tr>
<!-- <tr><th>Notarized Height</th><td><a href="/block/#NOTARIZED#">#NOTARIZED#</a></td></tr> -->
<!-- <tr><th>Notarized Hash</th><td><a href="/block/0000000000000000000000000000000000000000000000000000000000000000"> 0000000000000000000000000000000000000000000000000000000000000000</a></td></tr> -->
<tr><th>Longest Chain</th><td><a href="/block/798463">798463</a></td></tr>
<tr><th>Chain Tip Time</th><td> <font size=small>Mon Jan 10 14:56:50 2022<!-- 1641826610 --></font></td></tr>
<tr><th>Total Transactions</th><td> 1237062</td></tr>
<tr><th>Transaction Rate</th><td> 0.9788 per minute (Monthly Avg)</td></tr>
<!--<tr><th>Transactions Per Day</th><td> #TXS_PER_DAY#</td></tr> -->
<tr><th>Difficulty</th><td> 10543947</td></tr>
<tr><th>Network Solution Rate (Hashrate)</th><td> 2.44 MegaSols/s</td></tr>
<tr><th>Circulating Supply</th><td> 11859692.58202515 <b>HUSH</b></td></tr>
<tr><th>Shielded Supply</th><td> 5773652.68191908 <b>HUSH</b></td></tr>
<tr><th>Percent Shielded</th><td> 48.683 %</td></tr>
</table>
</td>
</tr>
</table>
</div>
<br>
<h2>About This Extreme Explorer</h2>
</center>
<p>
<ul>
<li>No Cookies</li>
<li>No Javascript client-side or server-side</li>
<li>No web analytics trackers</li>
<li>No images (<a href="https://en.wikipedia.org/wiki/Web_beacon">web bugs</a>)</li>
<li>No external CSS, only a few lines of inline per page</li>
<li>Visited/unvisited links are the same color so screenshots do not leak metadata</li>
<li>Tor Hidden Service Coming Soon</li>
</ul>
This Explorer doesn't snoop on your privacy! There is no Javascript or images for that reason.
Either could be used to steal your privacy. This explorer is natively compatible with Tor, i2p
and any other technology that improves privacy, because we do not use or rely on Javascript
IN ANY WAY, on the server-side or the client-side.
</p>
<p>
We beleive this is the most private and secure Blockchain Explorer in Zcash Protocol World.
Inspiration goes to <a href="https://xmrchain.net">xmrchain.net</a> and their fascinating
C++ <a href="https://github.com/moneroexamples/onion-monero-blockchain-explorer">codebase</a>.
Hush continues to "lovingly steal" the best ideas of Monero World and apply them to Zcash World,
which is why we claim to have the most advanced tech of any privacy coin.
</p>
<p>
The code to this explorer is still under development and will be released in due time.
</p>
<center>
<h3>Node Stats</h3>
<table border=1>
<tr><td>
11 of 11 peers connected via <font color=green>TLS 1.3</font>
</td></tr>
<tr><td>
Protocol Version <font color=orange>1987424</font>
</td></tr>
</center>
</body>
</html>

125
var/www/explorer.hush.land/var/www/explorer.hush.land/index.html

@ -0,0 +1,125 @@
<!doctype html>
<head>
<title>Home | Hush - Transact and Speak Freely</title>
<style>
body { background-color: #101010; max-width: 850px; margin: auto; font-family: 'Ubuntu Mono'; color: #b3b3b3; text-align: center }
table { width: 100%; border-collapse: collapse; margin-top: 15px }
td { border: 1px solid #1a1a1a; font-size: 16px; padding: 0.5em }
td:hover { background-color: #1a1a1a }
pre { background-color: #0d0d0d; border: 1px solid #1a1a1a; font-size: 6px; padding: 15px; color: #e6e6e6 }
details { cursor: pointer; background-color: #0d0d0d; text-align: left; margin-top: 15px; padding: 0.5em; border: 1px solid #1a1a1a; font-size: 13px; word-wrap: break-word }
summary { outline: none; padding: 0.4em }
.blockt { border: 1px solid #1a1a1a; padding: 0.15em; background-color: #0d0d0d; margin-top: 15px; text-align: left; font-size: 13px; word-wrap: break-word }
.blockt p { padding-left: 0.7em; padding-right: 0.7em }
.button:link { float: right; font-size: 11px }
.mainlink:link { text-decoration: dotted underline; text-underline-position: under }
.mainlink:hover { text-decoration: none; color: #595959 }
.mainlinkexplorer:link { text-decoration: dotted underline; text-underline-position: under }
.mainlinkexplorer:hover { text-decoration: none; color: #595959 }
.links { margin: 15px; font-size: 13px }
a:link { color: #b3b3b3; text-decoration: none }
a:visited { color: #b3b3b3 }
a:hover { color: #b3b3b3 }
* { scrollbar-width: thin; scrollbar-color: #333333 #101010 }
::-webkit-scrollbar { width: 6px }
::-webkit-scrollbar-thumb { background: #333333 }
@font-face { font-family: 'Ubuntu Mono'; src: url('UbuntuMono.ttf') format('truetype') }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>Hush - Speak and Transact Freely</h2>
<h3>Private Cryptocurrency and Messenger using Zero Knowledge Mathematics</h3>
<pre>
&&&&
&&&& &&&&&& &&&&
&&&&&& &&&&&& &&&&&&
&&& &&&&&& &&&& &&&&&& &&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&& &&&&&
&&&&& &&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&
&&&&& &&&& &&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&& &&&&&& && && &&&&&& &&&
&&&&&& &&&&&& &&&&&&
&&&& &&&&&& &&&&
&&&&&&
&&&& <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="button">.onion</a>
</pre>
<table>
<tr>
<td><a href="https://hush.land">Why Hush</a></td>
<td><a href="https://hush.land/hushchat.html">HushChat</a></td>
<td><a href="https://hushpool.is">HushPool</a></td>
<td><a href="https://git.hush.is/onryo/hush-box">HushBox</a></td>
</tr>
<tr>
<td><a href="https://explorer.hush.land">Explorer</a></td>
<td><a href="https://git.hush.is/hush">Gitea</a></td>
<td><a href="https://hush.land/faq.html">F.A.Q</a></td>
<td><a href="https://hush.land/team.html">Team</a></td>
</tr>
</table>
<div class="blockt"><p>This is the most private and secure Blockchain Explorer in Zcash World, inspiration goes to <a href="https://xmrchain.net" class="mainlink">xmrchain.net</a>! There is no Javascript both client or server-side, it has no cookies, web analytics trackers, no images, no external CSS, visited and unvisited links are the same color so screenshots do not leak metadata, likewise it is available as a <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="mainlink">Tor hidden service</a>.</p></div>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Thu Sep 29 17:23:39 2022<!-- 1664472219 --></td>
<td style="font-size: 14px; width: 50%"><a href="/blocks/" class="mainlinkexplorer">Blocks list</a></td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%"><a href="/blocks/" class="mainlinkexplorer">Block Height: 1099008 </a></td>
<td style="font-size: 14px; width: 50%"><a href="https://git.hush.is/hush/anonsets" class="mainlinkexplorer">Anonymity Set</a>:<span class='anonset'> 2410752 </span></td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Total Transactions: 1810407</td>
<td style="font-size: 14px; width: 50%">Transaction Rate: 2.1093 per minute </td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Hashrate: 11.19 MSol/s</td>
<td style="font-size: 14px; width: 50%">Difficulty: 49283696</td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Circulating Supply: 12798895.34523515 HUSH</td>
<td style="font-size: 14px; width: 50%">Shielded Supply: 6850551.72538454 HUSH</td>
</tr>
</table>
<table>
<td style="font-size: 14px; width: 50%">Price:<span class='price'> 0.00000273 BTC</span></td>
<td style="font-size: 14px; width: 50%">Total Volume:<span class='volume'> .0077033708 BTC </span></td>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Percent Shielded: 53.525 </td>
<td style="font-size: 14px; width: 50%"><a href="/addresses/" class="mainlinkexplorer">T-addresses list</a></td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">29 peers connected via TLS 1.3</td>
<td style="font-size: 14px; width: 50%">Protocol Version: 1987424</td>
</tr>
</table>
<div class="links">
<a href="https://hush.is/matrix"><span style="color: #262626">[</span> matrix <span style="color: #262626">]</span></a>
<a href="https://hush.is/mastodon"><span style="color: #262626">[</span> mastodon <span style="color: #262626">]</span></a>
<a href="https://videos.hush.is"><span style="color: #262626">[</span> peertube <span style="color: #262626">]</span></a>
<a href="https://t.me/hush_main"><span style="color: #262626">[</span> telegram <span style="color: #262626">]</span></a>
</div>
</body>
</html>

125
var/www/explorer.hush.land/var/www/explorer.hush.land/template.html

@ -0,0 +1,125 @@
<!doctype html>
<head>
<title>Home | Hush - Transact and Speak Freely</title>
<style>
body { background-color: #101010; max-width: 850px; margin: auto; font-family: 'Ubuntu Mono'; color: #b3b3b3; text-align: center }
table { width: 100%; border-collapse: collapse; margin-top: 15px }
td { border: 1px solid #1a1a1a; font-size: 16px; padding: 0.5em }
td:hover { background-color: #1a1a1a }
pre { background-color: #0d0d0d; border: 1px solid #1a1a1a; font-size: 6px; padding: 15px; color: #e6e6e6 }
details { cursor: pointer; background-color: #0d0d0d; text-align: left; margin-top: 15px; padding: 0.5em; border: 1px solid #1a1a1a; font-size: 13px; word-wrap: break-word }
summary { outline: none; padding: 0.4em }
.blockt { border: 1px solid #1a1a1a; padding: 0.15em; background-color: #0d0d0d; margin-top: 15px; text-align: left; font-size: 13px; word-wrap: break-word }
.blockt p { padding-left: 0.7em; padding-right: 0.7em }
.button:link { float: right; font-size: 11px }
.mainlink:link { text-decoration: dotted underline; text-underline-position: under }
.mainlink:hover { text-decoration: none; color: #595959 }
.mainlinkexplorer:link { text-decoration: dotted underline; text-underline-position: under }
.mainlinkexplorer:hover { text-decoration: none; color: #595959 }
.links { margin: 15px; font-size: 13px }
a:link { color: #b3b3b3; text-decoration: none }
a:visited { color: #b3b3b3 }
a:hover { color: #b3b3b3 }
* { scrollbar-width: thin; scrollbar-color: #333333 #101010 }
::-webkit-scrollbar { width: 6px }
::-webkit-scrollbar-thumb { background: #333333 }
@font-face { font-family: 'Ubuntu Mono'; src: url('UbuntuMono.ttf') format('truetype') }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>Hush - Speak and Transact Freely</h2>
<h3>Private Cryptocurrency and Messenger using Zero Knowledge Mathematics</h3>
<pre>
&&&&
&&&& &&&&&& &&&&
&&&&&& &&&&&& &&&&&&
&&& &&&&&& &&&& &&&&&& &&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&& &&&&&
&&&&& &&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&
&&&&& &&&& &&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&& &&&&&& && && &&&&&& &&&
&&&&&& &&&&&& &&&&&&
&&&& &&&&&& &&&&
&&&&&&
&&&& <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="button">.onion</a>
</pre>
<table>
<tr>
<td><a href="https://hush.land">Why Hush</a></td>
<td><a href="https://hush.land/hushchat.html">HushChat</a></td>
<td><a href="https://hushpool.is">HushPool</a></td>
<td><a href="https://git.hush.is/onryo/hush-box">HushBox</a></td>
</tr>
<tr>
<td><a href="https://explorer.hush.land">Explorer</a></td>
<td><a href="https://git.hush.is/hush">Gitea</a></td>
<td><a href="https://hush.land/faq.html">F.A.Q</a></td>
<td><a href="https://hush.land/team.html">Team</a></td>
</tr>
</table>
<div class="blockt"><p>This is the most private and secure Blockchain Explorer in Zcash World, inspiration goes to <a href="https://xmrchain.net" class="mainlink">xmrchain.net</a>! There is no Javascript both client or server-side, it has no cookies, web analytics trackers, no images, no external CSS, visited and unvisited links are the same color so screenshots do not leak metadata, likewise it is available as a <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="mainlink">Tor hidden service</a>.</p></div>
<table>
<tr>
<td style="font-size: 14px; width: 50%">#TIPTIME#</td>
<td style="font-size: 14px; width: 50%"><a href="/blocks/" class="mainlinkexplorer">Blocks list</a></td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%"><a href="/blocks/" class="mainlinkexplorer">Block Height: #BLOCKS# </a></td>
<td style="font-size: 14px; width: 50%"><a href="https://git.hush.is/hush/anonsets" class="mainlinkexplorer">Anonymity Set</a>:<span class='anonset'> 2410752 </span></td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Total Transactions: #TXCOUNT#</td>
<td style="font-size: 14px; width: 50%">Transaction Rate: #TXRATE# per minute </td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Hashrate: #NETWORKSOLPS# MSol/s</td>
<td style="font-size: 14px; width: 50%">Difficulty: #DIFFICULTY#</td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Circulating Supply: #SUPPLY# HUSH</td>
<td style="font-size: 14px; width: 50%">Shielded Supply: #ZFUNDS# HUSH</td>
</tr>
</table>
<table>
<td style="font-size: 14px; width: 50%">Price:<span class='price'> 0.00000273 BTC</span></td>
<td style="font-size: 14px; width: 50%">Total Volume:<span class='volume'> .0077033708 BTC </span></td>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">Percent Shielded: #ZFUNDS_PERCENT# </td>
<td style="font-size: 14px; width: 50%"><a href="/addresses/" class="mainlinkexplorer">T-addresses list</a></td>
</tr>
</table>
<table>
<tr>
<td style="font-size: 14px; width: 50%">#CONNECTIONS# peers connected via TLS 1.3</td>
<td style="font-size: 14px; width: 50%">Protocol Version: #PROTOCOLVERSION#</td>
</tr>
</table>
<div class="links">
<a href="https://hush.is/matrix"><span style="color: #262626">[</span> matrix <span style="color: #262626">]</span></a>
<a href="https://hush.is/mastodon"><span style="color: #262626">[</span> mastodon <span style="color: #262626">]</span></a>
<a href="https://videos.hush.is"><span style="color: #262626">[</span> peertube <span style="color: #262626">]</span></a>
<a href="https://t.me/hush_main"><span style="color: #262626">[</span> telegram <span style="color: #262626">]</span></a>
</div>
</body>
</html>

85
var/www/explorer.hush.land/var/www/explorer.hush.land/tx/template.html

@ -0,0 +1,85 @@
<!doctype html>
<head>
<title>Home | Hush - Transact and Speak Freely</title>
<style>
body { background-color: #101010; max-width: 850px; margin: auto; font-family: 'Ubuntu Mono'; color: #b3b3b3; text-align: center }
table { width: 100%; border-collapse: collapse; margin-top: 15px }
td { border: 1px solid #1a1a1a; font-size: 16px; padding: 0.5em }
td:hover { background-color: #1a1a1a }
pre { background-color: #0d0d0d; border: 1px solid #1a1a1a; font-size: 6px; padding: 15px; color: #e6e6e6 }
details { cursor: pointer; background-color: #0d0d0d; text-align: left; margin-top: 15px; padding: 0.5em; border: 1px solid #1a1a1a; font-size: 13px; word-wrap: break-word }
summary { outline: none; padding: 0.4em }
.blockt { border: 1px solid #1a1a1a; padding: 0.15em; background-color: #0d0d0d; margin-top: 15px; text-align: left; font-size: 13px; word-wrap: break-word }
.blockt p { padding-left: 0.7em; padding-right: 0.7em }
.button:link { float: right; font-size: 11px }
.mainlinkexplorer:link { text-decoration: dotted underline; text-underline-position: under }
.mainlinkexplorer:hover { text-decoration: none; color: #595959 }
.links { margin: 15px; font-size: 13px }
a:link { color: #b3b3b3; text-decoration: none }
a:visited { color: #b3b3b3 }
a:hover { color: #b3b3b3 }
* { scrollbar-width: thin; scrollbar-color: #333333 #101010 }
::-webkit-scrollbar { width: 6px }
::-webkit-scrollbar-thumb { background: #333333 }
@font-face { font-family: 'Ubuntu Mono'; src: url('../../UbuntuMono.ttf') format('truetype') }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>Hush - Speak and Transact Freely</h2>
<h3>Private Cryptocurrency and Messenger using Zero Knowledge Mathematics</h3>
<pre>
&&&&
&&&& &&&&&& &&&&
&&&&&& &&&&&& &&&&&&
&&& &&&&&& &&&& &&&&&& &&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&& &&&&&
&&&&& &&&& && &&&&&& &&&&&
&&&&& &&&&&& &&&&&
&&&&& &&&& &&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&& &&&&&
&&&&& &&&&&& &&&&&& &&&&&
&&& &&&&&& && && &&&&&& &&&
&&&&&& &&&&&& &&&&&&
&&&& &&&&&& &&&&
&&&&&&
&&&& <a href="http://jlqhwhak65kokg3pdjp3ufy6almf5spnhsfnugtjsc4z7wtapgozxyad.onion" class="button">.onion</a>
</pre>
<table>
<tr>
<td><a href="https://hush.land">Why Hush</a></td>
<td><a href="https://hush.land/hushchat.html">HushChat</a></td>
<td><a href="https://hushpool.is">HushPool</a></td>
<td><a href="https://git.hush.is/onryo/hush-box">HushBox</a></td>
</tr>
<tr>
<td><a href="https://explorer.hush.land">Explorer</a></td>
<td><a href="https://git.hush.is/hush">Gitea</a></td>
<td><a href="https://hush.land/faq.html">F.A.Q</a></td>
<td><a href="https://hush.land/team.html">Team</a></td>
</tr>
</table>
<table>
<tr><td style="font-size: 14px"><a href="/block/#BLOCKHEIGHT#" class="mainlinkexplorer">Block Height: #BLOCKHEIGHT#</a></td></tr>
<tr><td style="font-size: 14px"><a href="/block/#BLOCKHASH#" class="mainlinkexplorer">Block Hash: #BLOCKHASH#</a></td></tr>
<tr><td style="font-size: 14px"><a href="/tx/#TXID#" class="mainlinkexplorer">Transaction ID: #TXID#</a></td></tr>
<tr><td style="font-size: 14px">Transaction Time: #TXTIME#</td></tr>
</table>
<table>
#TX_DATA#
</table>
<div class="links">
<a href="https://hush.is/matrix"><span style="color: #262626">[</span> matrix <span style="color: #262626">]</span></a>
<a href="https://hush.is/mastodon"><span style="color: #262626">[</span> mastodon <span style="color: #262626">]</span></a>
<a href="https://videos.hush.is"><span style="color: #262626">[</span> peertube <span style="color: #262626">]</span></a>
<a href="https://t.me/hush_main"><span style="color: #262626">[</span> telegram <span style="color: #262626">]</span></a>
</div>
</body>
</html>
Loading…
Cancel
Save