tapyrus 0.3.3 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/{.prettierrc.yaml → .prettierrc.yml} +0 -1
  4. data/.ruby-version +1 -1
  5. data/Gemfile +2 -2
  6. data/README.md +1 -1
  7. data/Rakefile +2 -2
  8. data/exe/tapyrus-script-debugger +5 -5
  9. data/exe/tapyrusrb-cli +1 -1
  10. data/exe/tapyrusrbd +18 -17
  11. data/lib/openassets/payload.rb +2 -2
  12. data/lib/openassets/util.rb +2 -2
  13. data/lib/openassets.rb +4 -4
  14. data/lib/schnorr/sign_to_contract.rb +4 -4
  15. data/lib/schnorr/signature.rb +5 -5
  16. data/lib/schnorr.rb +14 -14
  17. data/lib/tapyrus/base58.rb +8 -8
  18. data/lib/tapyrus/bip175.rb +5 -5
  19. data/lib/tapyrus/block_header.rb +2 -2
  20. data/lib/tapyrus/bloom_filter.rb +1 -1
  21. data/lib/tapyrus/chain_params.rb +5 -5
  22. data/lib/tapyrus/constants.rb +1 -1
  23. data/lib/tapyrus/errors.rb +9 -9
  24. data/lib/tapyrus/ext/ecdsa.rb +4 -4
  25. data/lib/tapyrus/ext/json_parser.rb +1 -1
  26. data/lib/tapyrus/ext.rb +3 -3
  27. data/lib/tapyrus/ext_key.rb +21 -21
  28. data/lib/tapyrus/jws.rb +76 -0
  29. data/lib/tapyrus/key.rb +48 -20
  30. data/lib/tapyrus/key_path.rb +3 -3
  31. data/lib/tapyrus/logger.rb +4 -11
  32. data/lib/tapyrus/merkle_tree.rb +1 -1
  33. data/lib/tapyrus/message/addr.rb +2 -2
  34. data/lib/tapyrus/message/base.rb +2 -2
  35. data/lib/tapyrus/message/block.rb +1 -1
  36. data/lib/tapyrus/message/block_txn.rb +1 -1
  37. data/lib/tapyrus/message/cmpct_block.rb +1 -1
  38. data/lib/tapyrus/message/fee_filter.rb +3 -3
  39. data/lib/tapyrus/message/filter_add.rb +1 -1
  40. data/lib/tapyrus/message/filter_clear.rb +2 -2
  41. data/lib/tapyrus/message/filter_load.rb +7 -7
  42. data/lib/tapyrus/message/get_addr.rb +2 -2
  43. data/lib/tapyrus/message/get_block_txn.rb +1 -1
  44. data/lib/tapyrus/message/get_blocks.rb +1 -1
  45. data/lib/tapyrus/message/get_data.rb +1 -1
  46. data/lib/tapyrus/message/get_headers.rb +1 -1
  47. data/lib/tapyrus/message/header_and_short_ids.rb +6 -6
  48. data/lib/tapyrus/message/headers.rb +1 -1
  49. data/lib/tapyrus/message/headers_parser.rb +2 -2
  50. data/lib/tapyrus/message/inv.rb +1 -1
  51. data/lib/tapyrus/message/inventory.rb +3 -3
  52. data/lib/tapyrus/message/mem_pool.rb +2 -2
  53. data/lib/tapyrus/message/merkle_block.rb +3 -3
  54. data/lib/tapyrus/message/network_addr.rb +9 -9
  55. data/lib/tapyrus/message/not_found.rb +1 -1
  56. data/lib/tapyrus/message/ping.rb +3 -3
  57. data/lib/tapyrus/message/pong.rb +3 -3
  58. data/lib/tapyrus/message/reject.rb +6 -6
  59. data/lib/tapyrus/message/send_cmpct.rb +4 -4
  60. data/lib/tapyrus/message/send_headers.rb +2 -2
  61. data/lib/tapyrus/message/tx.rb +1 -1
  62. data/lib/tapyrus/message/ver_ack.rb +2 -2
  63. data/lib/tapyrus/message/version.rb +7 -7
  64. data/lib/tapyrus/message.rb +37 -37
  65. data/lib/tapyrus/mnemonic.rb +18 -16
  66. data/lib/tapyrus/network/connection.rb +2 -2
  67. data/lib/tapyrus/network/message_handler.rb +11 -11
  68. data/lib/tapyrus/network/peer.rb +1 -1
  69. data/lib/tapyrus/network/peer_discovery.rb +1 -1
  70. data/lib/tapyrus/network/pool.rb +4 -4
  71. data/lib/tapyrus/network.rb +6 -6
  72. data/lib/tapyrus/node/cli.rb +34 -34
  73. data/lib/tapyrus/node/configuration.rb +3 -3
  74. data/lib/tapyrus/node/spv.rb +2 -2
  75. data/lib/tapyrus/node.rb +3 -3
  76. data/lib/tapyrus/opcodes.rb +7 -7
  77. data/lib/tapyrus/out_point.rb +2 -2
  78. data/lib/tapyrus/rpc/http_server.rb +6 -6
  79. data/lib/tapyrus/rpc/request_handler.rb +5 -5
  80. data/lib/tapyrus/rpc/tapyrus_core_client.rb +10 -10
  81. data/lib/tapyrus/rpc.rb +4 -4
  82. data/lib/tapyrus/script/color.rb +3 -3
  83. data/lib/tapyrus/script/debugger.rb +9 -9
  84. data/lib/tapyrus/script/multisig.rb +2 -2
  85. data/lib/tapyrus/script/script.rb +28 -28
  86. data/lib/tapyrus/script/script_error.rb +42 -42
  87. data/lib/tapyrus/script/script_interpreter.rb +9 -9
  88. data/lib/tapyrus/script/tx_checker.rb +2 -5
  89. data/lib/tapyrus/secp256k1/native.rb +23 -23
  90. data/lib/tapyrus/secp256k1/rfc6979.rb +7 -7
  91. data/lib/tapyrus/secp256k1/ruby.rb +2 -2
  92. data/lib/tapyrus/secp256k1.rb +3 -3
  93. data/lib/tapyrus/slip39/share.rb +7 -7
  94. data/lib/tapyrus/slip39/sss.rb +24 -24
  95. data/lib/tapyrus/slip39.rb +514 -37
  96. data/lib/tapyrus/store/db/level_db.rb +2 -2
  97. data/lib/tapyrus/store/db.rb +1 -1
  98. data/lib/tapyrus/store/spv_chain.rb +7 -7
  99. data/lib/tapyrus/store.rb +3 -3
  100. data/lib/tapyrus/tip0137.rb +201 -0
  101. data/lib/tapyrus/tx.rb +12 -12
  102. data/lib/tapyrus/tx_builder.rb +3 -3
  103. data/lib/tapyrus/tx_in.rb +3 -3
  104. data/lib/tapyrus/tx_out.rb +3 -3
  105. data/lib/tapyrus/util.rb +21 -21
  106. data/lib/tapyrus/validation.rb +9 -9
  107. data/lib/tapyrus/version.rb +1 -1
  108. data/lib/tapyrus/wallet/account.rb +12 -12
  109. data/lib/tapyrus/wallet/base.rb +9 -8
  110. data/lib/tapyrus/wallet/db.rb +11 -11
  111. data/lib/tapyrus/wallet/master_key.rb +13 -13
  112. data/lib/tapyrus/wallet.rb +4 -4
  113. data/lib/tapyrus.rb +62 -59
  114. data/tapyrusrb.gemspec +33 -31
  115. metadata +27 -11
@@ -7,7 +7,7 @@ module Tapyrus
7
7
  include Tapyrus::HexConverter
8
8
 
9
9
  MAX_DEPTH = 255
10
- MASTER_FINGERPRINT = '00000000'
10
+ MASTER_FINGERPRINT = "00000000"
11
11
 
12
12
  attr_accessor :ver
13
13
  attr_accessor :depth
@@ -21,10 +21,10 @@ module Tapyrus
21
21
  def self.generate_master(seed)
22
22
  ext_key = ExtKey.new
23
23
  ext_key.depth = ext_key.number = 0
24
- ext_key.parent_fingerprint = '00000000'
25
- l = Tapyrus.hmac_sha512('Tapyrus seed', seed.htb)
24
+ ext_key.parent_fingerprint = "00000000"
25
+ l = Tapyrus.hmac_sha512("Tapyrus seed", seed.htb)
26
26
  left = l[0..31].bth.to_i(16)
27
- raise 'invalid key' if left >= CURVE_ORDER || left == 0
27
+ raise "invalid key" if left >= CURVE_ORDER || left == 0
28
28
  l_priv = ECDSA::Format::IntegerOctetString.encode(left, 32)
29
29
  ext_key.key = Tapyrus::Key.new(priv_key: l_priv.bth, key_type: Tapyrus::Key::TYPES[:compressed])
30
30
  ext_key.chain_code = l[32..-1]
@@ -45,8 +45,8 @@ module Tapyrus
45
45
 
46
46
  # serialize extended private key
47
47
  def to_payload
48
- version.htb << [depth].pack('C') << parent_fingerprint.htb << [number].pack('N') << chain_code <<
49
- [0x00].pack('C') << key.priv_key.htb
48
+ version.htb << [depth].pack("C") << parent_fingerprint.htb << [number].pack("N") << chain_code <<
49
+ [0x00].pack("C") << key.priv_key.htb
50
50
  end
51
51
 
52
52
  # Base58 encoded extended private key
@@ -99,15 +99,15 @@ module Tapyrus
99
99
  new_key.number = number
100
100
  new_key.parent_fingerprint = fingerprint
101
101
  if number > (Tapyrus::HARDENED_THRESHOLD - 1)
102
- data = [0x00].pack('C') << key.priv_key.htb << [number].pack('N')
102
+ data = [0x00].pack("C") << key.priv_key.htb << [number].pack("N")
103
103
  else
104
- data = key.pubkey.htb << [number].pack('N')
104
+ data = key.pubkey.htb << [number].pack("N")
105
105
  end
106
106
  l = Tapyrus.hmac_sha512(chain_code, data)
107
107
  left = l[0..31].bth.to_i(16)
108
- raise 'invalid key' if left >= CURVE_ORDER
108
+ raise "invalid key" if left >= CURVE_ORDER
109
109
  child_priv = (left + key.priv_key.to_i(16)) % CURVE_ORDER
110
- raise 'invalid key ' if child_priv >= CURVE_ORDER
110
+ raise "invalid key " if child_priv >= CURVE_ORDER
111
111
  child_priv = ECDSA::Format::IntegerOctetString.encode(child_priv, 32)
112
112
  new_key.key = Tapyrus::Key.new(priv_key: child_priv.bth, key_type: key_type)
113
113
  new_key.chain_code = l[32..-1]
@@ -143,9 +143,9 @@ module Tapyrus
143
143
  ext_key = ExtKey.new
144
144
  ext_key.ver = buf.read(4).bth # version
145
145
  raise ArgumentError, Errors::Messages::INVALID_BIP32_VERSION unless ExtKey.support_version?(ext_key.ver)
146
- ext_key.depth = buf.read(1).unpack('C').first
146
+ ext_key.depth = buf.read(1).unpack("C").first
147
147
  ext_key.parent_fingerprint = buf.read(4).bth
148
- ext_key.number = buf.read(4).unpack('N').first
148
+ ext_key.number = buf.read(4).unpack("N").first
149
149
  if ext_key.depth == 0
150
150
  unless ext_key.parent_fingerprint == ExtKey::MASTER_FINGERPRINT
151
151
  raise ArgumentError, Errors::Messages::INVALID_BIP32_FINGERPRINT
@@ -156,7 +156,7 @@ module Tapyrus
156
156
  raise ArgumentError, Errors::Messages::INVALID_BIP32_ZERO_DEPTH
157
157
  end
158
158
  ext_key.chain_code = buf.read(32)
159
- raise ArgumentError, Errors::Messages::INVALID_BIP32_PRIV_PREFIX unless buf.read(1).bth == '00' # 0x00
159
+ raise ArgumentError, Errors::Messages::INVALID_BIP32_PRIV_PREFIX unless buf.read(1).bth == "00" # 0x00
160
160
  ext_key.key = Tapyrus::Key.new(priv_key: buf.read(32).bth, key_type: Tapyrus::Key::TYPES[:compressed])
161
161
  ext_key
162
162
  end
@@ -200,7 +200,7 @@ module Tapyrus
200
200
  end
201
201
 
202
202
  def master?
203
- depth == 0 && number == 0 && parent_fingerprint == '00000000'
203
+ depth == 0 && number == 0 && parent_fingerprint == "00000000"
204
204
  end
205
205
  end
206
206
 
@@ -217,7 +217,7 @@ module Tapyrus
217
217
 
218
218
  # serialize extended pubkey
219
219
  def to_payload
220
- version.htb << [depth].pack('C') << parent_fingerprint.htb << [number].pack('N') << chain_code << pub.htb
220
+ version.htb << [depth].pack("C") << parent_fingerprint.htb << [number].pack("N") << chain_code << pub.htb
221
221
  end
222
222
 
223
223
  def pub
@@ -272,11 +272,11 @@ module Tapyrus
272
272
  new_key.depth = depth + 1
273
273
  new_key.number = number
274
274
  new_key.parent_fingerprint = fingerprint
275
- raise 'hardened key is not support' if number > (Tapyrus::HARDENED_THRESHOLD - 1)
276
- data = pub.htb << [number].pack('N')
275
+ raise "hardened key is not support" if number > (Tapyrus::HARDENED_THRESHOLD - 1)
276
+ data = pub.htb << [number].pack("N")
277
277
  l = Tapyrus.hmac_sha512(chain_code, data)
278
278
  left = l[0..31].bth.to_i(16)
279
- raise 'invalid key' if left >= CURVE_ORDER
279
+ raise "invalid key" if left >= CURVE_ORDER
280
280
  l_priv = ECDSA::Format::IntegerOctetString.encode(left, 32)
281
281
  p1 = Tapyrus::Key.new(priv_key: l_priv.bth, key_type: Tapyrus::Key::TYPES[:uncompressed]).to_point
282
282
  p2 = Tapyrus::Key.new(pubkey: pubkey, key_type: key_type).to_point
@@ -314,9 +314,9 @@ module Tapyrus
314
314
  ext_pubkey = ExtPubkey.new
315
315
  ext_pubkey.ver = buf.read(4).bth # version
316
316
  raise ArgumentError, Errors::Messages::INVALID_BIP32_VERSION unless ExtPubkey.support_version?(ext_pubkey.ver)
317
- ext_pubkey.depth = buf.read(1).unpack('C').first
317
+ ext_pubkey.depth = buf.read(1).unpack("C").first
318
318
  ext_pubkey.parent_fingerprint = buf.read(4).bth
319
- ext_pubkey.number = buf.read(4).unpack('N').first
319
+ ext_pubkey.number = buf.read(4).unpack("N").first
320
320
  if ext_pubkey.depth == 0
321
321
  unless ext_pubkey.parent_fingerprint == ExtKey::MASTER_FINGERPRINT
322
322
  raise ArgumentError, Errors::Messages::INVALID_BIP32_FINGERPRINT
@@ -365,7 +365,7 @@ module Tapyrus
365
365
  end
366
366
 
367
367
  def master?
368
- depth == 0 && number == 0 && parent_fingerprint == '00000000'
368
+ depth == 0 && number == 0 && parent_fingerprint == "00000000"
369
369
  end
370
370
  end
371
371
  end
@@ -0,0 +1,76 @@
1
+ module Tapyrus
2
+ module JWS
3
+ module_function
4
+
5
+ class DecodeError < StandardError
6
+ end
7
+
8
+ ALGO = "ES256K"
9
+ CURVE_NAME = "secp256k1"
10
+
11
+ # Encode data as JWS format.
12
+ #
13
+ # @param payload [Object] The data to be encoded as JWS.
14
+ # @param private_key_hex [String] The private key as hex string
15
+ # @return [String] JWS signed with the specified private key
16
+ def encode(payload, private_key_hex)
17
+ parameters = { use: "sig", alg: ALGO }
18
+
19
+ # see https://github.com/nov/json-jwt/blob/413848c/lib/json/jwk.rb#L162-L172
20
+ # see https://www.rfc-editor.org/rfc/rfc5915.html#page-6
21
+ sequence =
22
+ OpenSSL::ASN1.Sequence(
23
+ [
24
+ OpenSSL::ASN1.Integer(1),
25
+ OpenSSL::ASN1.OctetString(OpenSSL::BN.new(private_key_hex, 16).to_s(2)),
26
+ OpenSSL::ASN1.ObjectId(CURVE_NAME, 0, :EXPLICIT),
27
+ OpenSSL::ASN1.BitString(
28
+ ECDSA::Format::PointOctetString.encode(point_for(private_key_hex), compression: false),
29
+ 1,
30
+ :EXPLICIT
31
+ )
32
+ ]
33
+ )
34
+ ec_key = OpenSSL::PKey::EC.new(sequence.to_der)
35
+ jwk = JWT::JWK.new(ec_key, parameters)
36
+ jwks_hash = JWT::JWK::Set.new(jwk).export(include_private: false)
37
+ JWT.encode(payload, jwk.signing_key, jwk[:alg], { typ: "JWT", algo: ALGO, jwk: jwks_hash })
38
+ end
39
+
40
+ # Decode JWS to JSON object
41
+ #
42
+ # @param jws [String] The JWS formatted data to be decoded
43
+ # @return [Array[JSON]] JSON objects representing JWS header and payload.
44
+ # @raise [JWT::VerificationError] If the verification of the signature fails
45
+ # @raise [Tapyrus::JWS::DecodeError] If no jwk key found in header
46
+ # @raise [Tapyrus::JWS::DecodeError] If jwk kty header is not EC
47
+ # @raise [Tapyrus::JWS::DecodeError] If jwk crv header is not P-256K
48
+ # @raise [Tapyrus::JWS::DecodeError] If jwk use header is not sig
49
+ # @raise [Tapyrus::JWS::DecodeError] If jwk alg header is not ES256K
50
+ def decode(jws)
51
+ jwt_claims, header = JWT.decode(jws, nil, false, { algorithm: ALGO })
52
+ jwks_hash = header.dig("jwk", "keys")
53
+ raise Tapyrus::JWS::DecodeError, "No jwk key found in header" unless jwks_hash
54
+ validate_header!(jwks_hash)
55
+ jwks = JWT::JWK::Set.new(jwks_hash)
56
+ JWT.decode(jws, nil, true, { algorithm: ALGO, jwks: jwks, allow_nil_kid: true })
57
+ end
58
+
59
+ def validate_header!(jwks)
60
+ jwk = jwks.first
61
+ raise Tapyrus::JWS::DecodeError, "No jwk key found in header" unless jwk
62
+ raise Tapyrus::JWS::DecodeError, 'kty must be "EC"' if jwk["kty"] && jwk["kty"] != "EC"
63
+ raise Tapyrus::JWS::DecodeError, 'crv must be "P-256K"' if jwk["crv"] && jwk["crv"] != "P-256K"
64
+ raise Tapyrus::JWS::DecodeError, 'use must be "sig"' if jwk["use"] && jwk["use"] != "sig"
65
+ raise Tapyrus::JWS::DecodeError, 'alg must be "ES256K"' if jwk["alg"] && jwk["alg"] != "ES256K"
66
+ end
67
+
68
+ # Return point object that represents rG
69
+ #
70
+ # @param r_hex [String] r value as hex string
71
+ # @return [ECDSA::Point] The point that represents r * G
72
+ def point_for(r_hex)
73
+ Tapyrus::Key.new(priv_key: r_hex).to_point
74
+ end
75
+ end
76
+ end
data/lib/tapyrus/key.rb CHANGED
@@ -9,7 +9,7 @@ module Tapyrus
9
9
  SIGNATURE_SIZE = 72
10
10
  COMPACT_SIGNATURE_SIZE = 65
11
11
 
12
- SIG_ALGO = [:ecdsa, :schnorr]
12
+ SIG_ALGO = %i[ecdsa schnorr]
13
13
 
14
14
  attr_accessor :priv_key
15
15
  attr_accessor :pubkey
@@ -31,7 +31,7 @@ module Tapyrus
31
31
  # @return [Tapyrus::Key] a key object.
32
32
  def initialize(priv_key: nil, pubkey: nil, key_type: nil, compressed: true, allow_hybrid: false)
33
33
  if key_type.nil? && !compressed.nil? && pubkey.nil?
34
- warn('Use key_type parameter instead of compressed. compressed parameter removed in the future.')
34
+ warn("Use key_type parameter instead of compressed. compressed parameter removed in the future.")
35
35
  end
36
36
  if key_type
37
37
  @key_type = key_type
@@ -56,7 +56,7 @@ module Tapyrus
56
56
 
57
57
  # generate key pair
58
58
  def self.generate(key_type = TYPES[:compressed])
59
- priv_key, pubkey = Tapyrus.secp_impl.generate_key_pair
59
+ priv_key, pubkey = Tapyrus.secp_impl.generate_key_pair(compressed: key_type != TYPES[:uncompressed])
60
60
  new(priv_key: priv_key, pubkey: pubkey, key_type: key_type)
61
61
  end
62
62
 
@@ -64,22 +64,22 @@ module Tapyrus
64
64
  # https://en.bitcoin.it/wiki/Wallet_import_format
65
65
  def self.from_wif(wif)
66
66
  hex = Base58.decode(wif)
67
- raise ArgumentError, 'data is too short' if hex.htb.bytesize < 4
67
+ raise ArgumentError, "data is too short" if hex.htb.bytesize < 4
68
68
  version = hex[0..1]
69
69
  data = hex[2...-8].htb
70
70
  checksum = hex[-8..-1]
71
- raise ArgumentError, 'invalid version' unless version == Tapyrus.chain_params.privkey_version
71
+ raise ArgumentError, "invalid version" unless version == Tapyrus.chain_params.privkey_version
72
72
  unless Tapyrus.calc_checksum(version + data.bth) == checksum
73
73
  raise ArgumentError, Errors::Messages::INVALID_CHECKSUM
74
74
  end
75
75
  key_len = data.bytesize
76
- if key_len == COMPRESSED_PUBLIC_KEY_SIZE && data[-1].unpack('C').first == 1
76
+ if key_len == COMPRESSED_PUBLIC_KEY_SIZE && data[-1].unpack("C").first == 1
77
77
  key_type = TYPES[:compressed]
78
78
  data = data[0..-2]
79
79
  elsif key_len == 32
80
80
  key_type = TYPES[:uncompressed]
81
81
  else
82
- raise ArgumentError, 'Wrong number of bytes for a private key, not 32 or 33'
82
+ raise ArgumentError, "Wrong number of bytes for a private key, not 32 or 33"
83
83
  end
84
84
  new(priv_key: data.bth, key_type: key_type)
85
85
  end
@@ -88,7 +88,7 @@ module Tapyrus
88
88
  def to_wif
89
89
  version = Tapyrus.chain_params.privkey_version
90
90
  hex = version + priv_key
91
- hex += '01' if compressed?
91
+ hex += "01" if compressed?
92
92
  hex += Tapyrus.calc_checksum(hex)
93
93
  Base58.encode(hex)
94
94
  end
@@ -100,7 +100,7 @@ module Tapyrus
100
100
  # @param [Symbol] algo Algorithms used for verification. Either :ecdsa or :schnorr is supported. default value is :ecdsa.
101
101
  # @return [String] signature data with binary format
102
102
  def sign(data, low_r = true, extra_entropy = nil, algo: :ecdsa)
103
- raise ArgumentError, 'Unsupported algorithm has been specified.' unless SIG_ALGO.include?(algo)
103
+ raise ArgumentError, "Unsupported algorithm has been specified." unless SIG_ALGO.include?(algo)
104
104
  case algo
105
105
  when :ecdsa
106
106
  sign_ecdsa(data, low_r, extra_entropy)
@@ -119,7 +119,7 @@ module Tapyrus
119
119
  def verify(sig, origin, algo: :ecdsa)
120
120
  return false unless valid_pubkey?
121
121
  begin
122
- raise ArgumentError, 'Unsupported algorithm has been specified.' unless SIG_ALGO.include?(algo)
122
+ raise ArgumentError, "Unsupported algorithm has been specified." unless SIG_ALGO.include?(algo)
123
123
  sig = ecdsa_signature_parse_der_lax(sig) if algo == :ecdsa
124
124
  secp256k1_module.verify_sig(origin, sig, pubkey, algo: algo)
125
125
  rescue Exception
@@ -173,17 +173,45 @@ module Tapyrus
173
173
 
174
174
  # check +sig+ is low.
175
175
  def self.low_signature?(sig)
176
- s = sig.unpack('C*')
176
+ s = sig.unpack("C*")
177
177
  len_r = s[3]
178
178
  len_s = s[5 + len_r]
179
179
  val_s = s.slice(6 + len_r, len_s)
180
180
 
181
181
  # prettier-ignore
182
182
  max_mod_half_order = [
183
- 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
184
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
185
- 0x5d, 0x57, 0x6e, 0x73, 0x57, 0xa4, 0x50, 0x1d,
186
- 0xdf, 0xe9, 0x2f, 0x46, 0x68, 0x1b, 0x20, 0xa0
183
+ 0x7f,
184
+ 0xff,
185
+ 0xff,
186
+ 0xff,
187
+ 0xff,
188
+ 0xff,
189
+ 0xff,
190
+ 0xff,
191
+ 0xff,
192
+ 0xff,
193
+ 0xff,
194
+ 0xff,
195
+ 0xff,
196
+ 0xff,
197
+ 0xff,
198
+ 0xff,
199
+ 0x5d,
200
+ 0x57,
201
+ 0x6e,
202
+ 0x73,
203
+ 0x57,
204
+ 0xa4,
205
+ 0x50,
206
+ 0x1d,
207
+ 0xdf,
208
+ 0xe9,
209
+ 0x2f,
210
+ 0x46,
211
+ 0x68,
212
+ 0x1b,
213
+ 0x20,
214
+ 0xa0
187
215
  ]
188
216
  compare_big_endian(val_s, [0]) > 0 && compare_big_endian(val_s, max_mod_half_order) <= 0
189
217
  end
@@ -199,7 +227,7 @@ module Tapyrus
199
227
 
200
228
  return false if sig.bytesize < num_parts || sig.bytesize > size # Minimum and maximum size check
201
229
 
202
- s = sig.unpack('C*')
230
+ s = sig.unpack("C*")
203
231
 
204
232
  return false if s[0] != 0x30 || s[1] != s.size - (data_sig ? 2 : 3) # A signature is of type 0x30 (compound). Make sure the length covers the entire signature.
205
233
 
@@ -267,11 +295,11 @@ module Tapyrus
267
295
  # strict DER before being passed to this module, and we know it supports all
268
296
  # violations present in the blockchain before that point.
269
297
  def ecdsa_signature_parse_der_lax(sig)
270
- sig_array = sig.unpack('C*')
298
+ sig_array = sig.unpack("C*")
271
299
  len_r = sig_array[3]
272
- r = sig_array[4...(len_r + 4)].pack('C*').bth
300
+ r = sig_array[4...(len_r + 4)].pack("C*").bth
273
301
  len_s = sig_array[len_r + 5]
274
- s = sig_array[(len_r + 6)...(len_r + 6 + len_s)].pack('C*').bth
302
+ s = sig_array[(len_r + 6)...(len_r + 6 + len_s)].pack("C*").bth
275
303
  ECDSA::Signature.new(r.to_i(16), s.to_i(16)).to_der
276
304
  end
277
305
 
@@ -292,7 +320,7 @@ module Tapyrus
292
320
  if low_r && !sig_has_low_r?(sig)
293
321
  counter = 1
294
322
  until sig_has_low_r?(sig)
295
- extra_entropy = [counter].pack('I*').bth.ljust(64, '0').htb
323
+ extra_entropy = [counter].pack("I*").bth.ljust(64, "0").htb
296
324
  sig = secp256k1_module.sign_data(data, priv_key, extra_entropy, algo: :ecdsa)
297
325
  counter += 1
298
326
  end
@@ -5,11 +5,11 @@ module Tapyrus
5
5
  # @return [Array[Integer]] key path numbers.
6
6
  def parse_key_path(path_string)
7
7
  path_string
8
- .split('/')
8
+ .split("/")
9
9
  .map
10
10
  .with_index do |p, index|
11
11
  if index == 0
12
- raise ArgumentError.new("#{path_string} is invalid format.") unless p == 'm'
12
+ raise ArgumentError.new("#{path_string} is invalid format.") unless p == "m"
13
13
  next
14
14
  end
15
15
  raise ArgumentError.new("#{path_string} is invalid format.") unless p.delete("'") =~ /^[0-9]+$/
@@ -23,7 +23,7 @@ module Tapyrus
23
23
  # @param [Array[Integer]] key path numbers.
24
24
  # @return [String] path string.
25
25
  def to_key_path(numbers)
26
- "m/#{numbers.map { |p| p >= Tapyrus::HARDENED_THRESHOLD ? "#{p - Tapyrus::HARDENED_THRESHOLD}'" : p.to_s }.join('/')}"
26
+ "m/#{numbers.map { |p| p >= Tapyrus::HARDENED_THRESHOLD ? "#{p - Tapyrus::HARDENED_THRESHOLD}'" : p.to_s }.join("/")}"
27
27
  end
28
28
  end
29
29
  end
@@ -1,4 +1,4 @@
1
- require 'logger'
1
+ require "logger"
2
2
 
3
3
  module Tapyrus
4
4
  # Simple Logger module
@@ -15,15 +15,8 @@ module Tapyrus
15
15
  logger.level = level
16
16
  logger.formatter =
17
17
  proc do |severity, datetime, progname, msg|
18
- Format % [
19
- severity[0..0],
20
- format_datetime(datetime),
21
- $$,
22
- Thread.current.object_id,
23
- severity,
24
- progname,
25
- msg2str(msg)
26
- ]
18
+ Format %
19
+ [severity[0..0], format_datetime(datetime), $$, Thread.current.object_id, severity, progname, msg2str(msg)]
27
20
  end
28
21
  logger
29
22
  end
@@ -40,7 +33,7 @@ module Tapyrus
40
33
  end
41
34
 
42
35
  def format_datetime(time)
43
- time.strftime(@datetime_format || '%Y-%m-%dT%H:%M:%S.%6N '.freeze)
36
+ time.strftime(@datetime_format || "%Y-%m-%dT%H:%M:%S.%6N ".freeze)
44
37
  end
45
38
  end
46
39
  end
@@ -93,7 +93,7 @@ module Tapyrus
93
93
  def value
94
94
  return @value if @value
95
95
  self.right = left.dup unless right
96
- Tapyrus.double_sha256([left.value + right.value].pack('H*')).bth
96
+ Tapyrus.double_sha256([left.value + right.value].pack("H*")).bth
97
97
  end
98
98
 
99
99
  def root?
@@ -1,11 +1,11 @@
1
- require 'ipaddr'
1
+ require "ipaddr"
2
2
 
3
3
  module Tapyrus
4
4
  module Message
5
5
  # addr message
6
6
  # https://bitcoin.org/en/developer-reference#addr
7
7
  class Addr < Base
8
- COMMAND = 'addr'
8
+ COMMAND = "addr"
9
9
 
10
10
  attr_reader :addrs
11
11
 
@@ -12,14 +12,14 @@ module Tapyrus
12
12
  payload = to_payload
13
13
  magic = Tapyrus.chain_params.magic_head.htb
14
14
  command_name = self.class.const_get(:COMMAND, false).ljust(12, "\x00")
15
- payload_size = [payload.bytesize].pack('V')
15
+ payload_size = [payload.bytesize].pack("V")
16
16
  checksum = Tapyrus.double_sha256(payload)[0...4]
17
17
  magic << command_name << payload_size << checksum << payload
18
18
  end
19
19
 
20
20
  # abstract method
21
21
  def to_payload
22
- raise 'to_payload must be implemented in a child class.'
22
+ raise "to_payload must be implemented in a child class."
23
23
  end
24
24
  end
25
25
  end
@@ -7,7 +7,7 @@ module Tapyrus
7
7
  attr_accessor :transactions
8
8
  attr_accessor :use_segwit
9
9
 
10
- COMMAND = 'block'
10
+ COMMAND = "block"
11
11
 
12
12
  def initialize(header, transactions = [])
13
13
  @header = header
@@ -3,7 +3,7 @@ module Tapyrus
3
3
  # blocktxn message.
4
4
  # https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki#blocktxn
5
5
  class BlockTxn < Base
6
- COMMAND = 'blocktxn'
6
+ COMMAND = "blocktxn"
7
7
 
8
8
  attr_accessor :block_transactions
9
9
 
@@ -3,7 +3,7 @@ module Tapyrus
3
3
  # cmpctblock message. support only version 1.
4
4
  # https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
5
5
  class CmpctBlock < Base
6
- COMMAND = 'cmpctblock'
6
+ COMMAND = "cmpctblock"
7
7
 
8
8
  attr_accessor :header_and_short_ids
9
9
 
@@ -3,7 +3,7 @@ module Tapyrus
3
3
  # feefilter message
4
4
  # https://bitcoin.org/en/developer-reference#feefilter
5
5
  class FeeFilter < Base
6
- COMMAND = 'feefilter'
6
+ COMMAND = "feefilter"
7
7
 
8
8
  # The fee rate (in satoshis per kilobyte)
9
9
  attr_accessor :fee_rate
@@ -13,11 +13,11 @@ module Tapyrus
13
13
  end
14
14
 
15
15
  def self.parse_from_payload(payload)
16
- new(payload.unpack('Q').first)
16
+ new(payload.unpack("Q").first)
17
17
  end
18
18
 
19
19
  def to_payload
20
- [fee_rate].pack('Q')
20
+ [fee_rate].pack("Q")
21
21
  end
22
22
  end
23
23
  end
@@ -3,7 +3,7 @@ module Tapyrus
3
3
  # filteradd message
4
4
  # https://bitcoin.org/en/developer-reference#filteradd
5
5
  class FilterAdd < Base
6
- COMMAND = 'filteradd'
6
+ COMMAND = "filteradd"
7
7
 
8
8
  # element must be sent in the byte order they would use when appearing in a raw transaction;
9
9
  attr_accessor :element
@@ -3,10 +3,10 @@ module Tapyrus
3
3
  # filterclear message
4
4
  # https://bitcoin.org/en/developer-reference#filterclear
5
5
  class FilterClear < Base
6
- COMMAND = 'filterclear'
6
+ COMMAND = "filterclear"
7
7
 
8
8
  def to_payload
9
- ''
9
+ ""
10
10
  end
11
11
  end
12
12
  end
@@ -3,7 +3,7 @@ module Tapyrus
3
3
  # filterload message
4
4
  # https://bitcoin.org/en/developer-reference#filterload
5
5
  class FilterLoad < Base
6
- COMMAND = 'filterload'
6
+ COMMAND = "filterload"
7
7
 
8
8
  BLOOM_UPDATE_NONE = 0
9
9
  BLOOM_UPDATE_ALL = 1
@@ -20,16 +20,16 @@ module Tapyrus
20
20
  def self.parse_from_payload(payload)
21
21
  buf = StringIO.new(payload)
22
22
  filter_count = Tapyrus.unpack_var_int_from_io(buf)
23
- filter = buf.read(filter_count).unpack('C*')
24
- func_count = buf.read(4).unpack('V').first
25
- tweak = buf.read(4).unpack('V').first
26
- flag = buf.read(1).unpack('C').first
23
+ filter = buf.read(filter_count).unpack("C*")
24
+ func_count = buf.read(4).unpack("V").first
25
+ tweak = buf.read(4).unpack("V").first
26
+ flag = buf.read(1).unpack("C").first
27
27
  FilterLoad.new(Tapyrus::BloomFilter.new(filter, func_count, tweak), flag)
28
28
  end
29
29
 
30
30
  def to_payload
31
- Tapyrus.pack_var_int(filter.filter.size) << filter.filter.pack('C*') <<
32
- [filter.hash_funcs, filter.tweak, flag].pack('VVC')
31
+ Tapyrus.pack_var_int(filter.filter.size) << filter.filter.pack("C*") <<
32
+ [filter.hash_funcs, filter.tweak, flag].pack("VVC")
33
33
  end
34
34
  end
35
35
  end
@@ -3,10 +3,10 @@ module Tapyrus
3
3
  # getaddr message
4
4
  # https://bitcoin.org/en/developer-reference#getaddr
5
5
  class GetAddr < Base
6
- COMMAND = 'getaddr'
6
+ COMMAND = "getaddr"
7
7
 
8
8
  def to_payload
9
- ''
9
+ ""
10
10
  end
11
11
  end
12
12
  end
@@ -3,7 +3,7 @@ module Tapyrus
3
3
  # getblocktxn message.
4
4
  # https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
5
5
  class GetBlockTxn < Base
6
- COMMAND = 'getblocktxn'
6
+ COMMAND = "getblocktxn"
7
7
 
8
8
  attr_accessor :request
9
9
 
@@ -6,7 +6,7 @@ module Tapyrus
6
6
  include HeadersParser
7
7
  extend HeadersParser
8
8
 
9
- COMMAND = 'getblocks'
9
+ COMMAND = "getblocks"
10
10
 
11
11
  # protocol version
12
12
  attr_accessor :version
@@ -6,7 +6,7 @@ module Tapyrus
6
6
  include InventoriesParser
7
7
  extend InventoriesParser
8
8
 
9
- COMMAND = 'getdata'
9
+ COMMAND = "getdata"
10
10
 
11
11
  attr_reader :inventories
12
12
 
@@ -6,7 +6,7 @@ module Tapyrus
6
6
  include HeadersParser
7
7
  extend HeadersParser
8
8
 
9
- COMMAND = 'getheaders'
9
+ COMMAND = "getheaders"
10
10
 
11
11
  # protocol version
12
12
  attr_accessor :version