File Coverage

blib/lib/Blockchain/Ethereum/ABI/Encoder.pm
Criterion Covered Total %
statement 51 51 100.0
branch 6 8 75.0
condition 1 3 33.3
subroutine 14 14 100.0
pod 5 6 83.3
total 77 82 93.9


line stmt bran cond sub pod time code
1             package Blockchain::Ethereum::ABI::Encoder;
2              
3 8     8   983400 use v5.26;
  8         36  
4 8     8   49 use strict;
  8         20  
  8         316  
5 8     8   69 use warnings;
  8         29  
  8         858  
6              
7             # ABSTRACT: ABI utility for encoding ethereum contract arguments
8             our $AUTHORITY = 'cpan:REFECO'; # AUTHORITY
9             our $VERSION = '0.021'; # VERSION
10              
11 8     8   58 use Carp;
  8         39  
  8         876  
12 8     8   4588 use Crypt::Digest::Keccak256 qw(keccak256_hex);
  8         42157  
  8         1637  
13              
14 8     8   4087 use Blockchain::Ethereum::ABI::Type;
  8         26  
  8         371  
15 8     8   4037 use Blockchain::Ethereum::ABI::Type::Tuple;
  8         29  
  8         4277  
16              
17             sub new {
18 7     7 0 1865669 my $class = shift;
19 7         45 my $self = {
20             instances => [],
21             function_name => undef,
22             };
23              
24 7         31 return bless $self, $class;
25             }
26              
27             sub append {
28 30     30 1 9239 my ($self, %param) = @_;
29              
30 30         103 for my $type_signature (keys %param) {
31             push(
32             $self->{instances}->@*,
33             Blockchain::Ethereum::ABI::Type->new(
34             signature => $type_signature,
35 30         225 data => $param{$type_signature}));
36             }
37              
38 29         196 return $self;
39             }
40              
41             sub function {
42 11     11 1 33740 my ($self, $function_name) = @_;
43              
44 11         116 $self->{function_name} = $function_name;
45 11         81 return $self;
46             }
47              
48             sub generate_function_signature {
49 11     11 1 24 my $self = shift;
50              
51 11 50       40 croak "Missing function name e.g. ->function('name')" unless $self->{function_name};
52              
53 11         46 my @instances = $self->{instances}->@*;
54              
55 11         27 my $signature = $self->{function_name} . '(';
56 11         52 $signature .= sprintf("%s,", $_->{signature}) for @instances;
57 11 100       42 chop $signature if scalar @instances;
58 11         88 return $signature . ')';
59             }
60              
61             sub encode_function_signature {
62 11     11 1 30 my ($self, $signature) = @_;
63              
64 11   33     80 return sprintf("0x%.8s", keccak256_hex($signature // $self->generate_function_signature));
65             }
66              
67             sub encode {
68 17     17 1 37 my $self = shift;
69              
70 17         127 my $tuple = Blockchain::Ethereum::ABI::Type::Tuple->new;
71 17         74 $tuple->{instances} = $self->{instances};
72              
73 17         118 my $encoded = $tuple->encode;
74 11         25 my @data;
75 11 100       44 push @data, $tuple->encode->@* if $encoded;
76 11 50       90 unshift @data, $self->encode_function_signature if $self->{function_name};
77              
78 11         391 $self->_clean;
79              
80 11         373 return join('', @data);
81             }
82              
83             sub _clean {
84 18     18   11785 my $self = shift;
85 18         127 $self->{instances} = [];
86 18         55 $self->{function_name} = undef;
87             }
88              
89             1;
90              
91             __END__