File Coverage

blib/lib/Blockchain/Contract/Solidity/ABI/Encoder.pm
Criterion Covered Total %
statement 56 56 100.0
branch 2 4 50.0
condition 3 5 60.0
subroutine 17 17 100.0
pod 5 7 71.4
total 83 89 93.2


line stmt bran cond sub pod time code
1             package Blockchain::Contract::Solidity::ABI::Encoder;
2              
3 4     4   275132 use v5.26;
  4         46  
4 4     4   26 use strict;
  4         8  
  4         93  
5 4     4   20 use warnings;
  4         9  
  4         144  
6 4     4   1912 no indirect;
  4         4456  
  4         22  
7              
8 4     4   224 use Carp;
  4         10  
  4         295  
9 4     4   1730 use Digest::Keccak qw(keccak_256_hex);
  4         5707  
  4         286  
10              
11 4     4   1832 use Blockchain::Contract::Solidity::ABI::Type;
  4         14  
  4         187  
12 4     4   1962 use Blockchain::Contract::Solidity::ABI::Type::Tuple;
  4         15  
  4         2624  
13              
14             sub new {
15 4     4 0 1412 my ($class, %params) = @_;
16              
17 4         16 my $self = {};
18 4         11 bless $self, $class;
19 4         14 return $self;
20             }
21              
22             sub _instances {
23 50     50   86 my $self = shift;
24 50   100     306 return $self->{instances} //= [];
25             }
26              
27             sub function_name {
28 24     24 0 43 my $self = shift;
29 24         81 return $self->{function_name};
30             }
31              
32             sub append {
33 28     28 1 5788 my ($self, %param) = @_;
34              
35 28         99 for my $type_signature (keys %param) {
36             push(
37             $self->_instances->@*,
38             Blockchain::Contract::Solidity::ABI::Type::new_type(
39             signature => $type_signature,
40 28         81 data => $param{$type_signature}));
41             }
42              
43 27         143 return $self;
44             }
45              
46             sub function {
47 8     8 1 16620 my ($self, $function_name) = @_;
48 8         31 $self->{function_name} = $function_name;
49 8         51 return $self;
50             }
51              
52             sub generate_function_signature {
53 8     8 1 26 my $self = shift;
54 8 50       19 croak "Missing function name e.g. ->function('name')" unless $self->function_name;
55 8         28 my $signature = $self->function_name . '(';
56 8         33 $signature .= sprintf("%s,", $_->signature) for $self->_instances->@*;
57 8         23 chop $signature;
58 8         124 return $signature . ')';
59             }
60              
61             sub encode_function_signature {
62 8     8 1 21 my ($self, $signature) = @_;
63 8   33     38 return sprintf("0x%.8s", keccak_256_hex($signature // $self->generate_function_signature));
64             }
65              
66             sub encode {
67 14     14 1 30 my $self = shift;
68              
69 14         65 my $tuple = Blockchain::Contract::Solidity::ABI::Type::Tuple->new;
70 14         49 $tuple->{instances} = $self->_instances;
71 14         45 my @data = $tuple->encode->@*;
72 8 50       38 unshift @data, $self->encode_function_signature if $self->function_name;
73              
74 8         36 $self->_clean;
75              
76 8         245 return join('', @data);
77             }
78              
79             sub _clean {
80 15     15   5101 my $self = shift;
81 15         51 delete $self->{instances};
82 15         40 undef $self->{function_name};
83             }
84              
85             1;
86              
87             __END__