From b114439402fa4055415005a46e520946bebc5755 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Duke\" Leto" Date: Sat, 11 Nov 2017 22:24:19 -0800 Subject: [PATCH] Start getting serious about z_sendmany --- bin/hushlist | 14 ++++++---- lib/Hush/List.pm | 69 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/bin/hushlist b/bin/hushlist index f04145f..a5ef1b1 100755 --- a/bin/hushlist +++ b/bin/hushlist @@ -14,8 +14,8 @@ my $walletinfo = $rpc->getwalletinfo; my $chain = $chaininfo->{chain}; my $blocks = $chaininfo->{blocks}; my $balance = $rpc->z_gettotalbalance; -my $tbalance = $balance->{transparent}; -my $zbalance = $balance->{private}; +my $tbalance = sprintf "%.6f", $balance->{transparent}; +my $zbalance = sprintf "%.6f", $balance->{private}; my $total_balance = $balance->{total}; my $blockchain = "HUSH"; @@ -71,8 +71,12 @@ sub status { } } -sub public { +# make a hushlist public by publishing its privkey in OP_RETURN data +# This operation costs HUSH!!! +sub publi { my ($name) = @_; + + $list->public($name); } sub new { @@ -108,7 +112,7 @@ sub remove { } sub send { - my ($list_name,$from,$memo) = @_; + my ($list_name,$memo) = @_; - $list->send_message($from, $list_name, $memo); + $list->send_message($list_name, $memo); } diff --git a/lib/Hush/List.pm b/lib/Hush/List.pm index 4e494ec..1ed59a6 100644 --- a/lib/Hush/List.pm +++ b/lib/Hush/List.pm @@ -9,6 +9,7 @@ use Hush::Util qw/barf/; use File::Slurp; our $VERSION = 20171031; +my $rpc = Hush::RPC->new; # as per z_sendmany rpc docs my $MAX_RECIPIENTS = 54; @@ -52,7 +53,6 @@ sub create_default_conf { my ($list_conf) = @_; # when we create a brand new conf, we create brand new funding+nym addrs - my $rpc = Hush::RPC->new; my $funding_zaddr = $rpc->z_getnewaddress; barf "Unable to create funding zaddr" unless $funding_zaddr; @@ -84,6 +84,9 @@ sub new { return bless $hush_list, 'Hush::List'; } +sub list_members { +} + # show overview of current hushlists sub global_status { my ($self) = @_; @@ -150,11 +153,15 @@ sub new_list { } my $list_specific_conf = catfile($HUSHLIST_CONFIG_DIR,$name,'list.conf'); my $member_list = catfile($HUSHLIST_CONFIG_DIR,$name,'members.txt'); - my $time = time; + my $time = time; + my $sending_zaddr = $rpc->z_getnewaddress; { open my $fh, '>', $list_specific_conf or barf "Could not open $list_specific_conf for writing"; print $fh "# hushlist $name config v$Hush::List::VERSION\n"; + # every list has a unique sending zaddr, so there is no metadata leaked + # across one user sending messages to multiple hushlists + print $fh "sending_zaddr=$sending_zaddr\n"; print $fh "generated=$time\n"; # default chain is hush for now # changing the chain of an existing list means that the subset @@ -171,12 +178,8 @@ sub new_list { close $fh; } - # We consider members.txt the oracle, so users can simply maintain a list - # of zaddrs into a file, if they want. We sync/serialize to list.json - # each time we run - # hust list contacts? - # TODO: still in flux - # ~/.hush/list/contacts/ + # We consider members.txt the oracle, so users can simply maintain a simple + # text file of one item per line, and other files serialized version # ~/.hush/list/LIST_NAME/ # ~/.hush/list/LIST_NAME/list.conf - list-specific config items # ~/.hush/list/LIST_NAME/members.txt - list member zaddrs, one per line @@ -185,6 +188,14 @@ sub new_list { return $self; } +# make a local hushlist PUBLIC by publishing its PRIVKEY +# to the blockchain via OP_RETURN. This is a ONE WAY PROCESS!!! +# You can not make a public hushlist private again, it's privkey is in the wild, +# but we CAN make +sub public { + my ($self,$name) = @_; +} + sub add_zaddr { my ($self,$name,$zaddr) = @_; $zaddr||= ''; @@ -214,27 +225,57 @@ sub remove_zaddr { # send a message to a Hush List, weeeeee! sub send_message { - my ($self,$from,$name,$message) = @_; + my ($self,$name,$message) = @_; my $rpc = $self->{rpc}; # TODO: better validation - barf "Invalid Hush list name" unless $name; + barf "Invalid Hush list name" unless $name =~ m/^([a-z0-9]+)$/i; barf "Hush message cannot be empty" unless $message; - barf "Invalid Hush from address: $from" unless $from; + + # each hush list has a sending_zaddr defined at time of creation + # which is used to send to this list + my $list_specific_conf = catfile($HUSHLIST_CONFIG_DIR,$name,'list.conf'); + unless (-e $list_specific_conf) { + barf "Hushlist config for $name list not found!"; + } + + my %list_conf = read_file( $list_specific_conf ) =~ /^(\w+)=(.*)$/mg ; + my $from = $list_conf{sending_zaddr}; + + barf "Invalid Hush from address! $from" unless $from; my $hush_list = $self->{lists}->{$name} || barf "No Hush List by the name of '$name' found"; + my $list_members_file = catfile($HUSHLIST_CONFIG_DIR,$name,'members.txt'); + unless (-e $list_members_file) { + barf "No members file found for Hushlist $name!"; + } + my @list_members = read_file($list_members_file); + my $recipients = $hush_list->recipients; barf "Max recipients of $MAX_RECIPIENTS exceeded" if (@$recipients > $MAX_RECIPIENTS); - # TODO: can we make amount=0 and have fee-only xtns? # amount is hidden, so it does not identify list messages via metadata - my $amount = 1e-4; - my $fee = 1e-6; + my $amount = 0.0; # this could blow up for a bajillion reasons... try { + +# z_sendmany +# Arguments: +# 1. "fromaddress" (string, required) The taddr or zaddr to send the funds from. +# 2. "amounts" (array, required) An array of json objects representing the amounts to send. +# [{ +# "address":address (string, required) The address is a taddr or zaddr +# "amount":amount (numeric, required) The numeric amount in ZEC is the value +# "memo":memo (string, optional) If the address is a zaddr, raw data represented in hexadecimal string format +# }, ... ] +# 3. minconf (numeric, optional, default=1) Only use funds confirmed at least this many times. +# 4. fee (numeric, optional, default=0.0001) The fee amount to attach to this transaction. + + my $addr = "z42"; + my $amounts = [ { address => $addr, amount => $amount, memo => $message } ]; my $txid = $rpc->z_sendmany($from, $amount, $recipients, $message); warn "txid=$txid"; } catch {