money-tree 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -4
- data/lib/money-tree/node.rb +1 -0
- data/lib/money-tree/version.rb +1 -1
- data/spec/lib/money-tree/support_spec.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c440022c70d98f3f615a3b196094058bc28eae1
|
4
|
+
data.tar.gz: 1633093d7c5d4dced6a636d90767e45cb90e0131
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bae317b7a5007778220c746977d70634c6549dfafa8acd49819699d84d195c48554dd5290422c827a4ef48bfd09b19dfbf0a34abc5ca62c88b6d966eda6ead88
|
7
|
+
data.tar.gz: 0f77e37af78cd891f7871b89fc913395a3a12fa98e44b372497bb9211b34be2ab51d9a00348f7265a12d72625dba17df92a4b3d2b4953d30bdf1769f65f984ec
|
data/README.md
CHANGED
@@ -62,18 +62,20 @@ These instructions assume you have a decent understanding of how Bitcoin wallets
|
|
62
62
|
|
63
63
|
To create a new HD Wallet, we're going to create a tree structure of private/public keypairs (nodes). You'll first want to start with a master node. This master node should be seeded with at least 16 random bytes but preferably 32 random bytes from a cryptographically secure PRNG (pseudo-random number generator).
|
64
64
|
|
65
|
-
DO NOT use a user generated password. Keep in mind that whoever controls the seed controls ALL coins in the entire tree, so it should not be left up to a human brain, because humans tend to follow patterns and patterns are subject to brute force attacks. Luckily,
|
65
|
+
DO NOT use a user generated password. Keep in mind that whoever controls the seed controls ALL coins in the entire tree, so it should not be left up to a human brain, because humans tend to follow patterns and patterns are subject to brute force attacks. Luckily, MoneyTree includes the seed generation by default so you don't need to create this on your own.
|
66
66
|
|
67
67
|
```ruby
|
68
68
|
# Create a new master node (with automatic seed generation)
|
69
69
|
@master = MoneyTree::Master.new
|
70
70
|
=> MoneyTree::Master instance
|
71
|
+
|
71
72
|
@master.seed
|
72
73
|
=> "N\xC5\x9DD\xAA\xCC\x80a\a\x96%8\xC8\x86\x81\x90\t\x82&\xE4\x97Ay\xECs\xD8\xB1M\xEA\xE6|\xEF"
|
73
74
|
|
74
75
|
# Or import an existing seed
|
75
76
|
@master = MoneyTree::Master.new seed_hex: "000102030405060708090a0b0c0d0e0f"
|
76
77
|
=> MoneyTree::Master instance
|
78
|
+
|
77
79
|
@master.seed
|
78
80
|
=> "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0E\x0F"
|
79
81
|
```
|
@@ -85,28 +87,40 @@ DO NOT use a user generated password. Keep in mind that whoever controls the see
|
|
85
87
|
# Here are some things you can do with a node.
|
86
88
|
@master.index # The index is a sequential identifier in relation to its parent node. (i.e. the nth child of its parent)
|
87
89
|
=> 0
|
90
|
+
|
88
91
|
@master.depth # How many steps down the tree this node is. (The master node is at depth 0, its direct child is at depth 1, and so on...)
|
89
92
|
=> 0
|
93
|
+
|
90
94
|
@master.to_identifier
|
91
95
|
=> "3442193e1bb70916e914552172cd4e2dbc9df811"
|
96
|
+
|
92
97
|
@master.to_fingerprint
|
93
98
|
=> "3442193e"
|
99
|
+
|
94
100
|
@master.to_address
|
95
101
|
=> "15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma"
|
102
|
+
|
96
103
|
@master.private_key.to_hex
|
97
104
|
=> "e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35"
|
105
|
+
|
98
106
|
@master.private_key.to_wif
|
99
107
|
=> "L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW"
|
108
|
+
|
100
109
|
@master.public_key.to_hex
|
101
110
|
=> "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2"
|
111
|
+
|
102
112
|
@master.chain_code_hex
|
103
113
|
=> "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508" # Look up chain codes in the BIP0032 spec
|
114
|
+
|
104
115
|
@master.to_serialized_hex(:private)
|
105
116
|
=> "0488ade4000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d50800e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35"
|
117
|
+
|
106
118
|
@master.to_serialized_address(:private)
|
107
119
|
=> "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
|
120
|
+
|
108
121
|
@master.to_serialized_hex
|
109
122
|
=> "0488b21e000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d5080339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2"
|
123
|
+
|
110
124
|
@master.to_serialized_address
|
111
125
|
=> "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"
|
112
126
|
```
|
@@ -119,12 +133,16 @@ To generate a child node from a given path:
|
|
119
133
|
```ruby
|
120
134
|
@node = @master.node_for_path "m/0/3"
|
121
135
|
=> MoneyTree::Node instance
|
136
|
+
|
122
137
|
@node.index
|
123
138
|
=> 3
|
139
|
+
|
124
140
|
@node.depth
|
125
141
|
=> 2
|
142
|
+
|
126
143
|
@node.to_serialized_address(:private)
|
127
144
|
=> "xprv9ww7sMFLzJN15m7zX5JEBXQrQq8h4fU8PVqd929Hjy3xNSMzeBf163idMNBSq47DdCakyZTK7KcC2nbz3jqUkpJj8ZR4FqrijcFcFmcoBAe"
|
145
|
+
|
128
146
|
@node.to_serialized_address
|
129
147
|
=> "xpub6AvUGrnEpfvJJFCTd6qEYfMaxryBU8BykimDwQYuJJawFEh9BiyFdr37Cc4wEKCWWv7TsFQRUMdezXVqV9cfBUbeUEgNYCCP4omxULbNaRr"
|
130
148
|
```
|
@@ -135,11 +153,14 @@ In HD wallets, chain codes are the mathematical glue that binds a parent node to
|
|
135
153
|
You don't need to worry about chain codes if you are creating or importing from a Master key (it's always the same for all HD wallet master keys), however if you are trying to import a derived child key at some lower depth in the tree, you'll need the chain code. Luckily, whenever we export a node to a wallet file, we encode it in a special format that includes all of the relevant info (including chain code) that we need to reconstruct the node in a single convenient serialized address.
|
136
154
|
|
137
155
|
#### Serialized Addresses
|
138
|
-
Beacause we need multiple pieces of info to reconstruct nodes in a tree, when we're dealing with HD wallets, we pass around a serialized address format that encodes both the key and the chain code. It
|
156
|
+
Beacause we need multiple pieces of info to reconstruct nodes in a tree, when we're dealing with HD wallets, we pass around a serialized address format that encodes both the key and the chain code. It looks like this:
|
139
157
|
|
140
158
|
```ruby
|
141
|
-
|
142
|
-
"
|
159
|
+
# private key
|
160
|
+
"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
|
161
|
+
|
162
|
+
# public key
|
163
|
+
"xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"
|
143
164
|
```
|
144
165
|
|
145
166
|
In addition to the key and the chain code, this encoding also includes info about the depth and index of the key, along with a fingerprint of its parent key (which I presume is for quickly sorting a big pile of keys into a tree).
|
@@ -151,6 +172,7 @@ To export a node to a serialized address, you can do:
|
|
151
172
|
```ruby
|
152
173
|
@node.to_serialized_address(:private) # for private keys
|
153
174
|
=> "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
|
175
|
+
|
154
176
|
@node.to_serialized_address
|
155
177
|
=> "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"
|
156
178
|
```
|
@@ -175,8 +197,10 @@ For example:
|
|
175
197
|
|
176
198
|
```ruby
|
177
199
|
@node = @master.node_for_path("M/0/3") # or "m/0/3.pub" or "M/0/3.pub"...these are equivalent
|
200
|
+
|
178
201
|
@node.to_serialized_address
|
179
202
|
=> "xpub6AvUGrnEpfvJJFCTd6qEYfMaxryBU8BykimDwQYuJJawFEh9BiyFdr37Cc4wEKCWWv7TsFQRUMdezXVqV9cfBUbeUEgNYCCP4omxULbNaRr"
|
203
|
+
|
180
204
|
@node.to_serialized_address(:private)
|
181
205
|
-> raises MoneyTree::Node::PrivatePublicMismatch error
|
182
206
|
```
|
@@ -187,8 +211,10 @@ You can also import a node using only a public key. Keep in mind that this node
|
|
187
211
|
```ruby
|
188
212
|
@node = MoneyTree::Node.from_serialized_address("xpub6AvUGrnEpfvJJFCTd6qEYfMaxryBU8BykimDwQYuJJawFEh9BiyFdr37Cc4wEKCWWv7TsFQRUMdezXVqV9cfBUbeUEgNYCCP4omxULbNaRr")
|
189
213
|
=> MoneyTree::Node instance
|
214
|
+
|
190
215
|
@node.to_serialized_address
|
191
216
|
=> "xpub6AvUGrnEpfvJJFCTd6qEYfMaxryBU8BykimDwQYuJJawFEh9BiyFdr37Cc4wEKCWWv7TsFQRUMdezXVqV9cfBUbeUEgNYCCP4omxULbNaRr"
|
217
|
+
|
192
218
|
@node.to_serialized_address(:private)
|
193
219
|
-> raises MoneyTree::Node::PrivatePublicMismatch error
|
194
220
|
```
|
data/lib/money-tree/node.rb
CHANGED
data/lib/money-tree/version.rb
CHANGED
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.2
|
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-
|
11
|
+
date: 2013-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -159,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
159
159
|
version: '0'
|
160
160
|
requirements: []
|
161
161
|
rubyforge_project:
|
162
|
-
rubygems_version: 2.
|
162
|
+
rubygems_version: 2.1.11
|
163
163
|
signing_key:
|
164
164
|
specification_version: 4
|
165
165
|
summary: Bitcoin Hierarchical Deterministic Wallets in Ruby! (Bitcoin standard BIP0032)
|