#!/usr/bin/perl use IO::Socket;use IO::Select;use Digest::SHA; $tx=shift(@ARGV); $btc=IO::Socket::INET->new(PeerAddr=>"localhost",PeerPort=>'8333',Proto=>'tcp') or die "Socket"; $port="\x20\x8d";$magic="\xf9\xbe\xb4\xd9";$mmatch="f9.be.b4.d9"; $sel=IO::Select->new();$sel->add($btc); $p="\x2c\x7e\x00\x00"; # Version $p.="\x01\x00\x00\x00\x00\x00\x00\x00"; # Services $h=sprintf('%x',time());while(length($h)<16){$h="0".$h;} $h=reverse($h);$p.=pack('h*',$h); # Unix Timestamp $p.="\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"; # To IP $p.="\x7f\x00\x00\x01".$port; # 127.0.0.1:port $p.="\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"; # From IP $p.="\x00\x00\x00\x00".$port; # 0.0.0.0:port @chars=('a'..'f', 0..9);$rr=join '',map {$chars[rand @chars]} 1..16; $p.=pack('H*',$rr); # Random Unique ID $p.="\x00"; # No User Agent $p.="\x00\x00\x00\x00"; # No Blocks sendpacket('version',$p); while($gotver==0){ ($c,$p)=readpacket(); if($c eq 'version'){$gotver=1;} sleep(1);} sendpacket('verack',''); $tt=pack('H*',$tx); $h=Digest::SHA::sha256(Digest::SHA::sha256($tt)); $p="\x01\x01\x00\x00\x00".pack('H*',reverse(unpack('h*',$h))); sendpacket('inv',$p);$gotreq=0; while($gotreq==0){ ($c,$pp)=readpacket(); if($c eq 'getdata' && $p eq $pp){$gotreq=1;} sleep(1);} sendpacket('tx',$tt); print "Sent transaction ".unpack('H*',$h)."\n"; close($btc); sub sendpacket{my $c=shift(@_);my $p=shift(@_); my $o=$magic;while(length($c)<12){$c.="\x00";}$o.=$c; #Command my $h=sprintf('%x',length($p));while(length($h)<8){$h="0".$h;} $h=reverse($h);$o.=pack('h*',$h); # Payload length $h=Digest::SHA::sha256(Digest::SHA::sha256($p)); $h=unpack('H*',$h);$o.=pack('H*',substr($h,0,8)); # Checksum $o.=$p; # Payload print $btc $o;print STDERR "Sent $c (".length($p)." byte payload)\n"; } sub readpacket{ if(!$sel->can_read(1)){return 0;} my @x;my $x;while(1){read($btc,$x,1);$x=unpack('H*',$x); push(@x,$x);if($#x>3){shift(@x);} if(join('.',@x) eq $mmatch){ my $cmd;my $len; read($btc,$cmd,12);read($btc,$len,4);read($btc,$x,4); $x=unpack('h*',$len);$x=reverse($x);$len=hex($x); $x=chop($cmd);while($x eq "\x00"){$x=chop($cmd);}$cmd.=$x; print STDERR "Read $cmd ($len byte payload)\n"; if($len>0){read($btc,$x,$len);return ($cmd,$x);} else{return ($cmd,'');} } } }