Crypt-HashCash

 view release on metacpan or  search on metacpan

bin/vault-worker.pl  view on Meta::CPAN

#!/usr/bin/perl
# -*-cperl-*-
#
# vault-worker.pl - Vault worker for HashCash Digital Cash
# Copyright (c) 2017 Ashish Gulhati <crypt-hashcash at hash.neo.tc>
#
# $Id: bin/vault-worker.pl v1.130 Sat Dec 22 18:42:27 PST 2018 $

use strict;
use warnings;

use Crypt::HashCash::Vault::Bitcoin;
use Crypt::HashCash::Coin::Blinded;
use Crypt::HashCash::CoinRequest;
use Crypt::HashCash::Coin;
use Crypt::HashCash qw (_dec _hex _dectob85 _b85todec);
use Crypt::Random qw(makerandom);
use Crypt::EECDH;
use Crypt::CBC;
use File::HomeDir;
use Digest::MD5 qw(md5_hex);
use IPC::Queue::Duplex;

my $HASHCASH = $ENV{HASHCASHDIR} || File::HomeDir->my_home . '/.hashcash';

unless (-d $HASHCASH) {
  die "Directory $HASHCASH doesn't exist and couldn't be created.\n" unless mkdir($HASHCASH, 0700);
}

unless (-d "$HASHCASH/vaults") {
  die "Directory $HASHCASH/.vaults doesn't exist and couldn't be created.\n" unless mkdir("$HASHCASH/vaults", 0700);
}

my $vault = new Crypt::HashCash::Vault::Bitcoin ( DB => "$HASHCASH/vault.db",
						  KeyDB => "$HASHCASH/vaults/vault.key" );

if (!-f "$HASHCASH/vaults/vault.key" or (defined $ARGV[0] and $ARGV[0] eq '--keygen')) {
  $|=1;
  print STDERR "Generating vault keys... ";
  $vault->keygen( Name   => 'localhost',
		  Server => 'localhost',
		  Port   => '20203',
		  Fees   => { mf => 50, mp => 0, vf => 50, vp => 0.001 } );
  print "done.\n";
}

$vault->mint->loadkeys();
my $sk = pack ('H*',$vault->mint->keydb->{vaultsec});
my $queue = new IPC::Queue::Duplex ( Dir => '/tmp' );

while(1){
  my ($job, $pubkey, $keyhex, $ret, $preret, $sendto, $sendamt);
  my $eecdh = new Crypt::EECDH;
  unless ($job = $queue->get) {
    $vault->mint->signer->preinit if $vault->mint->sigscheme eq 'ECDSA';
    next;
  }
  $_ = $job->{Request};
  alarm(0);
  /^(\S+)\s?(\S+)?\s?(\S+)?/;
  if ($1 eq 'es') {                                   # Electrum signing request from external server
    my $electrum = '/home/hash/src/Electrum-2.8.2/electrum';
    my $withdrawid = $3;
    my $tx = "{\n\"complete\": false,\n\"final\": true,\n\"hex\": \"$2\"\n}";
    my $txdetails = `$electrum deserialize '$tx'`;    # Check transaction details
    my $addresses = `$electrum listaddresses --change`;
    my @addresses = map { /\"(\S+)\"/; $1; } split /,\s*/, $addresses;
    $txdetails =~ /\"outputs\": (.*)/s; my $outputs = $1;
    my @outputs = map { /\"address\": \"(\S+?)\".*\"value\": (\d+)/s; ($1 => $2) } split /\}\,/s, $outputs;
    my $query = "SELECT sendto,sendamt from withdrawals WHERE id='$withdrawid';";
    print STDERR "ERR: couldn't retrieve withdrawal params.\n" unless my ($sndto, $sndamt) = $vault->bizbtc->db->selectrow_array($query);
    $job->finish('ERR'), next unless $outputs[0] eq $sndto and $outputs[1] == $sndamt;
    my $err;
    for (2..$#outputs) {
      next if $_ % 2; my $o = $outputs[$_];
      $job->finish('ERR'), $err = 1, last unless grep { /^$o$/ } @addresses;
    }
    next if $err;
    my $signedtx = `$electrum signtransaction '$tx'`;



( run in 0.497 second using v1.01-cache-2.11-cpan-e1769b4cff6 )