Skip to content
Snippets Groups Projects
Commit 16315b70 authored by Robert Martin-Legene's avatar Robert Martin-Legene
Browse files

transactors traverses the blockchain\'s transactions and finds out who has ever received ether

parent 1f6f87db
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/perl -w
use strict;
use warnings;
use IO::File;
use Math::BigInt;
use Carp;
$Carp::Verbose = 1;
die "\$BFAHOME not set. Did you source bfa/bin/env ?\n"
unless exists $ENV{BFAHOME};
chdir "$ENV{BFAHOME}" or die $!;
package tools;
my $rpcport;
my $ua = LWP::UserAgent->new;
sub new
{
my $class = shift;
return bless {@_}, ref $class || $class;
}
sub wait
{
my $i = ++$_[0]->{'wait'};
printf "%s%c[D", substr('|/-\\', $i%4, 1), 27;
sleep 1;
}
sub cat($)
{
my ($filename) = @_;
my $fh = IO::File->new($filename) or return;
return join('', $fh->getlines);
}
sub hex2string($)
{
my ($msg)=@_;
my $txt = '';
while ($msg ne '')
{
my $i=hex( substr($msg,0,2) );
my $c='.';
$c=chr($i) if $i >= 32 and $i <= 127;
$txt .= $c;
$msg=substr $msg, 2;
}
return $txt;
}
sub rpcreq
{
my ( $opname, @params ) = @_;
if ( not defined $rpcport )
{
$rpcport = tools::cat "$ENV{BFAHOME}/network5445/node1/rpcport" or die;
}
my $req = HTTP::Request->new( POST => "http://127.0.0.1:$rpcport" );
$req->content_type('application/json');
my $extra = scalar @params
? sprintf(qq(,\"params\":[%s]), join(',', @params))
: '';
$req->content( qq({"jsonrpc":"2.0","method":"${opname}"${extra},"id":1}));
my $res = $ua->request($req);
die $res->status_line
unless $res->is_success;
return $res->content;
}
package balance;
use JSON;
sub new
{
my ($class, $acct, $at) = @_;
my $self = bless {}, ref $class || $class;
$self->get( $acct, $at ) if defined $acct;
return $self;
}
sub acct
{
my ($self, $acct) = @_;
if ( defined $acct )
{
$acct = '0x'.$acct if $acct !~ /^0x/;
$self->{'_acct'} = $acct;
}
return unless exists $self->{'_acct'};
return $self->{'_acct'};
}
sub at
{
my ($self, $at) = @_;
$self->{'_at'} = $at if defined $at;
return sprintf('0x%x', $self->{'_at'}) if exists $self->{'_at'};
return 'latest';
}
sub get
{
my ($self, $acct, $at) = @_;
$self->acct($acct) if defined $acct;
$self->at($at) if defined $at;
my @params = ( sprintf(qq("%s","%s"),$self->acct,$self->at) );
my $content = tools::rpcreq( 'eth_getBalance', @params );
my $json;
eval { $json = decode_json( $content ) };
my $error = error->new( $content );
if ( $error )
{
my $msg = '';
return 'NOTFOUND' if $error->message =~ /^missing trie node /;
die join(' * ', @params, $content);
return;
}
die if not exists $json->{'result'};
die if not defined $json->{'result'};
return Math::BigInt->from_hex( $json->{'result'} );
}
package error;
use JSON;
sub new
{
my ($class, $json_in) = @_;
my $json;
eval { $json = decode_json( $json_in ) };
return unless defined $json;
return unless exists $json->{'error'};
my $self = bless {
'_code' => undef,
'_message' => undef,
}, ref $class || $class;
$self->code( $json->{'error'}->{'code'} ) if exists $json->{'error'}->{'code'};
$self->message( $json->{'error'}->{'message'} ) if exists $json->{'error'}->{'message'};
return $self;
}
sub code
{
my ( $self, $val ) = @_;
$self->{'_code'} = $val if scalar @_ > 1;
return $self->{'_code'};
}
sub message
{
my ( $self, $val ) = @_;
$self->{'_message'} = $val if scalar @_ > 1;
return $self->{'_message'};
}
package block;
use LWP;
use JSON;
sub new
{
my ( $class, $json_raw ) = @_;
return unless defined $json_raw;
return if $json_raw eq '';
my $self = bless {}, ref $class || $class;
$self->{'json_raw'} = $json_raw;
eval { $self->{'json'} = decode_json( $json_raw ) };
return if $@;
$self->error( error->new($json_raw) );
return $self;
}
sub error
{
return if not exists $_[0]->{'error'};
return $_[0]->{'error'};
}
sub json
{
return unless exists $_[0]->{'json'};
return $_[0]->{'json'};
}
sub result
{
return unless exists $_[0]->{'json'}->{'result'};
return $_[0]->{'json'}->{'result'};
}
sub number
{
return if not exists $_[0]->result->{'number'};
return hex( $_[0]->result->{'number'} );
}
sub timestamp
{
return if not exists $_[0]->result->{'timestamp'};
return hex( $_[0]->result->{'timestamp'} );
}
sub miner
{
return if not exists $_[0]->result->{'miner'};
return $_[0]->result->{'miner'};
}
sub get($;$)
{
my ($number) = @_;
$number = sprintf('0x%x', $number) if $number ne 'earliest';
my $cachefile = "cache/block.$number";
my $content = tools::rpcreq( 'eth_getBlockByNumber', qq("$number"), "true");
my $block = block->new( $content );
return if not defined $block;
return if not exists $block->{'json'};
die $block->error->message
if $block->error;
return if not $block->result;
return $block;
}
sub tx {
my ($self) = @_;
return $self->result->{'transactions'};
}
package main;
my $number = shift || 'earliest';
my $_rcpts;
sub rcpt
{
return 0 if exists $_rcpts->{$_[0]};
$_rcpts->{$_[0]} = 1;
return 1;
}
while ( 1 )
{
my $block = block::get($number);
exit 0 if not defined $block;
use Data::Dumper; print Dumper( $block->result );
die $block->miner;
rcpt( $block->miner );
my $txref = $block->tx;
for my $tx (@$txref)
{
my $from = $tx->{'from'};
my $to = $tx->{'to'};
my $value = $tx->{'value'};
next if $value eq '0x0';
printf "%s\n", $to if rcpt( $to );
}
$number = $block->number + 1;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment