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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f25b7f5ff1de3882b880e49e858f3b49bf8c13a
|
4
|
+
data.tar.gz: 2a04f3a090503ffdc15d337b351c839d68b33929
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abbfff02611cb216dc843414bc7e8e9f4e9799a72314ebc3f165f6b100fa2e2d77843975b77bca8ccce3d23d7fb749eb12c62f881ac7f3635840bb68eedb9791
|
7
|
+
data.tar.gz: a0a3fd06f7120bdff5c04375e1ab4214d3e962256d96f4c5f9a48811eeb5227ad602bd7ff2283c117219d3bb4d880dd529a9b0fde1567cc2ef03d2a9b2106cfd
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,35 @@
|
|
1
|
-
# Bitcoinrb
|
1
|
+
# Bitcoinrb [](https://travis-ci.org/haw-itn/bitcoinrb) [](https://badge.fury.io/rb/bitcoinrb) [](LICENSE) <img src="http://segwit.co/static/public/images/logo.png" width="100">
|
2
2
|
|
3
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/bitcoinrb`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
3
|
|
5
|
-
|
4
|
+
Bitcoinrb is a Ruby implementation of Bitcoin Protocol.
|
5
|
+
|
6
|
+
NOTE: Bitcoinrb work in progress, and there is a possibility of incompatible change.
|
7
|
+
|
8
|
+
## Features
|
9
|
+
|
10
|
+
Bitcoinrb supports following feature:
|
11
|
+
|
12
|
+
* Bitcoin script interpreter
|
13
|
+
* De/serialization of Bitcoin protocol network messages
|
14
|
+
* De/serialization of blocks and transactions
|
15
|
+
* Key generation and verification for ECDSA, including [BIP-32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) and [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) supports.
|
16
|
+
* Segwit support (parsing segwit payload, Bech32 address, sign for segwit tx, etc..)
|
17
|
+
* [WIP] SPV node
|
18
|
+
* [WIP] 0ff-chain protocol
|
19
|
+
|
20
|
+
## Requirements
|
21
|
+
|
22
|
+
bitcoinrb requires a `leveldb` library.
|
23
|
+
|
24
|
+
### install LevelDB
|
25
|
+
|
26
|
+
* for Ubuntu
|
27
|
+
|
28
|
+
$ sudo apt-get install libleveldb-dev
|
29
|
+
|
30
|
+
+ for Mac
|
31
|
+
|
32
|
+
$ brew install leveldb
|
6
33
|
|
7
34
|
## Installation
|
8
35
|
|
@@ -20,16 +47,11 @@ Or install it yourself as:
|
|
20
47
|
|
21
48
|
$ gem install bitcoinrb
|
22
49
|
|
50
|
+
|
23
51
|
## Usage
|
24
52
|
|
25
53
|
TODO: Write usage instructions here
|
26
54
|
|
27
|
-
## Development
|
28
|
-
|
29
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
-
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
-
|
33
55
|
## Contributing
|
34
56
|
|
35
57
|
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/bitcoinrb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
File without changes
|
data/bitcoinrb.gemspec
CHANGED
@@ -4,6 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'bitcoin/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
+
|
7
8
|
spec.name = "bitcoinrb"
|
8
9
|
spec.version = Bitcoin::VERSION
|
9
10
|
spec.authors = ["azuchi"]
|
@@ -22,12 +23,15 @@ Gem::Specification.new do |spec|
|
|
22
23
|
spec.add_runtime_dependency 'ecdsa'
|
23
24
|
spec.add_runtime_dependency 'eventmachine'
|
24
25
|
spec.add_runtime_dependency 'murmurhash3'
|
25
|
-
spec.add_runtime_dependency 'bech32', '~> 1.0.
|
26
|
+
spec.add_runtime_dependency 'bech32', '~> 1.0.3'
|
26
27
|
spec.add_runtime_dependency 'daemon-spawn'
|
27
28
|
spec.add_runtime_dependency 'thor'
|
28
29
|
spec.add_runtime_dependency 'ffi'
|
29
|
-
spec.add_runtime_dependency 'parallel'
|
30
30
|
spec.add_runtime_dependency 'leb128', '~> 1.0.0'
|
31
|
+
spec.add_runtime_dependency 'leveldb-ruby'
|
32
|
+
spec.add_runtime_dependency 'eventmachine_httpserver'
|
33
|
+
spec.add_runtime_dependency 'rest-client'
|
34
|
+
spec.add_runtime_dependency 'iniparse'
|
31
35
|
|
32
36
|
spec.add_development_dependency 'bundler', '~> 1.11'
|
33
37
|
spec.add_development_dependency 'rake', '~> 10.0'
|
data/exe/bitcoinrb-cli
CHANGED
data/lib/bitcoin/block_header.rb
CHANGED
@@ -3,7 +3,6 @@ module Bitcoin
|
|
3
3
|
# Block Header
|
4
4
|
class BlockHeader
|
5
5
|
|
6
|
-
attr_accessor :hash
|
7
6
|
attr_accessor :version
|
8
7
|
attr_accessor :prev_hash
|
9
8
|
attr_accessor :merkle_root
|
@@ -18,7 +17,6 @@ module Bitcoin
|
|
18
17
|
@time = time
|
19
18
|
@bits = bits
|
20
19
|
@nonce = nonce
|
21
|
-
@hash = calc_hash
|
22
20
|
end
|
23
21
|
|
24
22
|
def self.parse_from_payload(payload)
|
@@ -38,6 +36,11 @@ module Bitcoin
|
|
38
36
|
(mantissa * 2 ** (8 * (exponent - 3)))
|
39
37
|
end
|
40
38
|
|
39
|
+
# block hash
|
40
|
+
def hash
|
41
|
+
calc_hash
|
42
|
+
end
|
43
|
+
|
41
44
|
# evaluate block header
|
42
45
|
def valid?
|
43
46
|
valid_pow? && valid_timestamp?
|
@@ -62,6 +65,10 @@ module Bitcoin
|
|
62
65
|
(2**256) / (target + 1)
|
63
66
|
end
|
64
67
|
|
68
|
+
def ==(other)
|
69
|
+
other && other.to_payload == to_payload
|
70
|
+
end
|
71
|
+
|
65
72
|
private
|
66
73
|
|
67
74
|
def calc_hash
|
data/lib/bitcoin/constants.rb
CHANGED
@@ -167,4 +167,7 @@ module Bitcoin
|
|
167
167
|
|
168
168
|
# Maximum amount of time that a block timestamp is allowed to exceed the current network-adjusted time before the block will be accepted.
|
169
169
|
MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60
|
170
|
+
|
171
|
+
# Size of set to pick median time from.
|
172
|
+
MEDIAN_TIME_SPAN = 11
|
170
173
|
end
|
data/lib/bitcoin/key.rb
CHANGED
@@ -8,9 +8,16 @@ module Bitcoin
|
|
8
8
|
attr_accessor :compressed
|
9
9
|
attr_reader :secp256k1_module
|
10
10
|
|
11
|
+
MIN_PRIV_KEy_MOD_ORDER = 0x01
|
12
|
+
# Order of secp256k1's generator minus 1.
|
13
|
+
MAX_PRIV_KEY_MOD_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140
|
14
|
+
|
11
15
|
def initialize(priv_key: nil, pubkey: nil, compressed: true)
|
12
16
|
@secp256k1_module = Bitcoin.secp_impl
|
13
17
|
@priv_key = priv_key
|
18
|
+
if @priv_key
|
19
|
+
raise ArgumentError, 'private key is not on curve' unless validate_private_key_range(@priv_key)
|
20
|
+
end
|
14
21
|
if pubkey
|
15
22
|
@pubkey = pubkey
|
16
23
|
else
|
@@ -28,12 +35,23 @@ module Bitcoin
|
|
28
35
|
# import private key from wif format
|
29
36
|
# https://en.bitcoin.it/wiki/Wallet_import_format
|
30
37
|
def self.from_wif(wif)
|
31
|
-
compressed = wif.size == 52
|
32
38
|
hex = Base58.decode(wif)
|
33
|
-
|
39
|
+
raise ArgumentError, 'data is too short' if hex.htb.bytesize < 4
|
40
|
+
version = hex[0..1]
|
41
|
+
data = hex[2...-8].htb
|
42
|
+
checksum = hex[-8..-1]
|
34
43
|
raise ArgumentError, 'invalid version' unless version == Bitcoin.chain_params.privkey_version
|
35
|
-
raise ArgumentError, 'invalid checksum' unless Bitcoin.calc_checksum(version +
|
36
|
-
|
44
|
+
raise ArgumentError, 'invalid checksum' unless Bitcoin.calc_checksum(version + data.bth) == checksum
|
45
|
+
key_len = data.bytesize
|
46
|
+
if key_len == 33 && data[-1].unpack('C').first == 1
|
47
|
+
compressed = true
|
48
|
+
data = data[0..-2]
|
49
|
+
elsif key_len == 32
|
50
|
+
compressed = false
|
51
|
+
else
|
52
|
+
raise ArgumentError, 'Wrong number of bytes for a private key, not 32 or 33'
|
53
|
+
end
|
54
|
+
new(priv_key: data.bth, compressed: compressed)
|
37
55
|
end
|
38
56
|
|
39
57
|
# export private key with wif format
|
@@ -47,7 +65,12 @@ module Bitcoin
|
|
47
65
|
|
48
66
|
# sign +data+ with private key
|
49
67
|
def sign(data)
|
50
|
-
|
68
|
+
sig = nil
|
69
|
+
until sig
|
70
|
+
signature = secp256k1_module.sign_data(data, priv_key)
|
71
|
+
sig = signature if Key.low_signature?(signature)
|
72
|
+
end
|
73
|
+
sig
|
51
74
|
end
|
52
75
|
|
53
76
|
# verify signature using public key
|
@@ -116,6 +139,42 @@ module Bitcoin
|
|
116
139
|
compare_big_endian(val_s, max_mod_half_order) <= 0
|
117
140
|
end
|
118
141
|
|
142
|
+
|
143
|
+
# check +sig+ is correct der encoding.
|
144
|
+
# This function is consensus-critical since BIP66.
|
145
|
+
def self.valid_signature_encoding?(sig)
|
146
|
+
return false if sig.bytesize < 9 || sig.bytesize > 73 # Minimum and maximum size check
|
147
|
+
|
148
|
+
s = sig.unpack('C*')
|
149
|
+
|
150
|
+
return false if s[0] != 0x30 || s[1] != s.size - 3 # A signature is of type 0x30 (compound). Make sure the length covers the entire signature.
|
151
|
+
|
152
|
+
len_r = s[3]
|
153
|
+
return false if 5 + len_r >= s.size # Make sure the length of the S element is still inside the signature.
|
154
|
+
|
155
|
+
len_s = s[5 + len_r]
|
156
|
+
return false unless len_r + len_s + 7 == s.size #Verify that the length of the signature matches the sum of the length of the elements.
|
157
|
+
|
158
|
+
return false unless s[2] == 0x02 # Check whether the R element is an integer.
|
159
|
+
|
160
|
+
return false if len_r == 0 # Zero-length integers are not allowed for R.
|
161
|
+
|
162
|
+
return false unless s[4] & 0x80 == 0 # Negative numbers are not allowed for R.
|
163
|
+
|
164
|
+
# Null bytes at the start of R are not allowed, unless R would otherwise be interpreted as a negative number.
|
165
|
+
return false if len_r > 1 && (s[4] == 0x00) && (s[5] & 0x80 == 0)
|
166
|
+
|
167
|
+
return false unless s[len_r + 4] == 0x02 # Check whether the S element is an integer.
|
168
|
+
|
169
|
+
return false if len_s == 0 # Zero-length integers are not allowed for S.
|
170
|
+
return false unless (s[len_r + 6] & 0x80) == 0 # Negative numbers are not allowed for S.
|
171
|
+
|
172
|
+
# Null bytes at the start of S are not allowed, unless S would otherwise be interpreted as a negative number.
|
173
|
+
return false if len_s > 1 && (s[len_r + 6] == 0x00) && (s[len_r + 7] & 0x80 == 0)
|
174
|
+
|
175
|
+
true
|
176
|
+
end
|
177
|
+
|
119
178
|
private
|
120
179
|
|
121
180
|
def self.compare_big_endian(c1, c2)
|
@@ -144,6 +203,12 @@ module Bitcoin
|
|
144
203
|
pubkey.bth
|
145
204
|
end
|
146
205
|
|
206
|
+
# check private key range.
|
207
|
+
def validate_private_key_range(private_key)
|
208
|
+
value = private_key.to_i(16)
|
209
|
+
MIN_PRIV_KEy_MOD_ORDER <= value && value <= MAX_PRIV_KEY_MOD_ORDER
|
210
|
+
end
|
211
|
+
|
147
212
|
end
|
148
213
|
|
149
214
|
end
|
data/lib/bitcoin/logger.rb
CHANGED
@@ -5,14 +5,38 @@ module Bitcoin
|
|
5
5
|
# Simple Logger module
|
6
6
|
module Logger
|
7
7
|
|
8
|
+
Format = "%s, [%s#%d #%d] %5s -- %s: %s\n".freeze
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
8
12
|
# Create a logger with given +name+.log in $HOME/.bitcoinrb/log.
|
9
|
-
def
|
13
|
+
def create(name, level = ::Logger::INFO)
|
10
14
|
dir = "#{Bitcoin.base_dir}/log"
|
11
15
|
FileUtils.mkdir_p(dir)
|
12
16
|
logger = ::Logger.new(dir + "/#{name}.log", 10)
|
13
17
|
logger.level = level
|
18
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
19
|
+
Format % [severity[0..0], format_datetime(datetime), $$,
|
20
|
+
Thread.current.object_id, severity, progname, msg2str(msg)]
|
21
|
+
end
|
14
22
|
logger
|
15
23
|
end
|
16
24
|
|
25
|
+
def self.msg2str(msg)
|
26
|
+
case msg
|
27
|
+
when ::String
|
28
|
+
msg
|
29
|
+
when ::Exception
|
30
|
+
"#{ msg.message } (#{ msg.class })\n" <<
|
31
|
+
(msg.backtrace || []).join("\n")
|
32
|
+
else
|
33
|
+
msg.inspect
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def format_datetime(time)
|
38
|
+
time.strftime(@datetime_format || "%Y-%m-%dT%H:%M:%S.%6N ".freeze)
|
39
|
+
end
|
40
|
+
|
17
41
|
end
|
18
42
|
end
|
data/lib/bitcoin/message/addr.rb
CHANGED
@@ -31,44 +31,5 @@ module Bitcoin
|
|
31
31
|
|
32
32
|
end
|
33
33
|
|
34
|
-
class NetworkAddr
|
35
|
-
|
36
|
-
# unix time.
|
37
|
-
# Nodes advertising their own IP address set this to the current time.
|
38
|
-
# Nodes advertising IP addresses they’ve connected to set this to the last time they connected to that node.
|
39
|
-
# Other nodes just relaying the IP address should not change the time. Nodes can use the time field to avoid relaying old addr messages.
|
40
|
-
attr_accessor :time
|
41
|
-
|
42
|
-
# The services the node advertised in its version message.
|
43
|
-
attr_accessor :services
|
44
|
-
|
45
|
-
attr_accessor :ip
|
46
|
-
|
47
|
-
attr_accessor :port
|
48
|
-
|
49
|
-
def initialize
|
50
|
-
@time = Time.now.to_i
|
51
|
-
@services = Bitcoin::Message::SERVICE_FLAGS[:network]
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.parse_from_payload(payload)
|
55
|
-
buf = payload.is_a?(String) ? StringIO.new(payload) : payload
|
56
|
-
addr = new
|
57
|
-
addr.time = buf.read(4).unpack('V').first
|
58
|
-
addr.services = buf.read(8).unpack('Q').first
|
59
|
-
ip = IPAddr::new_ntoh(buf.read(16))
|
60
|
-
addr.ip = ip.ipv4_mapped? ? ip.native : ip.to_s
|
61
|
-
addr.port = buf.read(2).unpack('n').first
|
62
|
-
addr
|
63
|
-
end
|
64
|
-
|
65
|
-
def to_payload
|
66
|
-
ip_addr = IPAddr.new (ip)
|
67
|
-
ip_addr = ip_addr.ipv4_mapped if ip_addr.ipv4?
|
68
|
-
[time, services].pack('VQ') << ip_addr.hton << [port].pack('n')
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
34
|
end
|
74
35
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
class NetworkAddr
|
5
|
+
|
6
|
+
# unix time.
|
7
|
+
# Nodes advertising their own IP address set this to the current time.
|
8
|
+
# Nodes advertising IP addresses they’ve connected to set this to the last time they connected to that node.
|
9
|
+
# Other nodes just relaying the IP address should not change the time. Nodes can use the time field to avoid relaying old addr messages.
|
10
|
+
attr_accessor :time
|
11
|
+
|
12
|
+
# The services the node advertised in its version message.
|
13
|
+
attr_accessor :services
|
14
|
+
|
15
|
+
attr_accessor :ip
|
16
|
+
|
17
|
+
attr_accessor :port
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@time = Time.now.to_i
|
21
|
+
@services = Bitcoin::Message::SERVICE_FLAGS[:network]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.parse_from_payload(payload)
|
25
|
+
buf = payload.is_a?(String) ? StringIO.new(payload) : payload
|
26
|
+
addr = new
|
27
|
+
addr.time = buf.read(4).unpack('V').first
|
28
|
+
addr.services = buf.read(8).unpack('Q').first
|
29
|
+
ip = IPAddr::new_ntoh(buf.read(16))
|
30
|
+
addr.ip = ip.ipv4_mapped? ? ip.native : ip.to_s
|
31
|
+
addr.port = buf.read(2).unpack('n').first
|
32
|
+
addr
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_payload
|
36
|
+
ip_addr = IPAddr.new (ip)
|
37
|
+
ip_addr = ip_addr.ipv4_mapped if ip_addr.ipv4?
|
38
|
+
[time, services].pack('VQ') << ip_addr.hton << [port].pack('n')
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
|
+
require 'ipaddr'
|
2
3
|
module Bitcoin
|
3
4
|
module Message
|
4
5
|
|
@@ -60,9 +61,13 @@ module Bitcoin
|
|
60
61
|
end
|
61
62
|
|
62
63
|
def pack_addr(addr)
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
separator = addr.rindex(':')
|
65
|
+
ip = addr[0...separator]
|
66
|
+
port = addr[separator + 1..-1].to_i
|
67
|
+
ip_addr = IPAddr.new(ip)
|
68
|
+
ip_addr = ip_addr.ipv4_mapped if ip_addr.ipv4?
|
69
|
+
[1].pack('Q') << ip_addr.hton << [port].pack('n')
|
70
|
+
# [[1].pack('Q'), "\x00" * 10, "\xFF\xFF", sockaddr[4...8], sockaddr[2...4]].join
|
66
71
|
end
|
67
72
|
|
68
73
|
def unpack_addr(addr)
|
data/lib/bitcoin/message.rb
CHANGED
@@ -8,6 +8,7 @@ module Bitcoin
|
|
8
8
|
autoload :Version, 'bitcoin/message/version'
|
9
9
|
autoload :VerAck, 'bitcoin/message/ver_ack'
|
10
10
|
autoload :Addr, 'bitcoin/message/addr'
|
11
|
+
autoload :NetworkAddr, 'bitcoin/message/network_addr'
|
11
12
|
autoload :Block, 'bitcoin/message/block'
|
12
13
|
autoload :FilterLoad, 'bitcoin/message/filter_load'
|
13
14
|
autoload :FilterAdd, 'bitcoin/message/filter_add'
|
@@ -47,5 +48,16 @@ module Bitcoin
|
|
47
48
|
|
48
49
|
DEFAULT_STOP_HASH = "00"*32
|
49
50
|
|
51
|
+
# the protocol version.
|
52
|
+
VERSION = {
|
53
|
+
headers: 31800,
|
54
|
+
pong: 60001,
|
55
|
+
bloom: 70011,
|
56
|
+
send_headers: 70012,
|
57
|
+
fee_filter: 70013,
|
58
|
+
compact: 70014,
|
59
|
+
compact_witness: 70015
|
60
|
+
}
|
61
|
+
|
50
62
|
end
|
51
63
|
end
|
data/lib/bitcoin/mnemonic.rb
CHANGED
@@ -24,7 +24,7 @@ module Bitcoin
|
|
24
24
|
def to_entropy(words)
|
25
25
|
word_master = load_words
|
26
26
|
mnemonic = words.map do |w|
|
27
|
-
index = word_master.index(w)
|
27
|
+
index = word_master.index(w.downcase)
|
28
28
|
raise IndexError, 'word not found in words list.' unless index
|
29
29
|
index.to_s(2).rjust(11, '0')
|
30
30
|
end.join
|
@@ -52,7 +52,7 @@ module Bitcoin
|
|
52
52
|
# @param [String] passphrase a passphrase which protects mnemonic. the default value is an empty string.
|
53
53
|
# @return [String] seed
|
54
54
|
def to_seed(mnemonic, passphrase: '')
|
55
|
-
OpenSSL::PKCS5.pbkdf2_hmac(mnemonic.join(' '),
|
55
|
+
OpenSSL::PKCS5.pbkdf2_hmac(mnemonic.join(' ').downcase,
|
56
56
|
'mnemonic' + passphrase, 2048, 64, OpenSSL::Digest::SHA512.new).bth
|
57
57
|
end
|
58
58
|
|
@@ -20,7 +20,7 @@ module Bitcoin
|
|
20
20
|
|
21
21
|
def initialize(peer)
|
22
22
|
@peer = peer
|
23
|
-
@logger =
|
23
|
+
@logger = peer.logger
|
24
24
|
@sendheaders = false
|
25
25
|
@attr_accessor = 0
|
26
26
|
@message = ''
|
@@ -28,6 +28,7 @@ module Bitcoin
|
|
28
28
|
|
29
29
|
def post_init
|
30
30
|
logger.info "connected. #{addr}"
|
31
|
+
peer.conn_time = Time.now.to_i
|
31
32
|
begin_handshake
|
32
33
|
end
|
33
34
|
|
@@ -51,6 +52,18 @@ module Bitcoin
|
|
51
52
|
EM.stop
|
52
53
|
end
|
53
54
|
|
55
|
+
def handle_error(e)
|
56
|
+
peer.handle_error(e)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# start handshake
|
62
|
+
def begin_handshake
|
63
|
+
logger.info "begin handshake with #{addr}"
|
64
|
+
send_message(peer.local_version)
|
65
|
+
end
|
66
|
+
|
54
67
|
end
|
55
68
|
|
56
69
|
end
|