File Coverage

blib/lib/Blockchain/Ethereum/Utils.pm
Criterion Covered Total %
statement 37 37 100.0
branch 8 8 100.0
condition 3 3 100.0
subroutine 14 14 100.0
pod 2 2 100.0
total 64 64 100.0


line stmt bran cond sub pod time code
1             package Blockchain::Ethereum::Utils;
2              
3 5     5   374560 use v5.26;
  5         19  
4 5     5   35 use strict;
  5         10  
  5         168  
5 5     5   22 use warnings;
  5         9  
  5         426  
6              
7             # ABSTRACT: Utility functions for Ethereum operations
8             our $AUTHORITY = 'cpan:REFECO'; # AUTHORITY
9             our $VERSION = '0.021'; # VERSION
10              
11 5     5   74 use Carp;
  5         12  
  5         429  
12 5     5   3699 use Math::BigInt;
  5         97315  
  5         38  
13 5     5   74537 use Math::BigFloat;
  5         216304  
  5         26  
14 5     5   734 use Scalar::Util qw(looks_like_number);
  5         9  
  5         312  
15 5     5   27 use Exporter 'import';
  5         13  
  5         312  
16              
17             our @EXPORT = qw(
18             parse_units format_units
19             WEI KWEI MWEI GWEI SZABO FINNEY ETHER ETH
20             );
21              
22             use constant {
23 5         2666 WEI => 0,
24             KWEI => 3,
25             MWEI => 6,
26             GWEI => 9,
27             SZABO => 12,
28             FINNEY => 15,
29             ETHER => 18,
30             ETH => 18, # alias for ether
31 5     5   27 };
  5         10  
32              
33             my %ETHEREUM_UNITS = (
34             'wei' => WEI,
35             'kwei' => KWEI,
36             'mwei' => MWEI,
37             'gwei' => GWEI,
38             'szabo' => SZABO,
39             'finney' => FINNEY,
40             'ether' => ETHER,
41             'eth' => ETH,
42             );
43              
44             sub _process_units {
45 99     99   248 my ($value, $unit, $processor) = @_;
46              
47 99 100 100     1737 croak "Invalid number format" unless defined $value && looks_like_number($value);
48 93 100       319 croak "Unknown unit" unless defined $unit;
49              
50             my $decimals =
51             $unit =~ /^\d+$/ ? $unit
52 92 100       1081 : exists $ETHEREUM_UNITS{lc($unit)} ? $ETHEREUM_UNITS{lc($unit)}
    100          
53             : croak "Unknown unit";
54              
55 89         443 return $processor->(Math::BigFloat->new($value), Math::BigInt->new(10)->bpow($decimals));
56             }
57              
58             sub parse_units {
59 60     60 1 886836 my ($value, $unit) = @_;
60 60     53   440 return _process_units($value, $unit, sub { Math::BigInt->new($_[0]->bmul($_[1]))->bstr() });
  53         40617  
61             }
62              
63             sub format_units {
64 39     39 1 62226 my ($value, $unit) = @_;
65 39     36   240 return _process_units($value, $unit, sub { $_[0]->bdiv($_[1])->bstr() });
  36         27378  
66             }
67              
68             1;
69              
70             __END__