tapyrus 0.2.8 → 0.2.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ad31bf4aa539aa394eeb5002fe11fc9b8c6a43aab73c9e36a63220159c2fb30
4
- data.tar.gz: 8b7aaacfd238de278b334b7b26249045facf14843b8fb32985045c0a52b9cdc9
3
+ metadata.gz: 82146cdd150374b76b593273e44c31f4f578d38a1b7dcabea0b0d1fd9acbbb5f
4
+ data.tar.gz: 8895de33dd2b36412f509c4e35465d513d3d6c98a0bcfc0e7db241a77acd8b3b
5
5
  SHA512:
6
- metadata.gz: ad3bc4d2fbaaf0e228cd7c07ee78e878f6b913e971645b8a6e188df70c9e363fbc210456833436f1e7ea780881bd10accdd7a069365e26fc09195744fe606766
7
- data.tar.gz: b267bb2ff699df8822feffc75573db5e506dc5490f5f79146cfaf16d20abfd14660ddbfa4f2f01401d54b5bb9ecdb646613de8c7a28b01d48260aebb862834d3
6
+ metadata.gz: e386ac9d8578846437902e78d79b3d4419c85df861c831c92641da94d2d46a37c4793efaafa8e28a1da4466e5347fbe79f66beb0d925fe2bfc83cca1d1e90c99
7
+ data.tar.gz: a34fa0709093aafb118356b7736b409c733e1185a22538f7e2ed4392dac0ac661a652a31853f652d988860ee66c8b57124815b0fc28dd795b7bea97ad44182c5
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.6.3
1
+ 3.0.2
@@ -0,0 +1,51 @@
1
+ module Schnorr
2
+ module SignToContract
3
+ module_function
4
+
5
+ GROUP = ECDSA::Group::Secp256k1
6
+
7
+ # Generate schnorr signature for sign-to-signature.
8
+ # @param message [String] A message to be signed with binary format.
9
+ # @param private_key [Integer] The private key.
10
+ # @param contract [String] A contract information with 32-bytes binary format.
11
+ # @return [(Schnorr::Signature, ECDSA::Point)] signature and point to prove the commitment to contract.
12
+ def sign(message, private_key, contract)
13
+ raise 'The message must be a 32-byte array.' unless message.bytesize == 32
14
+ raise 'private_key is zero or over the curve order.' if private_key == 0 || private_key >= GROUP.order
15
+ raise 'The contract must be a 32-byte binary string.' unless contract.bytesize == 32
16
+
17
+ p = GROUP.new_point(private_key)
18
+ k0 = Schnorr.deterministic_nonce(message, private_key)
19
+
20
+ k1, r = tweak(k0, contract)
21
+
22
+ q = GROUP.new_point(k1)
23
+ k = ECDSA::PrimeField.jacobi(q.y, GROUP.field.prime) == 1 ? k1 : GROUP.order - k1
24
+
25
+ e = Schnorr.create_challenge(q.x, p, message)
26
+
27
+ [Schnorr::Signature.new(q.x, (k + e * private_key) % GROUP.order), r]
28
+ end
29
+
30
+ def tweak(k, contract)
31
+ r = GROUP.new_point(k)
32
+ rx = ECDSA::Format::IntegerOctetString.encode(r.x, GROUP.byte_length)
33
+ h = Tapyrus.sha256(rx + contract)
34
+ k1 = (k + h.bth.to_i(16)) % GROUP.order
35
+ raise 'Creation of signature failed. k + h(R || c) is zero' if k1.zero?
36
+ [k1, r]
37
+ end
38
+
39
+ # Validate contract
40
+ # @param r [ECDSA::Point] point to prove the commitment.
41
+ # @param signature [Schnorr::Signature] signature.
42
+ # @param contract [String] A contract information with 32-bytes binary format.
43
+ # @return true if commitment for contract is valid, otherwise false
44
+ def valid_contract?(r, signature, contract)
45
+ rx = ECDSA::Format::IntegerOctetString.encode(r.x, GROUP.byte_length)
46
+ commitment = Tapyrus.sha256(rx + contract).bth.to_i(16) % GROUP.order
47
+ point = r + GROUP.generator.multiply_by_scalar(commitment)
48
+ signature.r == point.x
49
+ end
50
+ end
51
+ end
data/lib/schnorr.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module Schnorr
2
2
  autoload :Signature, 'schnorr/signature'
3
+ autoload :SignToContract, 'schnorr/sign_to_contract'
3
4
 
4
5
  module_function
5
6
 
@@ -16,12 +17,7 @@ module Schnorr
16
17
  raise 'private_key is zero or over the curve order.' if private_key == 0 || private_key >= GROUP.order
17
18
 
18
19
  p = GROUP.new_point(private_key)
19
- secret = ECDSA::Format::IntegerOctetString.encode(private_key, GROUP.byte_length)
20
- secret = secret + message + ALGO16
21
- nonce = Tapyrus::Secp256k1::RFC6979.generate_rfc6979_nonce(secret, '')
22
-
23
- k0 = nonce % GROUP.order
24
- raise 'Creation of signature failed. k is zero' if k0.zero?
20
+ k0 = deterministic_nonce(message, private_key)
25
21
 
26
22
  r = GROUP.new_point(k0)
27
23
  k = ECDSA::PrimeField.jacobi(r.y, GROUP.field.prime) == 1 ? k0 : GROUP.order - k0
@@ -31,6 +27,16 @@ module Schnorr
31
27
  Schnorr::Signature.new(r.x, (k + e * private_key) % GROUP.order)
32
28
  end
33
29
 
30
+ def deterministic_nonce(message, private_key)
31
+ secret = ECDSA::Format::IntegerOctetString.encode(private_key, GROUP.byte_length)
32
+ secret = secret + message + ALGO16
33
+ nonce = Tapyrus::Secp256k1::RFC6979.generate_rfc6979_nonce(secret, '')
34
+
35
+ k0 = nonce % GROUP.order
36
+ raise 'Creation of signature failed. k is zero' if k0.zero?
37
+ k0
38
+ end
39
+
34
40
  # Verifies the given {Signature} and returns true if it is valid.
35
41
  # @param message (String) A message to be signed with binary format.
36
42
  # @param public_key (String) The public key with binary format.
@@ -0,0 +1,78 @@
1
+ module Tapyrus
2
+ # Key generation based on BIP-175
3
+ #
4
+ # @example
5
+ #
6
+ # master = Tapyrus::ExtKey.from_base58('xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNHsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73')
7
+ # bip175 = Tapyrus::BIP175.from_private_key(master)
8
+ # bip175 << "foo"
9
+ # bip175 << "bar"
10
+ # bip175.addr
11
+ # > 1C7f322izqMqLzZzfzkPAjxBzprxDi47Yf
12
+ #
13
+ # @see https://github.com/bitcoin/bips/blob/master/bip-0175.mediawiki
14
+ class BIP175
15
+ PURPOSE_TYPE = 175
16
+
17
+ attr_accessor :master_ext_key, :payment_base
18
+
19
+ def initialize
20
+ @contracts = []
21
+ end
22
+
23
+ # @param key [Tapyrus::ExtKey] master private extended key
24
+ def self.from_ext_key(key)
25
+ raise ArgumentError, 'key should be Tapyrus::ExtKey' unless key.is_a?(Tapyrus::ExtKey)
26
+ raise ArgumentError, 'key should be master private extended key' unless key.master?
27
+ new.tap do |bip175|
28
+ bip175.master_ext_key = key
29
+ bip175.payment_base =
30
+ key.derive(PURPOSE_TYPE, true).derive(Tapyrus.chain_params.bip44_coin_type, true).ext_pubkey
31
+ end
32
+ end
33
+
34
+ # @param key [Tapyrus::ExtPubkey] contract base public key
35
+ def self.from_ext_pubkey(key)
36
+ raise ArgumentError, 'key should be Tapyrus::ExtPubkey' unless key.is_a?(Tapyrus::ExtPubkey)
37
+ new.tap { |bip175| bip175.payment_base = key }
38
+ end
39
+
40
+ # Add value of hashed contract
41
+ # @param contract [String] contract information
42
+ def add(contract)
43
+ @contracts << Tapyrus.sha256(contract)
44
+ self
45
+ end
46
+ alias << add
47
+
48
+ # Return combined hash consist of payment_base and contract hashes
49
+ # @return [String] contract_hash
50
+ def combined_hash
51
+ hashes = @contracts.map { |c| c.bth }.sort
52
+ concatenated_hash = [payment_base.to_base58].concat(hashes).join
53
+ Tapyrus.sha256(concatenated_hash)
54
+ end
55
+
56
+ # Return pay-to-contract extended private key
57
+ # @return [Tapyrus::ExtKey] extended private key
58
+ def priv_key
59
+ key = master_ext_key.derive(PURPOSE_TYPE, true).derive(Tapyrus.chain_params.bip44_coin_type, true)
60
+
61
+ # Split every 2 bytes
62
+ paths = combined_hash.unpack('S>*')
63
+ paths.inject(key) { |key, p| key.derive(p) }
64
+ end
65
+
66
+ # Return pay-to-contract extended public key
67
+ # @return [Tapyrus::ExtPubkey] extended public key
68
+ def pubkey
69
+ # Split every 2 bytes
70
+ paths = combined_hash.unpack('S>*')
71
+ paths.inject(payment_base) { |key, p| key.derive(p) }
72
+ end
73
+
74
+ def addr
75
+ pubkey.addr
76
+ end
77
+ end
78
+ end
@@ -196,6 +196,10 @@ module Tapyrus
196
196
  Tapyrus.chain_params.extended_pubkey_version
197
197
  end
198
198
  end
199
+
200
+ def master?
201
+ depth == 0 && number == 0 && parent_fingerprint == '00000000'
202
+ end
199
203
  end
200
204
 
201
205
  # BIP-32 Extended public key
@@ -356,5 +360,9 @@ module Tapyrus
356
360
  p = Tapyrus.chain_params
357
361
  [p.bip49_pubkey_p2wpkh_p2sh_version, p.bip84_pubkey_p2wpkh_version, p.extended_pubkey_version].include?(version)
358
362
  end
363
+
364
+ def master?
365
+ depth == 0 && number == 0 && parent_fingerprint == '00000000'
366
+ end
359
367
  end
360
368
  end
data/lib/tapyrus/key.rb CHANGED
@@ -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
- puts '[Warning] 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
@@ -16,11 +16,14 @@ module Tapyrus
16
16
  nodes = [Node.new(txids.first)]
17
17
  else
18
18
  nodes =
19
- txids.each_slice(2).map do |m|
20
- left = Node.new(m[0])
21
- right = Node.new(m[1] ? m[1] : m[0])
22
- [left, right]
23
- end.flatten
19
+ txids
20
+ .each_slice(2)
21
+ .map do |m|
22
+ left = Node.new(m[0])
23
+ right = Node.new(m[1] ? m[1] : m[0])
24
+ [left, right]
25
+ end
26
+ .flatten
24
27
  end
25
28
  new(build_initial_tree(nodes))
26
29
  end
@@ -26,14 +26,17 @@ module Tapyrus
26
26
 
27
27
  def find_from_dns_seeds
28
28
  logger.debug 'discover peer address from DNS seeds.'
29
- dns_seeds.map do |seed|
30
- begin
31
- Socket.getaddrinfo(seed, Tapyrus.chain_params.default_port).map { |a| a[2] }.uniq
32
- rescue SocketError => e
33
- logger.error "SocketError occurred when load DNS seed: #{seed}, error: #{e.message}"
34
- nil
29
+ dns_seeds
30
+ .map do |seed|
31
+ begin
32
+ Socket.getaddrinfo(seed, Tapyrus.chain_params.default_port).map { |a| a[2] }.uniq
33
+ rescue SocketError => e
34
+ logger.error "SocketError occurred when load DNS seed: #{seed}, error: #{e.message}"
35
+ nil
36
+ end
35
37
  end
36
- end.flatten.compact
38
+ .flatten
39
+ .compact
37
40
  end
38
41
  end
39
42
  end
@@ -47,32 +47,29 @@ module Tapyrus
47
47
 
48
48
  # Returns connected peer information.
49
49
  def getpeerinfo
50
- node
51
- .pool
52
- .peers
53
- .map do |peer|
54
- local_addr = "#{peer.remote_version.remote_addr.ip}:18333"
55
- {
56
- id: peer.id,
57
- addr: "#{peer.host}:#{peer.port}",
58
- addrlocal: local_addr,
59
- services: peer.remote_version.services.to_even_length_hex.rjust(16, '0'),
60
- relaytxes: peer.remote_version.relay,
61
- lastsend: peer.last_send,
62
- lastrecv: peer.last_recv,
63
- bytessent: peer.bytes_sent,
64
- bytesrecv: peer.bytes_recv,
65
- conntime: peer.conn_time,
66
- pingtime: peer.ping_time,
67
- minping: peer.min_ping,
68
- version: peer.remote_version.version,
69
- subver: peer.remote_version.user_agent,
70
- inbound: !peer.outbound?,
71
- startingheight: peer.remote_version.start_height,
72
- best_hash: peer.best_hash,
73
- best_height: peer.best_height
74
- }
75
- end
50
+ node.pool.peers.map do |peer|
51
+ local_addr = "#{peer.remote_version.remote_addr.ip}:18333"
52
+ {
53
+ id: peer.id,
54
+ addr: "#{peer.host}:#{peer.port}",
55
+ addrlocal: local_addr,
56
+ services: peer.remote_version.services.to_even_length_hex.rjust(16, '0'),
57
+ relaytxes: peer.remote_version.relay,
58
+ lastsend: peer.last_send,
59
+ lastrecv: peer.last_recv,
60
+ bytessent: peer.bytes_sent,
61
+ bytesrecv: peer.bytes_recv,
62
+ conntime: peer.conn_time,
63
+ pingtime: peer.ping_time,
64
+ minping: peer.min_ping,
65
+ version: peer.remote_version.version,
66
+ subver: peer.remote_version.user_agent,
67
+ inbound: !peer.outbound?,
68
+ startingheight: peer.remote_version.start_height,
69
+ best_hash: peer.best_hash,
70
+ best_height: peer.best_height
71
+ }
72
+ end
76
73
  end
77
74
 
78
75
  # broadcast transaction
@@ -16,22 +16,36 @@ module Tapyrus
16
16
  # end
17
17
  # end
18
18
  class Error < StandardError
19
- attr_reader :message
19
+ attr_reader :response_code, :response_msg, :rpc_error
20
20
 
21
- def initialize(response)
22
- raise ArgumentError, 'Must set response as cause.' unless response
21
+ def initialize(response_code, response_msg, rpc_error)
22
+ @response_code = response_code
23
+ @response_msg = response_msg
24
+ @rpc_error = rpc_error
25
+ end
23
26
 
24
- # set message from response body or status code.
25
- @message = { response_code: response&.code, response_msg: response&.msg }
26
- begin
27
- @message.merge!({ rpc_error: Tapyrus::RPC.response_body2json(response.body)['error'] })
28
- rescue JSON::ParserError => _
29
- # if RPC server don't send error message.
30
- end
27
+ # Return response object as Hash
28
+ # @return [Hash] response
29
+ # @option response_code [Integer] HTTP status code
30
+ # @option response_msg [String] HTTP response body
31
+ # @option rpc_error [String] error message received from Tapyrus Core
32
+ def response
33
+ @response ||=
34
+ begin
35
+ m = { response_code: response_code, response_msg: response_msg }
36
+ m.merge!(rpc_error: rpc_error) if rpc_error
37
+ m
38
+ end
39
+ end
40
+
41
+ # Return string that represents error message.
42
+ # @return [String] error message
43
+ def message
44
+ response.to_json
31
45
  end
32
46
 
33
47
  def to_s
34
- @message.to_s
48
+ message
35
49
  end
36
50
  end
37
51
 
@@ -83,10 +97,21 @@ module Tapyrus
83
97
  request.content_type = 'application/json'
84
98
  request.body = data.to_json
85
99
  response = http.request(request)
86
- raise Error.new(response) unless response.is_a? Net::HTTPOK
100
+ raise error!(response) unless response.is_a? Net::HTTPOK
87
101
  response = Tapyrus::RPC.response_body2json(response.body)
88
102
  response['result']
89
103
  end
104
+
105
+ def error!(response)
106
+ rpc_error =
107
+ begin
108
+ Tapyrus::RPC.response_body2json(response.body)['error']
109
+ rescue JSON::ParserError => _
110
+ # if RPC server don't send error message.
111
+ end
112
+
113
+ raise Error.new(response.code, response.msg, rpc_error)
114
+ end
90
115
  end
91
116
 
92
117
  def response_body2json(body)
data/lib/tapyrus/rpc.rb CHANGED
@@ -3,5 +3,6 @@ module Tapyrus
3
3
  autoload :HttpServer, 'tapyrus/rpc/http_server'
4
4
  autoload :RequestHandler, 'tapyrus/rpc/request_handler'
5
5
  autoload :TapyrusCoreClient, 'tapyrus/rpc/tapyrus_core_client'
6
+ autoload :Error, 'tapyrus/rpc/tapyrus_core_client'
6
7
  end
7
8
  end
@@ -281,10 +281,12 @@ module Tapyrus
281
281
  # get public keys in the stack.
282
282
  # @return[Array[String]] an array of the pubkeys with hex format.
283
283
  def get_pubkeys
284
- chunks.select do |c|
285
- c.pushdata? && [33, 65].include?(c.pushed_data.bytesize) &&
286
- [2, 3, 4, 6, 7].include?(c.pushed_data[0].bth.to_i(16))
287
- end.map { |c| c.pushed_data.bth }
284
+ chunks
285
+ .select do |c|
286
+ c.pushdata? && [33, 65].include?(c.pushed_data.bytesize) &&
287
+ [2, 3, 4, 6, 7].include?(c.pushed_data[0].bth.to_i(16))
288
+ end
289
+ .map { |c| c.pushed_data.bth }
288
290
  end
289
291
 
290
292
  # returns the self payload. ScriptInterpreter does not use this.
@@ -349,30 +351,32 @@ module Tapyrus
349
351
  end
350
352
 
351
353
  def to_s
352
- chunks.map do |c|
353
- case c
354
- when Integer
355
- opcode_to_name(c)
356
- when String
357
- return c if c.empty?
358
- if c.pushdata?
359
- v = Opcodes.opcode_to_small_int(c.ord)
360
- if v
361
- v
362
- else
363
- data = c.pushed_data
364
- if data.bytesize <= 4
365
- Script.decode_number(data.bth) # for scriptnum
354
+ chunks
355
+ .map do |c|
356
+ case c
357
+ when Integer
358
+ opcode_to_name(c)
359
+ when String
360
+ return c if c.empty?
361
+ if c.pushdata?
362
+ v = Opcodes.opcode_to_small_int(c.ord)
363
+ if v
364
+ v
366
365
  else
367
- data.bth
366
+ data = c.pushed_data
367
+ if data.bytesize <= 4
368
+ Script.decode_number(data.bth) # for scriptnum
369
+ else
370
+ data.bth
371
+ end
368
372
  end
373
+ else
374
+ opcode = Opcodes.opcode_to_name(c.ord)
375
+ opcode ? opcode : 'OP_UNKNOWN [error]'
369
376
  end
370
- else
371
- opcode = Opcodes.opcode_to_name(c.ord)
372
- opcode ? opcode : 'OP_UNKNOWN [error]'
373
377
  end
374
378
  end
375
- end.join(' ')
379
+ .join(' ')
376
380
  end
377
381
 
378
382
  # generate sha-256 hash for payload
@@ -190,9 +190,15 @@ module Tapyrus
190
190
  shares.each do |share|
191
191
  log_basis_eval = (log_prod - LOG_TABLE[share[0] ^ x] - shares.sum { |s| LOG_TABLE[share[0] ^ s[0]] }) % 255
192
192
  result =
193
- share[1].htb.bytes.each.map.with_index do |v, i|
194
- (result[i].bti ^ (v == 0 ? 0 : (EXP_TABLE[(LOG_TABLE[v] + log_basis_eval) % 255]))).itb
195
- end.join
193
+ share[1]
194
+ .htb
195
+ .bytes
196
+ .each
197
+ .map
198
+ .with_index do |v, i|
199
+ (result[i].bti ^ (v == 0 ? 0 : (EXP_TABLE[(LOG_TABLE[v] + log_basis_eval) % 255]))).itb
200
+ end
201
+ .join
196
202
  end
197
203
  result.bth
198
204
  end
@@ -206,14 +212,10 @@ module Tapyrus
206
212
  l, r = ems[0...(ems.length / 2)].htb, ems[(ems.length / 2)..-1].htb
207
213
  salt = get_salt(id)
208
214
  e = (Tapyrus::SLIP39::BASE_ITERATION_COUNT << exp) / Tapyrus::SLIP39::ROUND_COUNT
209
- Tapyrus::SLIP39::ROUND_COUNT
210
- .times
211
- .to_a
212
- .reverse
213
- .each do |i|
214
- f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
215
- l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
216
- end
215
+ Tapyrus::SLIP39::ROUND_COUNT.times.to_a.reverse.each do |i|
216
+ f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
217
+ l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
218
+ end
217
219
  (r + l).bth
218
220
  end
219
221
 
@@ -228,13 +230,10 @@ module Tapyrus
228
230
  l, r = s[0...(s.bytesize / 2)], s[(s.bytesize / 2)..-1]
229
231
  salt = get_salt(id)
230
232
  e = (Tapyrus::SLIP39::BASE_ITERATION_COUNT << exp) / Tapyrus::SLIP39::ROUND_COUNT
231
- Tapyrus::SLIP39::ROUND_COUNT
232
- .times
233
- .to_a
234
- .each do |i|
235
- f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
236
- l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
237
- end
233
+ Tapyrus::SLIP39::ROUND_COUNT.times.to_a.each do |i|
234
+ f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
235
+ l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
236
+ end
238
237
  (r + l).bth
239
238
  end
240
239
 
@@ -31,6 +31,8 @@ module Tapyrus
31
31
  # .build
32
32
  #
33
33
  class TxBuilder
34
+ attr_reader :outputs, :utxos
35
+
34
36
  def initialize
35
37
  @utxos = []
36
38
  @incomings = {}
@@ -1,3 +1,3 @@
1
1
  module Tapyrus
2
- VERSION = '0.2.8'
2
+ VERSION = '0.2.13'
3
3
  end
data/lib/tapyrus.rb CHANGED
@@ -49,6 +49,7 @@ module Tapyrus
49
49
  autoload :Color, 'tapyrus/script/color'
50
50
  autoload :Errors, 'tapyrus/errors'
51
51
  autoload :TxBuilder, 'tapyrus/tx_builder'
52
+ autoload :BIP175, 'tapyrus/bip175'
52
53
 
53
54
  require_relative 'tapyrus/constants'
54
55
  require_relative 'tapyrus/ext/ecdsa'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapyrus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-14 00:00:00.000000000 Z
11
+ date: 2022-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ecdsa
@@ -306,9 +306,11 @@ files:
306
306
  - lib/openassets/payload.rb
307
307
  - lib/openassets/util.rb
308
308
  - lib/schnorr.rb
309
+ - lib/schnorr/sign_to_contract.rb
309
310
  - lib/schnorr/signature.rb
310
311
  - lib/tapyrus.rb
311
312
  - lib/tapyrus/base58.rb
313
+ - lib/tapyrus/bip175.rb
312
314
  - lib/tapyrus/block.rb
313
315
  - lib/tapyrus/block_header.rb
314
316
  - lib/tapyrus/bloom_filter.rb
@@ -423,7 +425,7 @@ homepage: https://github.com/chaintope/tapyrusrb
423
425
  licenses:
424
426
  - MIT
425
427
  metadata: {}
426
- post_install_message:
428
+ post_install_message:
427
429
  rdoc_options: []
428
430
  require_paths:
429
431
  - lib
@@ -438,8 +440,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
438
440
  - !ruby/object:Gem::Version
439
441
  version: '0'
440
442
  requirements: []
441
- rubygems_version: 3.0.3
442
- signing_key:
443
+ rubygems_version: 3.2.22
444
+ signing_key:
443
445
  specification_version: 4
444
446
  summary: The implementation of Tapyrus Protocol for Ruby.
445
447
  test_files: []