line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package App::Bitcoin::PaperWallet; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = '1.01'; |
4
|
|
|
|
|
|
|
|
5
|
2
|
|
|
2
|
|
151190
|
use v5.12; |
|
2
|
|
|
|
|
18
|
|
6
|
2
|
|
|
2
|
|
16
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
102
|
|
7
|
|
|
|
|
|
|
|
8
|
2
|
|
|
2
|
|
1111
|
use Bitcoin::Crypto qw(btc_extprv); |
|
2
|
|
|
|
|
667
|
|
|
2
|
|
|
|
|
114
|
|
9
|
2
|
|
|
2
|
|
1203
|
use Digest::SHA qw(sha256); |
|
2
|
|
|
|
|
6953
|
|
|
2
|
|
|
|
|
627
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
sub get_addresses |
12
|
|
|
|
|
|
|
{ |
13
|
1
|
|
|
1
|
0
|
4
|
my ($key, $count) = @_; |
14
|
1
|
|
50
|
|
|
9
|
$count //= 4; |
15
|
|
|
|
|
|
|
|
16
|
1
|
|
|
|
|
2
|
my @addrs; |
17
|
1
|
|
|
|
|
8
|
my $priv = $key->derive_key_bip44(index => 0)->get_basic_key; |
18
|
1
|
|
|
|
|
55062
|
my $addr = $priv->get_public_key->get_compat_address; |
19
|
1
|
|
|
|
|
12172
|
push @addrs, $addr; |
20
|
|
|
|
|
|
|
|
21
|
1
|
|
|
|
|
8
|
for my $ind (1 .. $count - 1) { |
22
|
3
|
|
|
|
|
32
|
my $priv = $key->derive_key_bip44(index => $ind)->get_basic_key; |
23
|
3
|
|
|
|
|
139984
|
my $addr = $priv->get_public_key->get_segwit_address; |
24
|
3
|
|
|
|
|
15321
|
push @addrs, $addr; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
|
27
|
1
|
|
|
|
|
46
|
return @addrs; |
28
|
|
|
|
|
|
|
} |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub generate |
31
|
|
|
|
|
|
|
{ |
32
|
1
|
|
|
1
|
1
|
101
|
my ($class, $entropy, $pass, $address_count) = @_; |
33
|
|
|
|
|
|
|
|
34
|
1
|
50
|
|
|
|
10
|
my $mnemonic = defined $entropy |
35
|
|
|
|
|
|
|
? btc_extprv->mnemonic_from_entropy(sha256($entropy)) |
36
|
|
|
|
|
|
|
: btc_extprv->generate_mnemonic(256) |
37
|
|
|
|
|
|
|
; |
38
|
|
|
|
|
|
|
|
39
|
1
|
|
|
|
|
545482
|
my $key = btc_extprv->from_mnemonic($mnemonic, $pass); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
return { |
42
|
1
|
|
|
|
|
30069
|
mnemonic => $mnemonic, |
43
|
|
|
|
|
|
|
addresses => [get_addresses($key, $address_count)], |
44
|
|
|
|
|
|
|
}; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
1; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
__END__ |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=head1 NAME |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
App::Bitcoin::PaperWallet - Generate printable cold storage of bitcoins |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 SYNOPSIS |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
use App::Bitcoin::PaperWallet; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
my $hash = App::Bitcoin::PaperWallet->generate($entropy, $password, $address_count // 4); |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
my $mnemonic = $hash->{mnemonic}; |
62
|
|
|
|
|
|
|
my $addresses = $hash->{addresses}; |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
=head1 DESCRIPTION |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
This module allows you to generate a Hierarchical Deterministic BIP44 compilant Bitcoin wallet. |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
This package contains high level cryptographic operations for doing that. See L<paper-wallet> for the main script of this distribution. |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=head1 FUNCTIONS |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=head2 generate |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
my $hash = App::Bitcoin::PaperWallet->generate($entropy, $password, $address_count // 4); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
Not exported, should be used as a class method. Returns a hash containing two keys: C<mnemonic> (string) and C<addresses> (array reference of strings). |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
C<$entropy> is meant to be user-defined entropy (string) that will be passed through sha256 to obtain wallet seed. Can be passed C<undef> explicitly to use cryptographically secure random number generator instead. |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
C<$password> is a password that will be used to secure the generated mnemonic. Passing empty string will disable the password protection. Note that password does not have to be strong, since it will only secure the mnemonic in case someone obtained physical access to your mnemonic. Using a hard, long password increases the possibility you will not be able to claim your bitcoins in the future. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
Optional C<$address_count> is the number of addresses that will be generated (default 4). The first address is always SegWit compat address, while the rest are SegWit native addresses. |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=head1 SEE ALSO |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
L<Bitcoin::Crypto> |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head1 AUTHOR |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
Bartosz Jarzyna, E<lt>brtastic.dev@gmail.comE<gt> |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
Copyright (C) 2021 by Bartosz Jarzyna |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
97
|
|
|
|
|
|
|
it under the same terms as Perl itself, either Perl version 5.12.0 or, |
98
|
|
|
|
|
|
|
at your option, any later version of Perl 5 you may have available. |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=cut |