|
|
@ -4,6 +4,8 @@ BEGIN { if (-e $ENV{SITE}.'/lib') { use lib $ENV{SITE}.'/lib'; } } |
|
|
|
|
|
|
|
|
|
|
|
use config; |
|
|
|
use essential qw(sdate version); |
|
|
|
use misc qw(khash yamlify); |
|
|
|
use TXPOOL qw(saveTxPool); |
|
|
|
use CAStore qw(CASWrite); |
|
|
|
use ECKeys qw(ecsign ecverif getPeerid loadKeys); |
|
|
@ -14,9 +16,19 @@ foreach my $id (keys %{$keys}) { |
|
|
|
my $pub = $keys->{$id}{public}; |
|
|
|
$keys->{$pub}{id} = $id; |
|
|
|
} |
|
|
|
#printf "--- keys %s...\n",Dump($keys); |
|
|
|
my $keyfile = $ENV{SITE}.'/secrets/coinbase.yml'; |
|
|
|
if (-e $keyfile) { |
|
|
|
my $local_keys = &loadKeys($keyfile); |
|
|
|
if (exists $keys->{coinbase}) { |
|
|
|
$keys->{coinbase}{private} = $local_keys->{coinbase}{private}; |
|
|
|
} else { |
|
|
|
$keys->{coinbase} = $local_keys->{coinbase}; |
|
|
|
} |
|
|
|
} |
|
|
|
printf "--- keys %s...\n",Dump($keys); |
|
|
|
|
|
|
|
my $txf = shift; |
|
|
|
my $date = (exists $tx->{timestamp})? &sdate($tx->{timestamp}) : &sdate(time); |
|
|
|
|
|
|
|
|
|
|
|
my $tx = LoadFile($txf); |
|
|
@ -25,48 +37,81 @@ my %signatures = (); |
|
|
|
my %delta = (); |
|
|
|
foreach my $sign (@{$tx->{signatures}}) { |
|
|
|
my ($pub) = keys %{$sign}; |
|
|
|
$signatures{$pub} = $sign->{$pub}; |
|
|
|
$signatures{$pub} = $sign->{$pub}[0]; |
|
|
|
$delta{$pub} = 0; |
|
|
|
} |
|
|
|
printf "--- signatures %s...\n",Dump(\%signatures); |
|
|
|
foreach my $in (@{$tx->{inputs}}) { |
|
|
|
my ($pub) = keys %{$in}; |
|
|
|
my $id = (exists $keys->{$pub}{id}) ? $keys->{$pub}{id} : $pub; |
|
|
|
$pub = $keys->{$id}{public} if (exists $keys->{$id}{public}); |
|
|
|
my $value = $in->{$pub}; |
|
|
|
$valuein += $value; |
|
|
|
$delta{$pub} -= $value; |
|
|
|
printf "in: %s from %s (%s)\n",$value,$pub,$keys->{$pub}{id}; |
|
|
|
printf "in: %s from %s (%s)\n",$pub,$id; |
|
|
|
} |
|
|
|
foreach my $out (@{$tx->{outputs}}) { |
|
|
|
my ($pub) = keys %{$out}; |
|
|
|
my $id = (exists $keys->{$pub}{id}) ? $keys->{$pub}{id} : $pub; |
|
|
|
$pub = $keys->{$id}{public} if (exists $keys->{$id}{public}); |
|
|
|
my $value = $out->{$pub}; |
|
|
|
$valueout += $value; |
|
|
|
$delta{$pub} += $value; |
|
|
|
printf "out: %s to %s (%s)\n",$value,$pub,$keys->{$pub}{id}; |
|
|
|
printf "out: %s to %s (%s)\n",$value,$pub,$id; |
|
|
|
} |
|
|
|
if ($valuein != $valueout) { |
|
|
|
printf "error: i:%s != o:%s\n",$valuein,$valueout; |
|
|
|
} |
|
|
|
my $txi = { |
|
|
|
timestamp => $tx->{timestamp}, |
|
|
|
inputs => $tx->{inputs} |
|
|
|
}; |
|
|
|
my $txo = { |
|
|
|
timestamp => $tx->{timestamp}, |
|
|
|
message => $tx->{message}, |
|
|
|
outputs => $tx->{outputs} |
|
|
|
}; |
|
|
|
my $txio = { |
|
|
|
timestamp => $tx->{timestamp}, |
|
|
|
message => $tx->{message}, |
|
|
|
inputs => $tx->{inputs}, |
|
|
|
outputs => $tx->{outputs} |
|
|
|
|
|
|
|
}; |
|
|
|
my $txihash = khash('SHA256',yamlify($txi)); |
|
|
|
my $txohash = khash('SHA256',yamlify($txo)); |
|
|
|
my $txhash = khash('SHA256',yamlify($txio)); |
|
|
|
|
|
|
|
foreach my $pub (keys %delta) { |
|
|
|
my $value = -$delta{$pub}; |
|
|
|
if (exists $signatures{$pub}) { |
|
|
|
my $id = (exists $keys->{$pub}{id}) ? $keys->{$pub}{id} : $pub; |
|
|
|
my $key58 = (exists $keys->{$id}{public}) ? $keys->{$id}{public} : $pub; |
|
|
|
my $msg = qq'["$pub","$value","$tx->{payload}"]'; |
|
|
|
my $msg; |
|
|
|
if ($value > 0) { # input |
|
|
|
$msg = qq'["$pub","$value","$tx->{message}"]'; |
|
|
|
} else { # output |
|
|
|
$msg = qq'["$id","$value","$tx->{txohash}"]'; |
|
|
|
} |
|
|
|
printf "msg: %s\n",$msg; |
|
|
|
if (defined $signatures{$pub}) { |
|
|
|
my $sig = $signatures{$pub}; |
|
|
|
my $sig = $signatures{$pub}[0]; |
|
|
|
my $sigok = &ecverif($key58,$sig,$msg); |
|
|
|
printf "signature for %s (%s) ? %s\n",$id,$key58,($sigok)?'ok':'invalid'; |
|
|
|
if (! $sigok) { |
|
|
|
my $sig = &ecsign($id,$msg); |
|
|
|
printf "sig: %s: %s (corrected)\n",$id,$sig; |
|
|
|
$signatures{$pub} = $sig; |
|
|
|
$signatures{$pub} = [ $sig, $date ]; |
|
|
|
} |
|
|
|
} else { |
|
|
|
my $id = (exists $keys->{$pub}{id}) ? $keys->{$pub}{id} : $pub; |
|
|
|
if (exists $keys->{$id}{private}) { |
|
|
|
my $sig = &ecsign($id,$msg); |
|
|
|
printf "sig: %s: %s\n",$id,$sig; |
|
|
|
$signatures{$pub} = $sig; |
|
|
|
$signatures{$pub} = [ $sig, $date ]; |
|
|
|
} else { |
|
|
|
printf "sig: don't have private key for %s\n",$id; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -80,7 +125,7 @@ printf "--- %s.sig: %s...\n",$txf,Dump($tx); |
|
|
|
DumpFile("$txf.sig",$tx); |
|
|
|
|
|
|
|
$tx->{nonce} = 3976914969180171529, |
|
|
|
my $txaddr = CASWrite('txpool',$tx,$tx->{nonce},'txpool',5); |
|
|
|
my $txaddr = CASWrite($ENV{SITE}.'/txpool',$tx,$tx->{nonce},'txpool',$config->{difficulty}); |
|
|
|
|
|
|
|
push @{$TXPOOL},$txaddr; |
|
|
|
&saveTxPool($TXPOOL); |
|
|
|