tapyrus 0.3.3 → 0.3.5

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.
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