money-tree 0.8.4 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/money-tree/address.rb +4 -3
- data/lib/money-tree/key.rb +43 -13
- data/lib/money-tree/networks.rb +8 -6
- data/lib/money-tree/node.rb +27 -16
- data/lib/money-tree/version.rb +1 -1
- data/spec/lib/money-tree/address_spec.rb +10 -0
- data/spec/lib/money-tree/node_spec.rb +53 -1
- data/spec/lib/money-tree/private_key_spec.rb +12 -0
- data/spec/lib/money-tree/public_key_spec.rb +23 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed8522c0f961d7b6556cc9067455f12d65bcfd0f
|
4
|
+
data.tar.gz: 02857ab85d9b22a1a96c71f6d47c957a9310eb23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9d8647c31dccee3b9c34ad46e533bbd0cd37c8407402caa1356e8282b3e3e422637b69ebbee42a840c64948ccca8e9d5479fb0a260fa7d8508790210f9317ae
|
7
|
+
data.tar.gz: 22fbe674fbb0919ced227c8d3bd5f9f554b76726fca29442b2dd545c810f05e9dd5b97fa1f2f2ceaedaeb06e8b58f7b2c6bcb8f8e6d57e4d1103cc3c250369ac
|
data/lib/money-tree/address.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module MoneyTree
|
2
2
|
class Address
|
3
|
-
|
3
|
+
attr_reader :private_key, :public_key
|
4
4
|
|
5
5
|
def initialize(opts = {})
|
6
|
-
|
7
|
-
@
|
6
|
+
private_key = opts.delete(:private_key)
|
7
|
+
@private_key = MoneyTree::PrivateKey.new({ key: private_key }.merge(opts))
|
8
|
+
@public_key = MoneyTree::PublicKey.new(@private_key, opts)
|
8
9
|
end
|
9
10
|
|
10
11
|
def to_s
|
data/lib/money-tree/key.rb
CHANGED
@@ -15,7 +15,7 @@ module MoneyTree
|
|
15
15
|
class InvalidWIFFormat < Exception; end
|
16
16
|
class InvalidBase64Format < Exception; end
|
17
17
|
|
18
|
-
attr_reader :options, :key, :raw_key
|
18
|
+
attr_reader :options, :key, :raw_key, :network, :network_key
|
19
19
|
attr_accessor :ec_key
|
20
20
|
|
21
21
|
GROUP_NAME = 'secp256k1'
|
@@ -40,6 +40,8 @@ module MoneyTree
|
|
40
40
|
def initialize(opts = {})
|
41
41
|
@options = opts
|
42
42
|
@ec_key = PKey::EC.new GROUP_NAME
|
43
|
+
@network_key = options[:network] || :bitcoin
|
44
|
+
@network = MoneyTree::NETWORKS[network_key]
|
43
45
|
if @options[:key]
|
44
46
|
@raw_key = @options[:key]
|
45
47
|
@key = parse_raw_key
|
@@ -71,8 +73,8 @@ module MoneyTree
|
|
71
73
|
end
|
72
74
|
|
73
75
|
def parse_raw_key
|
74
|
-
result = if raw_key.is_a?(Bignum) then
|
75
|
-
elsif hex_format? then
|
76
|
+
result = if raw_key.is_a?(Bignum) then from_bignum
|
77
|
+
elsif hex_format? then from_hex
|
76
78
|
elsif base64_format? then from_base64
|
77
79
|
elsif compressed_wif_format? then from_wif
|
78
80
|
elsif uncompressed_wif_format? then from_wif
|
@@ -81,28 +83,52 @@ module MoneyTree
|
|
81
83
|
end
|
82
84
|
result.downcase
|
83
85
|
end
|
86
|
+
|
87
|
+
def from_bignum(bignum = raw_key)
|
88
|
+
int_to_hex(bignum)
|
89
|
+
end
|
90
|
+
|
91
|
+
def from_hex(hex = raw_key)
|
92
|
+
hex
|
93
|
+
end
|
84
94
|
|
85
95
|
def from_wif(wif = raw_key)
|
86
96
|
compressed = wif.length == 52
|
97
|
+
parse_network_from_wif(wif, compressed: compressed)
|
87
98
|
validate_wif(wif)
|
88
99
|
hex = decode_base58(wif)
|
89
100
|
last_char = compressed ? -11 : -9
|
90
101
|
hex.slice(2..last_char)
|
91
102
|
end
|
103
|
+
|
104
|
+
def parse_network_from_wif(wif, opts = {})
|
105
|
+
networks = MoneyTree::NETWORKS
|
106
|
+
chars_key = opts[:compressed] ? :compressed_wif_chars : :uncompressed_wif_chars
|
107
|
+
@network_key = networks.keys.select do |k|
|
108
|
+
networks[k][chars_key].include?(wif.slice(0))
|
109
|
+
end.first
|
110
|
+
@network = networks[network_key]
|
111
|
+
end
|
92
112
|
|
93
113
|
def from_base64(base64_key = raw_key)
|
94
114
|
raise InvalidBase64Format unless base64_format?(base64_key)
|
95
115
|
decode_base64(base64_key)
|
96
116
|
end
|
97
|
-
|
117
|
+
|
98
118
|
def compressed_wif_format?
|
99
|
-
|
119
|
+
wif_format?(:compressed)
|
100
120
|
end
|
101
121
|
|
102
122
|
def uncompressed_wif_format?
|
103
|
-
|
123
|
+
wif_format?(:uncompressed)
|
104
124
|
end
|
105
|
-
|
125
|
+
|
126
|
+
def wif_format?(compression)
|
127
|
+
length = compression == :compressed ? 52 : 51
|
128
|
+
wif_prefixes = MoneyTree::NETWORKS.map {|k, v| v["#{compression}_wif_chars".to_sym]}.flatten
|
129
|
+
raw_key.length == length && wif_prefixes.include?(raw_key.slice(0))
|
130
|
+
end
|
131
|
+
|
106
132
|
def base64_format?(base64_key = raw_key)
|
107
133
|
base64_key.length == 44 && base64_key =~ /^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/
|
108
134
|
end
|
@@ -117,8 +143,8 @@ module MoneyTree
|
|
117
143
|
|
118
144
|
def to_wif(opts = {})
|
119
145
|
opts[:compressed] = true unless opts[:compressed] == false
|
120
|
-
source =
|
121
|
-
source +=
|
146
|
+
source = network[:privkey_version] + to_hex
|
147
|
+
source += network[:privkey_compression_flag] if opts[:compressed]
|
122
148
|
hash = sha256(source)
|
123
149
|
hash = sha256(hash)
|
124
150
|
checksum = hash.slice(0..7)
|
@@ -128,7 +154,7 @@ module MoneyTree
|
|
128
154
|
|
129
155
|
def wif_valid?(wif)
|
130
156
|
hex = decode_base58(wif)
|
131
|
-
return false unless hex.slice(0..1) ==
|
157
|
+
return false unless hex.slice(0..1) == network[:privkey_version]
|
132
158
|
checksum = hex.chars.to_a.pop(8).join
|
133
159
|
source = hex.slice(0..-9)
|
134
160
|
hash = sha256(source)
|
@@ -160,10 +186,14 @@ module MoneyTree
|
|
160
186
|
|
161
187
|
if p_key.is_a?(PrivateKey)
|
162
188
|
@private_key = p_key
|
189
|
+
@network_key = private_key.network_key
|
190
|
+
@network = MoneyTree::NETWORKS[network_key]
|
163
191
|
@point = @private_key.calculate_public_key(@options)
|
164
192
|
@group = @point.group
|
165
193
|
@key = @raw_key = to_hex
|
166
194
|
else
|
195
|
+
@network_key = @options[:network] || :bitcoin
|
196
|
+
@network = MoneyTree::NETWORKS[network_key]
|
167
197
|
@raw_key = p_key
|
168
198
|
@group = PKey::EC::Group.new GROUP_NAME
|
169
199
|
@key = parse_raw_key
|
@@ -180,13 +210,13 @@ module MoneyTree
|
|
180
210
|
end
|
181
211
|
|
182
212
|
def compressed
|
183
|
-
compressed_key = self.class.new raw_key # deep clone
|
213
|
+
compressed_key = self.class.new raw_key, options # deep clone
|
184
214
|
compressed_key.set_point to_i, compressed: true
|
185
215
|
compressed_key
|
186
216
|
end
|
187
217
|
|
188
218
|
def uncompressed
|
189
|
-
uncompressed_key = self.class.new raw_key # deep clone
|
219
|
+
uncompressed_key = self.class.new raw_key, options # deep clone
|
190
220
|
uncompressed_key.set_point to_i, compressed: false
|
191
221
|
uncompressed_key
|
192
222
|
end
|
@@ -236,7 +266,7 @@ module MoneyTree
|
|
236
266
|
|
237
267
|
def to_address
|
238
268
|
hash = to_ripemd160
|
239
|
-
address =
|
269
|
+
address = network[:address_version] + hash
|
240
270
|
to_serialized_base58 address
|
241
271
|
end
|
242
272
|
alias :to_s :to_address
|
data/lib/money-tree/networks.rb
CHANGED
@@ -3,24 +3,26 @@ module MoneyTree
|
|
3
3
|
bitcoin: {
|
4
4
|
address_version: '00',
|
5
5
|
p2sh_version: '05',
|
6
|
+
p2sh_char: '3',
|
6
7
|
privkey_version: '80',
|
7
8
|
privkey_compression_flag: '01',
|
8
9
|
extended_privkey_version: "0488ade4",
|
9
10
|
extended_pubkey_version: "0488b21e",
|
10
11
|
compressed_wif_chars: %w(K L),
|
11
|
-
|
12
|
+
uncompressed_wif_chars: %w(5),
|
12
13
|
protocol_version: 70001
|
13
14
|
},
|
14
15
|
bitcoin_testnet: {
|
15
16
|
address_version: '6f',
|
16
|
-
p2sh_version: '
|
17
|
-
|
17
|
+
p2sh_version: 'c4',
|
18
|
+
p2sh_char: '2',
|
19
|
+
privkey_version: 'ef',
|
18
20
|
privkey_compression_flag: '01',
|
19
21
|
extended_privkey_version: "04358394",
|
20
22
|
extended_pubkey_version: "043587cf",
|
21
|
-
compressed_wif_chars: %w(
|
22
|
-
|
23
|
+
compressed_wif_chars: %w(c),
|
24
|
+
uncompressed_wif_chars: %w(9),
|
23
25
|
protocol_version: 70001
|
24
26
|
}
|
25
27
|
}
|
26
|
-
end
|
28
|
+
end
|
data/lib/money-tree/node.rb
CHANGED
@@ -2,7 +2,7 @@ module MoneyTree
|
|
2
2
|
class Node
|
3
3
|
include Support
|
4
4
|
extend Support
|
5
|
-
attr_reader :private_key, :public_key, :chain_code, :is_private, :depth, :index, :parent, :
|
5
|
+
attr_reader :private_key, :public_key, :chain_code, :is_private, :depth, :index, :parent, :network, :network_key
|
6
6
|
|
7
7
|
class PublicDerivationFailure < Exception; end
|
8
8
|
class InvalidKeyForIndex < Exception; end
|
@@ -10,6 +10,8 @@ module MoneyTree
|
|
10
10
|
class PrivatePublicMismatch < Exception; end
|
11
11
|
|
12
12
|
def initialize(opts = {})
|
13
|
+
@network_key = opts.delete(:network) || :bitcoin
|
14
|
+
@network = MoneyTree::NETWORKS[network_key]
|
13
15
|
opts.each { |k, v| instance_variable_set "@#{k}", v }
|
14
16
|
end
|
15
17
|
|
@@ -17,7 +19,6 @@ module MoneyTree
|
|
17
19
|
hex = from_serialized_base58 address
|
18
20
|
version = from_version_hex hex.slice!(0..7)
|
19
21
|
self.new({
|
20
|
-
is_test: version[:test],
|
21
22
|
depth: hex.slice!(0..1).to_i(16),
|
22
23
|
fingerprint: hex.slice!(0..7),
|
23
24
|
index: hex.slice!(0..7).to_i(16),
|
@@ -26,11 +27,12 @@ module MoneyTree
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def self.key_options(hex, version)
|
30
|
+
k_opts = { network: version[:network] }
|
29
31
|
if version[:private_key] && hex.slice(0..1) == '00'
|
30
|
-
private_key = MoneyTree::PrivateKey.new key: hex.slice(2..-1)
|
31
|
-
|
32
|
+
private_key = MoneyTree::PrivateKey.new({ key: hex.slice(2..-1) }.merge(k_opts))
|
33
|
+
k_opts.merge private_key: private_key, public_key: MoneyTree::PublicKey.new(private_key)
|
32
34
|
elsif %w(02 03).include? hex.slice(0..1)
|
33
|
-
|
35
|
+
k_opts.merge public_key: MoneyTree::PublicKey.new(hex, k_opts)
|
34
36
|
else
|
35
37
|
raise ImportError, 'Public or private key data does not match version type'
|
36
38
|
end
|
@@ -39,13 +41,13 @@ module MoneyTree
|
|
39
41
|
def self.from_version_hex(hex)
|
40
42
|
case hex
|
41
43
|
when MoneyTree::NETWORKS[:bitcoin][:extended_privkey_version]
|
42
|
-
{ private_key: true,
|
44
|
+
{ private_key: true, network: :bitcoin }
|
43
45
|
when MoneyTree::NETWORKS[:bitcoin][:extended_pubkey_version]
|
44
|
-
{ private_key: false,
|
46
|
+
{ private_key: false, network: :bitcoin }
|
45
47
|
when MoneyTree::NETWORKS[:bitcoin_testnet][:extended_privkey_version]
|
46
|
-
{ private_key: true,
|
48
|
+
{ private_key: true, network: :bitcoin_testnet }
|
47
49
|
when MoneyTree::NETWORKS[:bitcoin_testnet][:extended_pubkey_version]
|
48
|
-
{ private_key: false,
|
50
|
+
{ private_key: false, network: :bitcoin_testnet }
|
49
51
|
else
|
50
52
|
raise ImportError, 'invalid version bytes'
|
51
53
|
end
|
@@ -114,7 +116,7 @@ module MoneyTree
|
|
114
116
|
def to_serialized_hex(type = :public)
|
115
117
|
raise PrivatePublicMismatch if type.to_sym == :private && private_key.nil?
|
116
118
|
version_key = type.to_sym == :private ? :extended_privkey_version : :extended_pubkey_version
|
117
|
-
hex =
|
119
|
+
hex = network[version_key] # version (4 bytes)
|
118
120
|
hex += depth_hex(depth) # depth (1 byte)
|
119
121
|
hex += depth.zero? ? '00000000' : parent.to_fingerprint# fingerprint of key (4 bytes)
|
120
122
|
hex += index_hex(index) # child number i (4 bytes)
|
@@ -136,21 +138,22 @@ module MoneyTree
|
|
136
138
|
end
|
137
139
|
|
138
140
|
def to_address
|
139
|
-
address =
|
141
|
+
address = network[:address_version] + to_identifier
|
140
142
|
to_serialized_base58 address
|
141
143
|
end
|
142
144
|
|
143
145
|
def subnode(i = 0, opts = {})
|
144
146
|
if private_key.nil?
|
145
147
|
child_public_key, child_chain_code = derive_public_key(i)
|
146
|
-
child_public_key = MoneyTree::PublicKey.new child_public_key
|
148
|
+
child_public_key = MoneyTree::PublicKey.new child_public_key, network: network_key
|
147
149
|
else
|
148
150
|
child_private_key, child_chain_code = derive_private_key(i)
|
149
|
-
child_private_key = MoneyTree::PrivateKey.new key: child_private_key
|
151
|
+
child_private_key = MoneyTree::PrivateKey.new key: child_private_key, network: network_key
|
150
152
|
child_public_key = MoneyTree::PublicKey.new child_private_key
|
151
153
|
end
|
152
154
|
|
153
|
-
MoneyTree::Node.new
|
155
|
+
MoneyTree::Node.new network: network_key,
|
156
|
+
depth: depth+1,
|
154
157
|
index: i,
|
155
158
|
private_key: private_key.nil? ? nil : child_private_key,
|
156
159
|
public_key: child_public_key,
|
@@ -233,6 +236,8 @@ module MoneyTree
|
|
233
236
|
@depth = 0
|
234
237
|
@index = 0
|
235
238
|
opts[:seed] = [opts[:seed_hex]].pack("H*") if opts[:seed_hex]
|
239
|
+
@network_key = opts[:network] || :bitcoin
|
240
|
+
@network = MoneyTree::NETWORKS[network_key]
|
236
241
|
if opts[:seed]
|
237
242
|
@seed = opts[:seed]
|
238
243
|
@seed_hash = generate_seed_hash(@seed)
|
@@ -243,9 +248,15 @@ module MoneyTree
|
|
243
248
|
@chain_code = opts[:chain_code]
|
244
249
|
if opts[:private_key]
|
245
250
|
@private_key = opts[:private_key]
|
251
|
+
@network_key = @private_key.network_key
|
252
|
+
@network = MoneyTree::NETWORKS[network_key]
|
246
253
|
@public_key = MoneyTree::PublicKey.new @private_key
|
247
254
|
else opts[:public_key]
|
248
|
-
@public_key = opts[:public_key].is_a?(MoneyTree::PublicKey)
|
255
|
+
@public_key = if opts[:public_key].is_a?(MoneyTree::PublicKey)
|
256
|
+
opts[:public_key]
|
257
|
+
else
|
258
|
+
MoneyTree::PublicKey.new(opts[:public_key], network: network_key)
|
259
|
+
end
|
249
260
|
end
|
250
261
|
else
|
251
262
|
generate_seed
|
@@ -274,7 +285,7 @@ module MoneyTree
|
|
274
285
|
end
|
275
286
|
|
276
287
|
def set_seeded_keys
|
277
|
-
@private_key = MoneyTree::PrivateKey.new key: left_from_hash(seed_hash)
|
288
|
+
@private_key = MoneyTree::PrivateKey.new key: left_from_hash(seed_hash), network: network_key
|
278
289
|
@chain_code = right_from_hash(seed_hash)
|
279
290
|
@public_key = MoneyTree::PublicKey.new @private_key
|
280
291
|
end
|
data/lib/money-tree/version.rb
CHANGED
@@ -49,4 +49,14 @@ describe MoneyTree::Address do
|
|
49
49
|
@address.private_key.to_s.should == "KzPkwAXJ4wtXHnbamTaJqoMrzwCUUJaqhUxnqYhnZvZH6KhgmDPK"
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
context "testnet3" do
|
54
|
+
before do
|
55
|
+
@address = MoneyTree::Address.new network: :bitcoin_testnet
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns a testnet address" do
|
59
|
+
%w(m n).should include(@address.to_s[0])
|
60
|
+
end
|
61
|
+
end
|
52
62
|
end
|
@@ -12,7 +12,59 @@ describe MoneyTree::Master do
|
|
12
12
|
@master.seed.bytesize.should == 32
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
|
+
context "testnet" do
|
17
|
+
before do
|
18
|
+
@master = MoneyTree::Master.new network: :bitcoin_testnet
|
19
|
+
end
|
20
|
+
|
21
|
+
it "generates testnet address" do
|
22
|
+
%w(m n).should include(@master.to_address[0])
|
23
|
+
end
|
24
|
+
|
25
|
+
it "generates testnet compressed wif" do
|
26
|
+
@master.private_key.to_wif[0].should == 'c'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "generates testnet uncompressed wif" do
|
30
|
+
@master.private_key.to_wif(compressed: false)[0].should == '9'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "generates testnet serialized private address" do
|
34
|
+
@master.to_serialized_address(:private).slice(0, 4).should == "tprv"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "generates testnet serialized public address" do
|
38
|
+
@master.to_serialized_address.slice(0, 4).should == "tpub"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "imports from testnet serialized private address" do
|
42
|
+
node = MoneyTree::Node.from_serialized_address 'tprv8ZgxMBicQKsPcuN7bfUZqq78UEYapr3Tzmc9NcDXw8BnBJ47dZYr6SusnfYj7vbAYP9CP8ZiD5aVBTUo1yU5QP56mepKVvuEbu8KZQXMKNE'
|
43
|
+
node.to_serialized_address(:private).should == 'tprv8ZgxMBicQKsPcuN7bfUZqq78UEYapr3Tzmc9NcDXw8BnBJ47dZYr6SusnfYj7vbAYP9CP8ZiD5aVBTUo1yU5QP56mepKVvuEbu8KZQXMKNE'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "imports from testnet serialized public address" do
|
47
|
+
node = MoneyTree::Node.from_serialized_address 'tpubD6NzVbkrYhZ4YA8aUE9bBZTSyHJibBqwDny5urfwDdJc4W8od3y3Ebzy6CqsYn9CCC5P5VQ7CeZYpnT1kX3RPVPysU2rFRvYSj8BCoYYNqT'
|
48
|
+
%w(m n).should include(node.public_key.to_s[0])
|
49
|
+
node.to_serialized_address.should == 'tpubD6NzVbkrYhZ4YA8aUE9bBZTSyHJibBqwDny5urfwDdJc4W8od3y3Ebzy6CqsYn9CCC5P5VQ7CeZYpnT1kX3RPVPysU2rFRvYSj8BCoYYNqT'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "generates testnet subnodes from serialized private address" do
|
53
|
+
node = MoneyTree::Node.from_serialized_address 'tprv8ZgxMBicQKsPcuN7bfUZqq78UEYapr3Tzmc9NcDXw8BnBJ47dZYr6SusnfYj7vbAYP9CP8ZiD5aVBTUo1yU5QP56mepKVvuEbu8KZQXMKNE'
|
54
|
+
subnode = node.node_for_path('1/1/1')
|
55
|
+
%w(m n).should include(subnode.public_key.to_s[0])
|
56
|
+
subnode.to_serialized_address(:private).slice(0,4).should == 'tprv'
|
57
|
+
subnode.to_serialized_address.slice(0,4).should == 'tpub'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "generates testnet subnodes from serialized public address" do
|
61
|
+
node = MoneyTree::Node.from_serialized_address 'tpubD6NzVbkrYhZ4YA8aUE9bBZTSyHJibBqwDny5urfwDdJc4W8od3y3Ebzy6CqsYn9CCC5P5VQ7CeZYpnT1kX3RPVPysU2rFRvYSj8BCoYYNqT'
|
62
|
+
subnode = node.node_for_path('1/1/1')
|
63
|
+
%w(m n).should include(subnode.public_key.to_s[0])
|
64
|
+
subnode.to_serialized_address.slice(0,4).should == 'tpub'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
16
68
|
describe "Test vector 1" do
|
17
69
|
describe "from a seed" do
|
18
70
|
before do
|
@@ -91,4 +91,16 @@ describe MoneyTree::PrivateKey do
|
|
91
91
|
|
92
92
|
end
|
93
93
|
end
|
94
|
+
|
95
|
+
context "testnet" do
|
96
|
+
before do
|
97
|
+
@key = MoneyTree::PrivateKey.new key: 'cRhes8SBnsF6WizphaRKQKZZfDniDa9Bxcw31yKeEC1KDExhxFgD'
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "to_wif" do
|
101
|
+
it "returns same wif" do
|
102
|
+
@key.to_wif.should == 'cRhes8SBnsF6WizphaRKQKZZfDniDa9Bxcw31yKeEC1KDExhxFgD'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
94
106
|
end
|
@@ -157,4 +157,27 @@ describe MoneyTree::PublicKey do
|
|
157
157
|
before_str.should == after_str
|
158
158
|
end
|
159
159
|
end
|
160
|
+
|
161
|
+
context "testnet" do
|
162
|
+
context 'with private key' do
|
163
|
+
before do
|
164
|
+
@private_key = MoneyTree::PrivateKey.new network: :bitcoin_testnet
|
165
|
+
@key = MoneyTree::PublicKey.new(@private_key)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should have an address starting with m or n" do
|
169
|
+
%w(m n).should include(@key.to_s[0])
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'without private key' do
|
174
|
+
before do
|
175
|
+
@key = MoneyTree::PublicKey.new('0297b033ba894611345a0e777861237ef1632370fbd58ebe644eb9f3714e8fe2bc', network: :bitcoin_testnet)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should have an address starting with m or n" do
|
179
|
+
%w(m n).should include(@key.to_s[0])
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
160
183
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: money-tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micah Winkelspecht
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|