bitcoinrb 0.4.0 → 0.5.0
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/.ruby-version +1 -1
- data/.travis.yml +1 -0
- data/README.md +3 -2
- data/bitcoinrb.gemspec +2 -2
- data/exe/bitcoinrbd +5 -0
- data/lib/bitcoin.rb +10 -1
- data/lib/bitcoin/bip85_entropy.rb +111 -0
- data/lib/bitcoin/block_header.rb +2 -0
- data/lib/bitcoin/ext.rb +5 -0
- data/lib/bitcoin/ext/json_parser.rb +46 -0
- data/lib/bitcoin/ext_key.rb +7 -3
- data/lib/bitcoin/key_path.rb +12 -5
- data/lib/bitcoin/message.rb +7 -0
- data/lib/bitcoin/message/base.rb +1 -0
- data/lib/bitcoin/message/cf_parser.rb +16 -0
- data/lib/bitcoin/message/cfcheckpt.rb +36 -0
- data/lib/bitcoin/message/cfheaders.rb +40 -0
- data/lib/bitcoin/message/cfilter.rb +35 -0
- data/lib/bitcoin/message/get_cfcheckpt.rb +29 -0
- data/lib/bitcoin/message/get_cfheaders.rb +24 -0
- data/lib/bitcoin/message/get_cfilters.rb +25 -0
- data/lib/bitcoin/message/version.rb +7 -0
- data/lib/bitcoin/mnemonic.rb +5 -5
- data/lib/bitcoin/network/peer.rb +9 -4
- data/lib/bitcoin/network/peer_discovery.rb +3 -1
- data/lib/bitcoin/node/cli.rb +14 -10
- data/lib/bitcoin/node/spv.rb +1 -1
- data/lib/bitcoin/out_point.rb +2 -0
- data/lib/bitcoin/payment_code.rb +92 -0
- data/lib/bitcoin/psbt/input.rb +5 -14
- data/lib/bitcoin/psbt/tx.rb +7 -12
- data/lib/bitcoin/rpc/bitcoin_core_client.rb +22 -12
- data/lib/bitcoin/rpc/request_handler.rb +1 -1
- data/lib/bitcoin/script/script.rb +5 -9
- data/lib/bitcoin/script/script_interpreter.rb +2 -3
- data/lib/bitcoin/secp256k1.rb +1 -0
- data/lib/bitcoin/secp256k1/rfc6979.rb +43 -0
- data/lib/bitcoin/secp256k1/ruby.rb +4 -35
- data/lib/bitcoin/store.rb +1 -0
- data/lib/bitcoin/store/chain_entry.rb +1 -0
- data/lib/bitcoin/store/utxo_db.rb +226 -0
- data/lib/bitcoin/tx.rb +3 -7
- data/lib/bitcoin/tx_in.rb +3 -4
- data/lib/bitcoin/util.rb +7 -0
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin/wallet.rb +1 -0
- data/lib/bitcoin/wallet/account.rb +1 -0
- data/lib/bitcoin/wallet/base.rb +2 -2
- data/lib/bitcoin/wallet/master_key.rb +1 -0
- data/lib/bitcoin/wallet/utxo.rb +37 -0
- metadata +34 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5da63d0663778eba1816d008ebf369348bc75d214965b68c2ff7ce564e95ac3
|
4
|
+
data.tar.gz: 2a7e31c9f5b29b72b14e93103f1b69111a2283e390fb61fdad517a5aa764f9f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b062f7c6e944cac7787fdca7be284224961b9a675467bd6f55fa0d49ed502157507e098aee9b28998f600826d677ddc3f8b26947134591240b5d8ada5e004686
|
7
|
+
data.tar.gz: b32d9705400ac5bfb1cc252e4a79c66ff9fb2d8dcba1f530060b5c130e14726e412a5434d5769dd6824588374cbae99c797ae65a2478a92d53cc5fa664ab5a4e
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.0
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -17,6 +17,7 @@ Bitcoinrb supports following feature:
|
|
17
17
|
* Segwit support (parsing segwit payload, Bech32 address, sign for segwit tx, [BIP-141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki), [BIP-143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki), [BIP-144](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki))
|
18
18
|
* [BIP-173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) Bech32 address support
|
19
19
|
* [BIP-174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) PSBT(Partially Signed Bitcoin Transaction) support
|
20
|
+
* [BIP-85](https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki) Deterministic Entropy From BIP32 Keychains support by `Bitcoin::BIP85Entropy` class.
|
20
21
|
* [WIP] SPV node
|
21
22
|
* [WIP] 0ff-chain protocol
|
22
23
|
|
@@ -38,8 +39,8 @@ If you use node features, please install level DB as follows.
|
|
38
39
|
|
39
40
|
and put `leveldb-native` in your Gemfile and run bundle install.
|
40
41
|
|
41
|
-
```
|
42
|
-
gem leveldb-native
|
42
|
+
```ruby
|
43
|
+
gem 'leveldb-native'
|
43
44
|
```
|
44
45
|
|
45
46
|
## Installation
|
data/bitcoinrb.gemspec
CHANGED
@@ -29,17 +29,17 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_runtime_dependency 'ffi'
|
30
30
|
spec.add_runtime_dependency 'leb128', '~> 1.0.0'
|
31
31
|
spec.add_runtime_dependency 'eventmachine_httpserver'
|
32
|
-
spec.add_runtime_dependency 'rest-client'
|
33
32
|
spec.add_runtime_dependency 'iniparse'
|
34
33
|
spec.add_runtime_dependency 'siphash'
|
35
34
|
spec.add_runtime_dependency 'protobuf', '3.8.5'
|
36
35
|
spec.add_runtime_dependency 'scrypt'
|
36
|
+
spec.add_runtime_dependency 'json_pure', '>= 2.3.1'
|
37
37
|
|
38
38
|
# for options
|
39
39
|
spec.add_development_dependency 'leveldb-native'
|
40
40
|
|
41
41
|
spec.add_development_dependency 'bundler'
|
42
|
-
spec.add_development_dependency 'rake', '
|
42
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
43
43
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
44
44
|
spec.add_development_dependency 'timecop'
|
45
45
|
spec.add_development_dependency 'webmock', '~> 3.0'
|
data/exe/bitcoinrbd
CHANGED
data/lib/bitcoin.rb
CHANGED
@@ -14,6 +14,7 @@ require_relative 'openassets'
|
|
14
14
|
|
15
15
|
module Bitcoin
|
16
16
|
|
17
|
+
autoload :Ext, 'bitcoin/ext'
|
17
18
|
autoload :Util, 'bitcoin/util'
|
18
19
|
autoload :ChainParams, 'bitcoin/chain_params'
|
19
20
|
autoload :Message, 'bitcoin/message'
|
@@ -55,6 +56,8 @@ module Bitcoin
|
|
55
56
|
autoload :Descriptor, 'bitcoin/descriptor'
|
56
57
|
autoload :SLIP39, 'bitcoin/slip39'
|
57
58
|
autoload :Aezeed, 'bitcoin/aezeed'
|
59
|
+
autoload :PaymentCode, 'bitcoin/payment_code'
|
60
|
+
autoload :BIP85Entropy, 'bitcoin/bip85_entropy'
|
58
61
|
|
59
62
|
require_relative 'bitcoin/constants'
|
60
63
|
|
@@ -189,7 +192,7 @@ module Bitcoin
|
|
189
192
|
if value.is_a?(Array)
|
190
193
|
result.update(key => value.map{|v|v.to_h})
|
191
194
|
else
|
192
|
-
result.update(key => value)
|
195
|
+
result.update(key => value.class.to_s.start_with?("Bitcoin::") ? value.to_h : value)
|
193
196
|
end
|
194
197
|
end
|
195
198
|
end
|
@@ -223,4 +226,10 @@ module Bitcoin
|
|
223
226
|
end
|
224
227
|
end
|
225
228
|
|
229
|
+
class ::ECDSA::Point
|
230
|
+
def to_hex(compression = true)
|
231
|
+
ECDSA::Format::PointOctetString.encode(self, compression: compression).bth
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
226
235
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
|
3
|
+
# Deterministic Entropy From BIP32 Keychains
|
4
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki
|
5
|
+
class BIP85Entropy
|
6
|
+
|
7
|
+
BIP85_PATH = 83696968 + HARDENED_THRESHOLD
|
8
|
+
|
9
|
+
include Bitcoin::KeyPath
|
10
|
+
|
11
|
+
attr_reader :root_key #hex format
|
12
|
+
|
13
|
+
# Import root key.
|
14
|
+
# @param [String] base58 master bip32 root key.
|
15
|
+
# @return [Bitcoin::BIP85Entropy]
|
16
|
+
def self.from_base58(base58)
|
17
|
+
key = Bitcoin::ExtKey.from_base58(base58)
|
18
|
+
self.new(key)
|
19
|
+
end
|
20
|
+
|
21
|
+
# derive entropy
|
22
|
+
# @param [String] path derive path.
|
23
|
+
# @return [Tuple(String, Object)] a tuple of entropy with hex format and results depending the application.
|
24
|
+
def derive(path)
|
25
|
+
raise ArgumentError, "Invalid BIP85 path format." unless path.start_with?("m/83696968'")
|
26
|
+
derived_key = root_key
|
27
|
+
parse_key_path(path).each{|num| derived_key = derived_key.derive(num)}
|
28
|
+
derived_key = derived_key.priv
|
29
|
+
entropy = Bitcoin.hmac_sha512("bip-entropy-from-k", derived_key.htb).bth
|
30
|
+
app_no = path.split('/')[2]
|
31
|
+
case app_no
|
32
|
+
when "39'"
|
33
|
+
bip39_entropy(path, entropy)
|
34
|
+
when "2'"
|
35
|
+
hd_seed_entropy(entropy)
|
36
|
+
when "32'"
|
37
|
+
xprv_entropy(entropy)
|
38
|
+
else
|
39
|
+
[entropy, entropy]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def initialize(root_key)
|
46
|
+
@root_key = root_key
|
47
|
+
end
|
48
|
+
|
49
|
+
# derive BIP39 entropy.
|
50
|
+
def bip39_entropy(path, entropy)
|
51
|
+
params = path.split('/')
|
52
|
+
word_len = params[4]
|
53
|
+
language = code_to_language(params[3])
|
54
|
+
entropy = case word_len
|
55
|
+
when "12'"
|
56
|
+
entropy[0...32]
|
57
|
+
when "18'"
|
58
|
+
entropy[0...48]
|
59
|
+
when "24'"
|
60
|
+
entropy[0...64]
|
61
|
+
else
|
62
|
+
raise ArgumentError, "Word length #{word_len} does not supported."
|
63
|
+
end
|
64
|
+
mnemonic = Bitcoin::Mnemonic.new(language)
|
65
|
+
[entropy, mnemonic.to_mnemonic(entropy)]
|
66
|
+
end
|
67
|
+
|
68
|
+
# derive HD-Seed WIF entropy.
|
69
|
+
def hd_seed_entropy(entropy)
|
70
|
+
result = entropy[0...64]
|
71
|
+
[result, Bitcoin::Key.new(priv_key: result).to_wif]
|
72
|
+
end
|
73
|
+
|
74
|
+
# derive xprv entropy
|
75
|
+
def xprv_entropy(entropy)
|
76
|
+
chaincode = entropy[0...64]
|
77
|
+
private_key = Bitcoin::Key.new(priv_key: entropy[64..-1])
|
78
|
+
ext_key = Bitcoin::ExtKey.new
|
79
|
+
ext_key.key = private_key
|
80
|
+
ext_key.chain_code = chaincode.htb
|
81
|
+
ext_key.depth = 0
|
82
|
+
ext_key.number = 0
|
83
|
+
ext_key.parent_fingerprint = Bitcoin::ExtKey::MASTER_FINGERPRINT
|
84
|
+
[entropy, ext_key.to_base58]
|
85
|
+
end
|
86
|
+
|
87
|
+
# convert language code to language string.
|
88
|
+
def code_to_language(code)
|
89
|
+
case code
|
90
|
+
when "0'"
|
91
|
+
"english"
|
92
|
+
when "1'"
|
93
|
+
"japanese"
|
94
|
+
when "3'"
|
95
|
+
"spanish"
|
96
|
+
when "4'"
|
97
|
+
"chinese_simplified"
|
98
|
+
when "5'"
|
99
|
+
"chinese_traditional"
|
100
|
+
when "6'"
|
101
|
+
"french"
|
102
|
+
when "7'"
|
103
|
+
"italian"
|
104
|
+
else
|
105
|
+
raise ArgumentError, "bitcoinrb does not support language: #{code}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
data/lib/bitcoin/block_header.rb
CHANGED
data/lib/bitcoin/ext.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'json/pure'
|
2
|
+
|
3
|
+
module Bitcoin
|
4
|
+
module Ext
|
5
|
+
# Extension of JSON::Pure::Parser.
|
6
|
+
# This class convert Float value to String value.
|
7
|
+
class JsonParser < JSON::Pure::Parser
|
8
|
+
|
9
|
+
def parse_value
|
10
|
+
case
|
11
|
+
when scan(FLOAT)
|
12
|
+
self[1].to_s
|
13
|
+
when scan(INTEGER)
|
14
|
+
Integer(self[1])
|
15
|
+
when scan(TRUE)
|
16
|
+
true
|
17
|
+
when scan(FALSE)
|
18
|
+
false
|
19
|
+
when scan(NULL)
|
20
|
+
nil
|
21
|
+
when !UNPARSED.equal?(string = parse_string)
|
22
|
+
string
|
23
|
+
when scan(ARRAY_OPEN)
|
24
|
+
@current_nesting += 1
|
25
|
+
ary = parse_array
|
26
|
+
@current_nesting -= 1
|
27
|
+
ary
|
28
|
+
when scan(OBJECT_OPEN)
|
29
|
+
@current_nesting += 1
|
30
|
+
obj = parse_object
|
31
|
+
@current_nesting -= 1
|
32
|
+
obj
|
33
|
+
when @allow_nan && scan(NAN)
|
34
|
+
NaN
|
35
|
+
when @allow_nan && scan(INFINITY)
|
36
|
+
Infinity
|
37
|
+
when @allow_nan && scan(MINUS_INFINITY)
|
38
|
+
MinusInfinity
|
39
|
+
else
|
40
|
+
UNPARSED
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/bitcoin/ext_key.rb
CHANGED
@@ -6,6 +6,8 @@ module Bitcoin
|
|
6
6
|
# BIP32 Extended private key
|
7
7
|
class ExtKey
|
8
8
|
|
9
|
+
include Bitcoin::HexConverter
|
10
|
+
|
9
11
|
MAX_DEPTH = 255
|
10
12
|
MASTER_FINGERPRINT = '00000000'
|
11
13
|
|
@@ -50,7 +52,7 @@ module Bitcoin
|
|
50
52
|
|
51
53
|
# Base58 encoded extended private key
|
52
54
|
def to_base58
|
53
|
-
h =
|
55
|
+
h = to_hex
|
54
56
|
hex = h + Bitcoin.calc_checksum(h)
|
55
57
|
Base58.encode(hex)
|
56
58
|
end
|
@@ -198,6 +200,8 @@ module Bitcoin
|
|
198
200
|
# BIP-32 Extended public key
|
199
201
|
class ExtPubkey
|
200
202
|
|
203
|
+
include Bitcoin::HexConverter
|
204
|
+
|
201
205
|
attr_accessor :ver
|
202
206
|
attr_accessor :depth
|
203
207
|
attr_accessor :number
|
@@ -249,7 +253,7 @@ module Bitcoin
|
|
249
253
|
|
250
254
|
# Base58 encoded extended pubkey
|
251
255
|
def to_base58
|
252
|
-
h =
|
256
|
+
h = to_hex
|
253
257
|
hex = h + Bitcoin.calc_checksum(h)
|
254
258
|
Base58.encode(hex)
|
255
259
|
end
|
@@ -273,7 +277,7 @@ module Bitcoin
|
|
273
277
|
raise 'invalid key' if left >= CURVE_ORDER
|
274
278
|
p1 = Bitcoin::Secp256k1::GROUP.generator.multiply_by_scalar(left)
|
275
279
|
p2 = Bitcoin::Key.new(pubkey: pubkey, key_type: key_type).to_point
|
276
|
-
new_key.pubkey =
|
280
|
+
new_key.pubkey = (p1 + p2).to_hex
|
277
281
|
new_key.chain_code = l[32..-1]
|
278
282
|
new_key.ver = version
|
279
283
|
new_key
|
data/lib/bitcoin/key_path.rb
CHANGED
@@ -4,14 +4,21 @@ module Bitcoin
|
|
4
4
|
# key path convert an array of derive number
|
5
5
|
# @param [String] path_string
|
6
6
|
# @return [Array[Integer]] key path numbers.
|
7
|
+
# @raise [ArgumentError] if invalid +path_string+.
|
7
8
|
def parse_key_path(path_string)
|
8
|
-
path_string.split('/')
|
9
|
+
paths = path_string.split('/')
|
10
|
+
raise ArgumentError, "Invalid path." if path_string.include?(" ")
|
11
|
+
raise ArgumentError, "Invalid path." unless path_string.count("/") <= paths.size
|
12
|
+
paths.map.with_index do|p, index|
|
9
13
|
if index == 0
|
10
|
-
|
11
|
-
|
14
|
+
next if p == 'm'
|
15
|
+
raise ArgumentError, "Invalid path." unless p == 'm'
|
12
16
|
end
|
13
|
-
raise ArgumentError.
|
14
|
-
|
17
|
+
raise ArgumentError, "Invalid path." if p.count("'") > 1 || (p.count("'") == 1 && p[-1] != "'")
|
18
|
+
raise ArgumentError, "Invalid path." unless p.delete("'") =~ /^[0-9]+$/
|
19
|
+
value = (p[-1] == "'" ? p.delete("'").to_i + Bitcoin::HARDENED_THRESHOLD : p.to_i)
|
20
|
+
raise ArgumentError, "Invalid path." if value > 4294967295 # 4294967295 = 0xFFFFFFFF (uint32 max)
|
21
|
+
value
|
15
22
|
end[1..-1]
|
16
23
|
end
|
17
24
|
|
data/lib/bitcoin/message.rb
CHANGED
@@ -37,6 +37,13 @@ module Bitcoin
|
|
37
37
|
autoload :BlockTransactionRequest, 'bitcoin/message/block_transaction_request'
|
38
38
|
autoload :BlockTxn, 'bitcoin/message/block_txn'
|
39
39
|
autoload :BlockTransactions, 'bitcoin/message/block_transactions'
|
40
|
+
autoload :GetCFilters, 'bitcoin/message/get_cfilters'
|
41
|
+
autoload :GetCFHeaders, 'bitcoin/message/get_cfheaders'
|
42
|
+
autoload :CFParser, 'bitcoin/message/cf_parser'
|
43
|
+
autoload :GetCFCheckpt, 'bitcoin/message/get_cfcheckpt'
|
44
|
+
autoload :CFCheckpt, 'bitcoin/message/cfcheckpt'
|
45
|
+
autoload :CFilter, 'bitcoin/message/cfilter'
|
46
|
+
autoload :CFHeaders, 'bitcoin/message/cfheaders'
|
40
47
|
|
41
48
|
USER_AGENT = "/bitcoinrb:#{Bitcoin::VERSION}/"
|
42
49
|
|
data/lib/bitcoin/message/base.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
module CFParser
|
4
|
+
|
5
|
+
def parse_from_payload(payload)
|
6
|
+
type, start, hash = payload.unpack('CLH*')
|
7
|
+
self.new(type, start, hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_payload
|
11
|
+
[filter_type, start_height, stop_hash].pack('CLH*')
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# cfcheckpt message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#cfcheckpt
|
6
|
+
class CFCheckpt < Base
|
7
|
+
|
8
|
+
COMMAND = 'cfcheckpt'
|
9
|
+
|
10
|
+
attr_accessor :filter_type
|
11
|
+
attr_accessor :stop_hash # little endian
|
12
|
+
attr_accessor :filter_headers # little endian
|
13
|
+
|
14
|
+
def initialize(filter_type, stop_hash, filter_headers)
|
15
|
+
@filter_type = filter_type
|
16
|
+
@stop_hash = stop_hash
|
17
|
+
@filter_headers = filter_headers
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse_from_payload(payload)
|
21
|
+
buf = StringIO.new(payload)
|
22
|
+
type = buf.read(1).unpack('C').first
|
23
|
+
hash = buf.read(32).unpack('H*').first
|
24
|
+
count = Bitcoin.unpack_var_int_from_io(buf)
|
25
|
+
headers = count.times.map{buf.read(32).bth}
|
26
|
+
self.new(type, hash, headers)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_payload
|
30
|
+
[filter_type, stop_hash].pack('CH*') +
|
31
|
+
Bitcoin.pack_var_int(filter_headers.size) + filter_headers.map(&:htb).join
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# cfheaders message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#cfheaders
|
6
|
+
class CFHeaders < Base
|
7
|
+
|
8
|
+
COMMAND = 'cfheaders'
|
9
|
+
|
10
|
+
attr_accessor :filter_type
|
11
|
+
attr_accessor :stop_hash # little endian
|
12
|
+
attr_accessor :prev_filter_header # little endian
|
13
|
+
attr_accessor :filter_hashes # little endian
|
14
|
+
|
15
|
+
def initialize(filter_type, stop_hash, prev_filter_header, filter_hashes)
|
16
|
+
@filter_type = filter_type
|
17
|
+
@stop_hash = stop_hash
|
18
|
+
@prev_filter_header = prev_filter_header
|
19
|
+
@filter_hashes = filter_hashes
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.parse_from_payload(payload)
|
23
|
+
buf = StringIO.new(payload)
|
24
|
+
type = buf.read(1).unpack("C").first
|
25
|
+
hash = buf.read(32).bth
|
26
|
+
header = buf.read(32).bth
|
27
|
+
count = Bitcoin.unpack_var_int_from_io(buf)
|
28
|
+
hashes = count.times.map{buf.read(32).bth}
|
29
|
+
self.new(type, hash, header, hashes)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_payload
|
33
|
+
[filter_type].pack('C') + stop_hash.htb + prev_filter_header.htb +
|
34
|
+
Bitcoin.pack_var_int(filter_hashes.size) + filter_hashes.map(&:htb).join
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|