bitcoinrb 0.1.3 → 0.1.4
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/.travis.yml +4 -0
- data/README.md +31 -9
- data/bitcoinrb.conf.sample +0 -0
- data/bitcoinrb.gemspec +6 -2
- data/exe/bitcoinrb-cli +2 -2
- data/lib/bitcoin/block_header.rb +9 -2
- data/lib/bitcoin/chainparams/regtest.yml +1 -1
- data/lib/bitcoin/constants.rb +3 -0
- data/lib/bitcoin/key.rb +70 -5
- data/lib/bitcoin/logger.rb +25 -1
- data/lib/bitcoin/message/addr.rb +0 -39
- data/lib/bitcoin/message/headers.rb +1 -0
- data/lib/bitcoin/message/inventory.rb +4 -0
- data/lib/bitcoin/message/network_addr.rb +44 -0
- data/lib/bitcoin/message/version.rb +8 -3
- data/lib/bitcoin/message.rb +12 -0
- data/lib/bitcoin/mnemonic.rb +2 -2
- data/lib/bitcoin/network/connection.rb +14 -1
- data/lib/bitcoin/network/message_handler.rb +52 -19
- data/lib/bitcoin/network/peer.rb +142 -5
- data/lib/bitcoin/network/peer_discovery.rb +16 -8
- data/lib/bitcoin/network/pool.rb +39 -14
- data/lib/bitcoin/network.rb +0 -1
- data/lib/bitcoin/node/cli.rb +66 -0
- data/lib/bitcoin/node/configuration.rb +37 -0
- data/lib/bitcoin/node/spv.rb +13 -3
- data/lib/bitcoin/node.rb +2 -1
- data/lib/bitcoin/rpc/http_server.rb +56 -0
- data/lib/bitcoin/rpc/request_handler.rb +84 -0
- data/lib/bitcoin/rpc.rb +6 -0
- data/lib/bitcoin/script/multisig.rb +92 -0
- data/lib/bitcoin/script/script.rb +17 -7
- data/lib/bitcoin/script/script_interpreter.rb +2 -38
- data/lib/bitcoin/store/chain_entry.rb +64 -0
- data/lib/bitcoin/store/db/level_db.rb +101 -0
- data/lib/bitcoin/store/db.rb +9 -0
- data/lib/bitcoin/store/spv_chain.rb +96 -0
- data/lib/bitcoin/store.rb +5 -1
- data/lib/bitcoin/tx.rb +6 -2
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin/wallet/account.rb +82 -0
- data/lib/bitcoin/wallet/base.rb +84 -0
- data/lib/bitcoin/wallet/db.rb +57 -0
- data/lib/bitcoin/wallet/master_key.rb +100 -0
- data/lib/bitcoin/wallet.rb +8 -0
- data/lib/bitcoin.rb +4 -0
- data/lib/openassets/payload.rb +6 -2
- metadata +70 -13
- data/lib/bitcoin/node/spv_block_chain.rb +0 -15
- data/lib/bitcoin/store/spv_block_store.rb +0 -11
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'leveldb'
|
2
|
+
module Bitcoin
|
3
|
+
module Wallet
|
4
|
+
|
5
|
+
class Base
|
6
|
+
|
7
|
+
attr_accessor :wallet_id
|
8
|
+
attr_reader :db
|
9
|
+
|
10
|
+
DEFAULT_PATH_PREFIX = "#{Bitcoin.base_dir}/db/wallet"
|
11
|
+
|
12
|
+
# Create new wallet. If wallet already exist, throw error.
|
13
|
+
# The wallet generates a seed using SecureRandom and store to db at initialization.
|
14
|
+
# @param [String] wallet_id new wallet id.
|
15
|
+
# @param [String] path_prefix wallet file path prefix.
|
16
|
+
# @return [Bitcoin::Wallet::Base] the wallet
|
17
|
+
def self.create(wallet_id = 1, path_prefix = DEFAULT_PATH_PREFIX)
|
18
|
+
raise ArgumentError, "wallet_id : #{wallet_id} already exist." if self.exist?(wallet_id, path_prefix)
|
19
|
+
w = self.new(wallet_id, path_prefix)
|
20
|
+
# generate seed
|
21
|
+
raise RuntimeError, 'the seed already exist.' if w.db.registered_master?
|
22
|
+
master = Bitcoin::Wallet::MasterKey.generate
|
23
|
+
w.db.register_master_key(master)
|
24
|
+
w
|
25
|
+
end
|
26
|
+
|
27
|
+
# load wallet with specified +wallet_id+
|
28
|
+
# @return [Bitcoin::Wallet::Base] the wallet
|
29
|
+
def self.load(wallet_id, path_prefix = DEFAULT_PATH_PREFIX)
|
30
|
+
raise ArgumentError, "wallet_id : #{wallet_id} dose not exist." unless self.exist?(wallet_id, path_prefix)
|
31
|
+
self.new(wallet_id, path_prefix)
|
32
|
+
end
|
33
|
+
|
34
|
+
# get account list based on BIP-44
|
35
|
+
def accounts
|
36
|
+
db.accounts.map{|raw| Account.parse_from_payload(raw)}
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_account(purpose = Account::PURPOSE_TYPE[:legacy], index = 0, name)
|
40
|
+
account = Account.new(purpose, index, name)
|
41
|
+
account.wallet = self
|
42
|
+
account.init
|
43
|
+
account
|
44
|
+
end
|
45
|
+
|
46
|
+
# close database wallet
|
47
|
+
def close
|
48
|
+
db.close
|
49
|
+
end
|
50
|
+
|
51
|
+
# get master key
|
52
|
+
# @return [Bitcoin::Wallet::MasterKey]
|
53
|
+
def master_key
|
54
|
+
db.master_key
|
55
|
+
end
|
56
|
+
|
57
|
+
# encrypt wallet
|
58
|
+
# @param [String] passphrase the wallet passphrase
|
59
|
+
def encrypt(passphrase)
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# decrypt wallet
|
64
|
+
# @param [String] passphrase the wallet passphrase
|
65
|
+
def decrypt(passphrase)
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def initialize(wallet_id, path_prefix)
|
72
|
+
@db = Bitcoin::Wallet::DB.new("#{path_prefix}_#{wallet_id}")
|
73
|
+
@wallet_id = wallet_id
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.exist?(wallet_id, path_prefix)
|
77
|
+
path = "#{path_prefix}_#{wallet_id}"
|
78
|
+
Dir.exist?(path)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Wallet
|
3
|
+
|
4
|
+
class DB
|
5
|
+
|
6
|
+
KEY_PREFIX = {
|
7
|
+
account: 'a', # key: account index, value: Account raw data.
|
8
|
+
master: 'm', # value : wallet seed.
|
9
|
+
}
|
10
|
+
|
11
|
+
attr_reader :level_db
|
12
|
+
attr_accessor :master_key
|
13
|
+
|
14
|
+
def initialize(path = "#{Bitcoin.base_dir}/db/wallet")
|
15
|
+
FileUtils.mkdir_p(path)
|
16
|
+
@level_db = ::LevelDB::DB.new(path)
|
17
|
+
end
|
18
|
+
|
19
|
+
# close database
|
20
|
+
def close
|
21
|
+
level_db.close
|
22
|
+
end
|
23
|
+
|
24
|
+
# get accounts raw data.
|
25
|
+
def accounts
|
26
|
+
from = KEY_PREFIX[:account] + '00000000'
|
27
|
+
to = KEY_PREFIX[:account] + 'ffffffff'
|
28
|
+
level_db.each(from: from, to: to).map { |k, v| v}
|
29
|
+
end
|
30
|
+
|
31
|
+
def save_account(account)
|
32
|
+
level_db.batch do
|
33
|
+
key = KEY_PREFIX[:account] + account.index.to_s(16).rjust(8, '0')
|
34
|
+
level_db.put(key, account.to_payload)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# get master_key
|
39
|
+
def master_key
|
40
|
+
@master_key ||= Bitcoin::Wallet::MasterKey.parse_from_payload(level_db.get(KEY_PREFIX[:master]))
|
41
|
+
end
|
42
|
+
|
43
|
+
# save seed
|
44
|
+
# @param [Bitcoin::Wallet::MasterKey] master a master key.
|
45
|
+
def register_master_key(master)
|
46
|
+
level_db.put(KEY_PREFIX[:master], master.to_payload)
|
47
|
+
@master_key = master
|
48
|
+
end
|
49
|
+
|
50
|
+
# whether master key registered.
|
51
|
+
def registered_master?
|
52
|
+
!level_db.get(KEY_PREFIX[:master]).nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Wallet
|
3
|
+
|
4
|
+
# HD Wallet master seed
|
5
|
+
class MasterKey
|
6
|
+
extend Bitcoin::Util
|
7
|
+
include Bitcoin::Util
|
8
|
+
|
9
|
+
attr_reader :seed
|
10
|
+
attr_accessor :salt
|
11
|
+
attr_accessor :encrypted
|
12
|
+
attr_accessor :mnemonic # ephemeral data existing only at initialization
|
13
|
+
|
14
|
+
def initialize(seed, salt: '', encrypted: false, mnemonic: nil)
|
15
|
+
@mnemonic = mnemonic
|
16
|
+
@seed = seed
|
17
|
+
@encrypted = encrypted
|
18
|
+
@salt = salt
|
19
|
+
end
|
20
|
+
|
21
|
+
# generate new master key.
|
22
|
+
# @return Bitcoin::Wallet::MasterKey
|
23
|
+
def self.generate
|
24
|
+
entropy = SecureRandom.hex(16)
|
25
|
+
mnemonic = Bitcoin::Mnemonic.new('english')
|
26
|
+
self.recover_from_words(mnemonic.to_mnemonic(entropy))
|
27
|
+
end
|
28
|
+
|
29
|
+
# recover master key from mnemonic word list.
|
30
|
+
# @param [Array] words the mnemonic word list.
|
31
|
+
# @return Bitcoin::Wallet::MasterKey
|
32
|
+
def self.recover_from_words(words)
|
33
|
+
mnemonic = Bitcoin::Mnemonic.new('english')
|
34
|
+
seed = mnemonic.to_seed(words)
|
35
|
+
self.new(seed, mnemonic: words)
|
36
|
+
end
|
37
|
+
|
38
|
+
# parse master key raw data
|
39
|
+
# @param [String] payload raw data
|
40
|
+
# @return [Bitcoin::Wallet::MasterKey]
|
41
|
+
def self.parse_from_payload(payload)
|
42
|
+
flag, payload = unpack_var_int(payload)
|
43
|
+
raise 'encrypted flag is invalid.' unless [0, 1].include?(flag)
|
44
|
+
salt, payload = unpack_var_string(payload)
|
45
|
+
seed, payload = unpack_var_string(payload)
|
46
|
+
self.new(seed.bth, salt: salt.bth, encrypted: flag == 1)
|
47
|
+
end
|
48
|
+
|
49
|
+
# generate payload with following format
|
50
|
+
# [encrypted(false:0, true:1)][salt(var str)][seed(var str)]
|
51
|
+
def to_payload
|
52
|
+
flg = encrypted ? 1 : 0
|
53
|
+
pack_var_int(flg) << [salt, seed].map{|v|pack_var_string(v.htb)}.join
|
54
|
+
end
|
55
|
+
|
56
|
+
# get master key
|
57
|
+
# @return [Bitcoin::ExtKey] the master key
|
58
|
+
def key
|
59
|
+
raise 'seed is encrypted. please decrypt the seed.' if encrypted
|
60
|
+
Bitcoin::ExtKey.generate_master(seed)
|
61
|
+
end
|
62
|
+
|
63
|
+
# encrypt seed
|
64
|
+
def encrypt(passphrase)
|
65
|
+
raise 'seed already encrypted.' if encrypted
|
66
|
+
@salt = SecureRandom.hex(16)
|
67
|
+
enc = OpenSSL::Cipher.new('AES-256-CBC')
|
68
|
+
enc.encrypt
|
69
|
+
enc.key, enc.iv = key_iv(enc, passphrase)
|
70
|
+
encrypted_data = ''
|
71
|
+
encrypted_data << enc.update(seed)
|
72
|
+
encrypted_data << enc.final
|
73
|
+
@seed = encrypted_data
|
74
|
+
@encrypted = true
|
75
|
+
end
|
76
|
+
|
77
|
+
# decrypt seed
|
78
|
+
def decrypt(passphrase)
|
79
|
+
raise 'seed is not encrypted.' unless encrypted
|
80
|
+
dec = OpenSSL::Cipher.new('AES-256-CBC')
|
81
|
+
dec.decrypt
|
82
|
+
dec.key, dec.iv = key_iv(dec, passphrase)
|
83
|
+
decrypted_data = ''
|
84
|
+
decrypted_data << dec.update(seed)
|
85
|
+
decrypted_data << dec.final
|
86
|
+
@seed = decrypted_data
|
87
|
+
@encrypted = false
|
88
|
+
@salt = ''
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def key_iv(enc, passphrase)
|
94
|
+
key_iv = OpenSSL::PKCS5.pbkdf2_hmac_sha1(passphrase, salt, 2000, enc.key_len + enc.iv_len)
|
95
|
+
[key_iv[0, enc.key_len], key_iv[enc.key_len, enc.iv_len]]
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/bitcoin.rb
CHANGED
@@ -5,6 +5,7 @@ require 'securerandom'
|
|
5
5
|
require 'json'
|
6
6
|
require 'bech32'
|
7
7
|
require 'ffi'
|
8
|
+
require 'tmpdir'
|
8
9
|
require_relative 'openassets'
|
9
10
|
|
10
11
|
module Bitcoin
|
@@ -17,6 +18,7 @@ module Bitcoin
|
|
17
18
|
autoload :BlockHeader, 'bitcoin/block_header'
|
18
19
|
autoload :Tx, 'bitcoin/tx'
|
19
20
|
autoload :Script, 'bitcoin/script/script'
|
21
|
+
autoload :Multisig, 'bitcoin/script/multisig'
|
20
22
|
autoload :ScriptInterpreter, 'bitcoin/script/script_interpreter'
|
21
23
|
autoload :ScriptError, 'bitcoin/script/script_error'
|
22
24
|
autoload :TxChecker, 'bitcoin/script/tx_checker'
|
@@ -35,6 +37,8 @@ module Bitcoin
|
|
35
37
|
autoload :ValidationState, 'bitcoin/validation'
|
36
38
|
autoload :Network, 'bitcoin/network'
|
37
39
|
autoload :Store, 'bitcoin/store'
|
40
|
+
autoload :RPC, 'bitcoin/rpc'
|
41
|
+
autoload :Wallet, 'bitcoin/wallet'
|
38
42
|
|
39
43
|
require_relative 'bitcoin/constants'
|
40
44
|
|
data/lib/openassets/payload.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module OpenAssets
|
2
4
|
|
3
5
|
MARKER = "\x4f\x41"
|
@@ -34,9 +36,11 @@ module OpenAssets
|
|
34
36
|
|
35
37
|
# generate binary payload
|
36
38
|
def to_payload
|
37
|
-
payload =
|
39
|
+
payload = String.new
|
40
|
+
payload << MARKER
|
41
|
+
payload << VERSION
|
38
42
|
payload << Bitcoin.pack_var_int(quantities.size) << quantities.map{|q| LEB128.encode_unsigned(q).read }.join
|
39
|
-
payload << Bitcoin.pack_var_int(metadata.length) << metadata.bytes.map{|b|b
|
43
|
+
payload << Bitcoin.pack_var_int(metadata.length) << metadata.bytes.map{|b| sprintf("%02x", b)}.join.htb
|
40
44
|
payload
|
41
45
|
end
|
42
46
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitcoinrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0.
|
61
|
+
version: 1.0.3
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0.
|
68
|
+
version: 1.0.3
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: daemon-spawn
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,7 +109,21 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: leb128
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.0.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.0.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: leveldb-ruby
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - ">="
|
@@ -123,19 +137,47 @@ dependencies:
|
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
140
|
+
name: eventmachine_httpserver
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
|
-
- - "
|
143
|
+
- - ">="
|
130
144
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
145
|
+
version: '0'
|
132
146
|
type: :runtime
|
133
147
|
prerelease: false
|
134
148
|
version_requirements: !ruby/object:Gem::Requirement
|
135
149
|
requirements:
|
136
|
-
- - "
|
150
|
+
- - ">="
|
137
151
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rest-client
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: iniparse
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
139
181
|
- !ruby/object:Gem::Dependency
|
140
182
|
name: bundler
|
141
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -213,6 +255,7 @@ files:
|
|
213
255
|
- Rakefile
|
214
256
|
- bin/console
|
215
257
|
- bin/setup
|
258
|
+
- bitcoinrb.conf.sample
|
216
259
|
- bitcoinrb.gemspec
|
217
260
|
- exe/bitcoinrb-cli
|
218
261
|
- exe/bitcoinrbd
|
@@ -249,6 +292,7 @@ files:
|
|
249
292
|
- lib/bitcoin/message/inventory.rb
|
250
293
|
- lib/bitcoin/message/mem_pool.rb
|
251
294
|
- lib/bitcoin/message/merkle_block.rb
|
295
|
+
- lib/bitcoin/message/network_addr.rb
|
252
296
|
- lib/bitcoin/message/not_found.rb
|
253
297
|
- lib/bitcoin/message/ping.rb
|
254
298
|
- lib/bitcoin/message/pong.rb
|
@@ -273,10 +317,15 @@ files:
|
|
273
317
|
- lib/bitcoin/network/peer_discovery.rb
|
274
318
|
- lib/bitcoin/network/pool.rb
|
275
319
|
- lib/bitcoin/node.rb
|
320
|
+
- lib/bitcoin/node/cli.rb
|
321
|
+
- lib/bitcoin/node/configuration.rb
|
276
322
|
- lib/bitcoin/node/spv.rb
|
277
|
-
- lib/bitcoin/node/spv_block_chain.rb
|
278
323
|
- lib/bitcoin/opcodes.rb
|
279
324
|
- lib/bitcoin/out_point.rb
|
325
|
+
- lib/bitcoin/rpc.rb
|
326
|
+
- lib/bitcoin/rpc/http_server.rb
|
327
|
+
- lib/bitcoin/rpc/request_handler.rb
|
328
|
+
- lib/bitcoin/script/multisig.rb
|
280
329
|
- lib/bitcoin/script/script.rb
|
281
330
|
- lib/bitcoin/script/script_error.rb
|
282
331
|
- lib/bitcoin/script/script_interpreter.rb
|
@@ -286,13 +335,21 @@ files:
|
|
286
335
|
- lib/bitcoin/secp256k1/native.rb
|
287
336
|
- lib/bitcoin/secp256k1/ruby.rb
|
288
337
|
- lib/bitcoin/store.rb
|
289
|
-
- lib/bitcoin/store/
|
338
|
+
- lib/bitcoin/store/chain_entry.rb
|
339
|
+
- lib/bitcoin/store/db.rb
|
340
|
+
- lib/bitcoin/store/db/level_db.rb
|
341
|
+
- lib/bitcoin/store/spv_chain.rb
|
290
342
|
- lib/bitcoin/tx.rb
|
291
343
|
- lib/bitcoin/tx_in.rb
|
292
344
|
- lib/bitcoin/tx_out.rb
|
293
345
|
- lib/bitcoin/util.rb
|
294
346
|
- lib/bitcoin/validation.rb
|
295
347
|
- lib/bitcoin/version.rb
|
348
|
+
- lib/bitcoin/wallet.rb
|
349
|
+
- lib/bitcoin/wallet/account.rb
|
350
|
+
- lib/bitcoin/wallet/base.rb
|
351
|
+
- lib/bitcoin/wallet/db.rb
|
352
|
+
- lib/bitcoin/wallet/master_key.rb
|
296
353
|
- lib/openassets.rb
|
297
354
|
- lib/openassets/marker_output.rb
|
298
355
|
- lib/openassets/payload.rb
|
@@ -316,7 +373,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
316
373
|
version: '0'
|
317
374
|
requirements: []
|
318
375
|
rubyforge_project:
|
319
|
-
rubygems_version: 2.6.
|
376
|
+
rubygems_version: 2.6.12
|
320
377
|
signing_key:
|
321
378
|
specification_version: 4
|
322
379
|
summary: "[WIP]The implementation of Bitcoin Protocol for Ruby."
|