File Coverage

blib/lib/Blockchain/Ethereum/ABI/Encoder.pm
Criterion Covered Total %
statement 50 50 100.0
branch 2 4 50.0
condition 3 5 60.0
subroutine 16 16 100.0
pod 5 7 71.4
total 76 82 92.6


line stmt bran cond sub pod time code
1             package Blockchain::Ethereum::ABI::Encoder;
2              
3 4     4   281933 use v5.26;
  4         54  
4 4     4   23 use strict;
  4         28  
  4         142  
5 4     4   40 use warnings;
  4         9  
  4         170  
6              
7 4     4   28 use Carp;
  4         9  
  4         314  
8 4     4   1829 use Digest::Keccak qw(keccak_256_hex);
  4         6015  
  4         269  
9              
10 4     4   1807 use Blockchain::Ethereum::ABI::Type;
  4         12  
  4         129  
11 4     4   1745 use Blockchain::Ethereum::ABI::Type::Tuple;
  4         11  
  4         1897  
12              
13             sub new {
14 4     4 0 1520 return bless {}, shift;
15             }
16              
17             sub _instances {
18 50     50   93 my $self = shift;
19 50   100     277 return $self->{instances} //= [];
20             }
21              
22             sub function_name {
23 24     24 0 43 my $self = shift;
24 24         85 return $self->{function_name};
25             }
26              
27             sub append {
28 28     28 1 5839 my ($self, %param) = @_;
29              
30 28         86 for my $type_signature (keys %param) {
31             push(
32             $self->_instances->@*,
33             Blockchain::Ethereum::ABI::Type::new_type(
34             signature => $type_signature,
35 28         74 data => $param{$type_signature}));
36             }
37              
38 27         150 return $self;
39             }
40              
41             sub function {
42 8     8 1 16932 my ($self, $function_name) = @_;
43 8         30 $self->{function_name} = $function_name;
44 8         56 return $self;
45             }
46              
47             sub generate_function_signature {
48 8     8 1 15 my $self = shift;
49 8 50       16 croak "Missing function name e.g. ->function('name')" unless $self->function_name;
50 8         22 my $signature = $self->function_name . '(';
51 8         32 $signature .= sprintf("%s,", $_->_signature) for $self->_instances->@*;
52 8         40 chop $signature;
53 8         122 return $signature . ')';
54             }
55              
56             sub encode_function_signature {
57 8     8 1 21 my ($self, $signature) = @_;
58 8   33     37 return sprintf("0x%.8s", keccak_256_hex($signature // $self->generate_function_signature));
59             }
60              
61             sub encode {
62 14     14 1 28 my $self = shift;
63              
64 14         63 my $tuple = Blockchain::Ethereum::ABI::Type::Tuple->new;
65 14         39 $tuple->{instances} = $self->_instances;
66 14         44 my @data = $tuple->encode->@*;
67 8 50       30 unshift @data, $self->encode_function_signature if $self->function_name;
68              
69 8         34 $self->_clean;
70              
71 8         268 return join('', @data);
72             }
73              
74             sub _clean {
75 15     15   5204 my $self = shift;
76 15         57 delete $self->{instances};
77 15         44 undef $self->{function_name};
78             }
79              
80             1;
81              
82             __END__