tapyrus 0.2.4 → 0.2.9

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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +37 -0
  3. data/.prettierignore +3 -0
  4. data/.prettierrc.yaml +3 -0
  5. data/CODE_OF_CONDUCT.md +7 -7
  6. data/README.md +14 -17
  7. data/Rakefile +3 -3
  8. data/lib/openassets.rb +0 -2
  9. data/lib/openassets/marker_output.rb +0 -4
  10. data/lib/openassets/payload.rb +4 -10
  11. data/lib/schnorr.rb +14 -9
  12. data/lib/schnorr/sign_to_contract.rb +51 -0
  13. data/lib/schnorr/signature.rb +3 -6
  14. data/lib/tapyrus.rb +8 -30
  15. data/lib/tapyrus/base58.rb +7 -6
  16. data/lib/tapyrus/bip175.rb +67 -0
  17. data/lib/tapyrus/block.rb +1 -2
  18. data/lib/tapyrus/block_header.rb +15 -9
  19. data/lib/tapyrus/bloom_filter.rb +5 -3
  20. data/lib/tapyrus/chain_params.rb +1 -4
  21. data/lib/tapyrus/chainparams/dev.yml +3 -2
  22. data/lib/tapyrus/chainparams/prod.yml +3 -2
  23. data/lib/tapyrus/constants.rb +29 -23
  24. data/lib/tapyrus/errors.rb +1 -3
  25. data/lib/tapyrus/ext.rb +1 -1
  26. data/lib/tapyrus/ext/ecdsa.rb +4 -4
  27. data/lib/tapyrus/ext/json_parser.rb +1 -4
  28. data/lib/tapyrus/ext_key.rb +44 -32
  29. data/lib/tapyrus/key.rb +31 -35
  30. data/lib/tapyrus/key_path.rb +15 -12
  31. data/lib/tapyrus/logger.rb +20 -16
  32. data/lib/tapyrus/merkle_tree.rb +19 -20
  33. data/lib/tapyrus/message.rb +14 -16
  34. data/lib/tapyrus/message/addr.rb +1 -7
  35. data/lib/tapyrus/message/base.rb +0 -3
  36. data/lib/tapyrus/message/block.rb +2 -9
  37. data/lib/tapyrus/message/block_transaction_request.rb +3 -6
  38. data/lib/tapyrus/message/block_transactions.rb +2 -6
  39. data/lib/tapyrus/message/block_txn.rb +0 -4
  40. data/lib/tapyrus/message/cmpct_block.rb +1 -7
  41. data/lib/tapyrus/message/error.rb +1 -4
  42. data/lib/tapyrus/message/fee_filter.rb +1 -4
  43. data/lib/tapyrus/message/filter_add.rb +0 -4
  44. data/lib/tapyrus/message/filter_clear.rb +0 -4
  45. data/lib/tapyrus/message/filter_load.rb +2 -5
  46. data/lib/tapyrus/message/get_addr.rb +0 -4
  47. data/lib/tapyrus/message/get_block_txn.rb +0 -4
  48. data/lib/tapyrus/message/get_blocks.rb +0 -3
  49. data/lib/tapyrus/message/get_data.rb +1 -4
  50. data/lib/tapyrus/message/get_headers.rb +1 -3
  51. data/lib/tapyrus/message/header_and_short_ids.rb +3 -9
  52. data/lib/tapyrus/message/headers.rb +0 -4
  53. data/lib/tapyrus/message/headers_parser.rb +3 -8
  54. data/lib/tapyrus/message/inv.rb +1 -4
  55. data/lib/tapyrus/message/inventories_parser.rb +2 -7
  56. data/lib/tapyrus/message/inventory.rb +12 -5
  57. data/lib/tapyrus/message/mem_pool.rb +0 -4
  58. data/lib/tapyrus/message/merkle_block.rb +4 -9
  59. data/lib/tapyrus/message/network_addr.rb +7 -6
  60. data/lib/tapyrus/message/not_found.rb +0 -3
  61. data/lib/tapyrus/message/ping.rb +0 -3
  62. data/lib/tapyrus/message/pong.rb +0 -3
  63. data/lib/tapyrus/message/prefilled_tx.rb +0 -4
  64. data/lib/tapyrus/message/reject.rb +0 -3
  65. data/lib/tapyrus/message/send_cmpct.rb +1 -3
  66. data/lib/tapyrus/message/send_headers.rb +0 -3
  67. data/lib/tapyrus/message/tx.rb +0 -4
  68. data/lib/tapyrus/message/ver_ack.rb +1 -5
  69. data/lib/tapyrus/message/version.rb +2 -5
  70. data/lib/tapyrus/mnemonic.rb +17 -15
  71. data/lib/tapyrus/network.rb +0 -2
  72. data/lib/tapyrus/network/connection.rb +0 -3
  73. data/lib/tapyrus/network/message_handler.rb +61 -60
  74. data/lib/tapyrus/network/peer.rb +13 -12
  75. data/lib/tapyrus/network/peer_discovery.rb +3 -5
  76. data/lib/tapyrus/network/pool.rb +12 -12
  77. data/lib/tapyrus/node.rb +1 -1
  78. data/lib/tapyrus/node/cli.rb +12 -14
  79. data/lib/tapyrus/node/configuration.rb +1 -3
  80. data/lib/tapyrus/node/spv.rb +2 -3
  81. data/lib/tapyrus/opcodes.rb +9 -7
  82. data/lib/tapyrus/out_point.rb +5 -5
  83. data/lib/tapyrus/rpc.rb +1 -0
  84. data/lib/tapyrus/rpc/http_server.rb +21 -22
  85. data/lib/tapyrus/rpc/request_handler.rb +42 -44
  86. data/lib/tapyrus/rpc/tapyrus_core_client.rb +67 -25
  87. data/lib/tapyrus/script/color.rb +20 -2
  88. data/lib/tapyrus/script/multisig.rb +13 -12
  89. data/lib/tapyrus/script/script.rb +104 -67
  90. data/lib/tapyrus/script/script_error.rb +1 -4
  91. data/lib/tapyrus/script/script_interpreter.rb +439 -399
  92. data/lib/tapyrus/script/tx_checker.rb +20 -10
  93. data/lib/tapyrus/secp256k1.rb +0 -4
  94. data/lib/tapyrus/secp256k1/native.rb +14 -15
  95. data/lib/tapyrus/secp256k1/rfc6979.rb +7 -4
  96. data/lib/tapyrus/secp256k1/ruby.rb +10 -12
  97. data/lib/tapyrus/slip39.rb +20 -5
  98. data/lib/tapyrus/slip39/share.rb +41 -29
  99. data/lib/tapyrus/slip39/sss.rb +101 -57
  100. data/lib/tapyrus/store.rb +1 -3
  101. data/lib/tapyrus/store/chain_entry.rb +0 -4
  102. data/lib/tapyrus/store/db.rb +0 -2
  103. data/lib/tapyrus/store/db/level_db.rb +5 -9
  104. data/lib/tapyrus/store/spv_chain.rb +11 -17
  105. data/lib/tapyrus/tx.rb +45 -37
  106. data/lib/tapyrus/tx_builder.rb +158 -0
  107. data/lib/tapyrus/tx_in.rb +1 -6
  108. data/lib/tapyrus/tx_out.rb +2 -7
  109. data/lib/tapyrus/util.rb +20 -7
  110. data/lib/tapyrus/validation.rb +12 -11
  111. data/lib/tapyrus/version.rb +1 -1
  112. data/lib/tapyrus/wallet/account.rb +22 -18
  113. data/lib/tapyrus/wallet/base.rb +12 -9
  114. data/lib/tapyrus/wallet/db.rb +6 -9
  115. data/lib/tapyrus/wallet/master_key.rb +2 -4
  116. data/tapyrusrb.gemspec +13 -16
  117. metadata +22 -31
  118. data/.travis.yml +0 -12
@@ -1,23 +1,18 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # Common message parser which only handle multiple inventory as payload.
5
4
  module InventoriesParser
6
-
7
5
  def parse_from_payload(payload)
8
6
  size, payload = Tapyrus.unpack_var_int(payload)
9
7
  buf = StringIO.new(payload)
10
8
  i = new
11
- size.times do
12
- i.inventories << Inventory.parse_from_payload(buf.read(36))
13
- end
9
+ size.times { i.inventories << Inventory.parse_from_payload(buf.read(36)) }
14
10
  i
15
11
  end
16
12
 
17
13
  def to_payload
18
14
  Tapyrus.pack_var_int(inventories.length) << inventories.map(&:to_payload).join
19
15
  end
20
-
21
16
  end
22
17
  end
23
- end
18
+ end
@@ -3,7 +3,6 @@ module Tapyrus
3
3
  # inventory class. inventory is a part of message.
4
4
  # https://bitcoin.org/en/developer-reference#term-inventory
5
5
  class Inventory
6
-
7
6
  SEGWIT_FLAG = 1 << 30
8
7
 
9
8
  MSG_TX = 1
@@ -18,7 +17,9 @@ module Tapyrus
18
17
  attr_accessor :hash
19
18
 
20
19
  def initialize(identifier, hash)
21
- raise Error, "invalid type identifier specified. identifier = #{identifier}" unless valid_identifier?(identifier)
20
+ unless valid_identifier?(identifier)
21
+ raise Error, "invalid type identifier specified. identifier = #{identifier}"
22
+ end
22
23
  @identifier = identifier
23
24
  @hash = hash
24
25
  end
@@ -42,10 +43,16 @@ module Tapyrus
42
43
  private
43
44
 
44
45
  def valid_identifier?(identifier)
45
- [MSG_TX, MSG_BLOCK, MSG_FILTERED_BLOCK, MSG_CMPCT_BLOCK, MSG_WITNESS_TX,
46
- MSG_WITNESS_BLOCK, MSG_FILTERED_WITNESS_BLOCK].include?(identifier)
46
+ [
47
+ MSG_TX,
48
+ MSG_BLOCK,
49
+ MSG_FILTERED_BLOCK,
50
+ MSG_CMPCT_BLOCK,
51
+ MSG_WITNESS_TX,
52
+ MSG_WITNESS_BLOCK,
53
+ MSG_FILTERED_WITNESS_BLOCK
54
+ ].include?(identifier)
47
55
  end
48
-
49
56
  end
50
57
  end
51
58
  end
@@ -1,17 +1,13 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # mempool message
5
4
  # https://bitcoin.org/en/developer-reference#mempool
6
5
  class MemPool < Base
7
-
8
6
  COMMAND = 'mempool'
9
7
 
10
8
  def to_payload
11
9
  ''
12
10
  end
13
-
14
11
  end
15
-
16
12
  end
17
13
  end
@@ -1,10 +1,8 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # merckleblock message
5
4
  # https://bitcoin.org/en/developer-reference#merkleblock
6
5
  class MerkleBlock < Base
7
-
8
6
  COMMAND = 'merkleblock'
9
7
 
10
8
  attr_accessor :header
@@ -22,21 +20,18 @@ module Tapyrus
22
20
  m.header = Tapyrus::BlockHeader.parse_from_payload(buf)
23
21
  m.tx_count = buf.read(4).unpack('V').first
24
22
  hash_count = Tapyrus.unpack_var_int_from_io(buf)
25
- hash_count.times do
26
- m.hashes << buf.read(32).bth
27
- end
23
+ hash_count.times { m.hashes << buf.read(32).bth }
28
24
  flag_count = Tapyrus.unpack_var_int_from_io(buf)
25
+
29
26
  # A sequence of bits packed eight in a byte with the least significant bit first.
30
27
  m.flags = buf.read(flag_count).bth
31
28
  m
32
29
  end
33
30
 
34
31
  def to_payload
35
- header.to_payload << [tx_count].pack('V') << Tapyrus.pack_var_int(hashes.size) <<
36
- hashes.map(&:htb).join << Tapyrus.pack_var_int(flags.htb.bytesize) << flags.htb
32
+ header.to_payload << [tx_count].pack('V') << Tapyrus.pack_var_int(hashes.size) << hashes.map(&:htb).join <<
33
+ Tapyrus.pack_var_int(flags.htb.bytesize) << flags.htb
37
34
  end
38
-
39
35
  end
40
-
41
36
  end
42
37
  end
@@ -2,9 +2,7 @@ require 'ipaddr'
2
2
 
3
3
  module Tapyrus
4
4
  module Message
5
-
6
5
  class NetworkAddr
7
-
8
6
  # unix time.
9
7
  # Nodes advertising their own IP address set this to the current time.
10
8
  # Nodes advertising IP addresses they’ve connected to set this to the last time they connected to that node.
@@ -20,7 +18,12 @@ module Tapyrus
20
18
 
21
19
  attr_reader :skip_time
22
20
 
23
- def initialize(ip: '127.0.0.1', port: Tapyrus.chain_params.default_port, services: DEFAULT_SERVICE_FLAGS, time: Time.now.to_i)
21
+ def initialize(
22
+ ip: '127.0.0.1',
23
+ port: Tapyrus.chain_params.default_port,
24
+ services: DEFAULT_SERVICE_FLAGS,
25
+ time: Time.now.to_i
26
+ )
24
27
  @time = time
25
28
  @ip_addr = IPAddr.new(ip)
26
29
  @port = port
@@ -33,7 +36,7 @@ module Tapyrus
33
36
  addr = new(time: nil)
34
37
  addr.time = buf.read(4).unpack('V').first if has_time
35
38
  addr.services = buf.read(8).unpack('Q').first
36
- addr.ip_addr = IPAddr::new_ntoh(buf.read(16))
39
+ addr.ip_addr = IPAddr.new_ntoh(buf.read(16))
37
40
  addr.port = buf.read(2).unpack('n').first
38
41
  addr
39
42
  end
@@ -56,8 +59,6 @@ module Tapyrus
56
59
  addr = ip_addr.ipv4? ? ip_addr.ipv4_mapped : ip_addr
57
60
  p << [services].pack('Q') << addr.hton << [port].pack('n')
58
61
  end
59
-
60
62
  end
61
-
62
63
  end
63
64
  end
@@ -1,6 +1,5 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # notfound message
5
4
  # https://bitcoin.org/en/developer-reference#notfound
6
5
  class NotFound < Base
@@ -14,8 +13,6 @@ module Tapyrus
14
13
  def initialize(inventories = [])
15
14
  @inventories = inventories
16
15
  end
17
-
18
16
  end
19
17
  end
20
-
21
18
  end
@@ -1,10 +1,8 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # ping message class
5
4
  # https://bitcoin.org/en/developer-reference#ping
6
5
  class Ping < Base
7
-
8
6
  COMMAND = 'ping'
9
7
 
10
8
  attr_accessor :nonce
@@ -24,7 +22,6 @@ module Tapyrus
24
22
  def to_response
25
23
  Pong.new(nonce)
26
24
  end
27
-
28
25
  end
29
26
  end
30
27
  end
@@ -1,10 +1,8 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # pong message
5
4
  # https://bitcoin.org/en/developer-reference#pong
6
5
  class Pong < Base
7
-
8
6
  COMMAND = 'pong'
9
7
 
10
8
  attr_reader :nonce
@@ -21,6 +19,5 @@ module Tapyrus
21
19
  [nonce].pack('Q')
22
20
  end
23
21
  end
24
-
25
22
  end
26
23
  end
@@ -1,10 +1,8 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # A PrefilledTransaction structure is used in HeaderAndShortIDs to provide a list of a few transactions explicitly.
5
4
  # https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
6
5
  class PrefilledTx
7
-
8
6
  attr_accessor :index
9
7
  attr_accessor :tx
10
8
 
@@ -22,8 +20,6 @@ module Tapyrus
22
20
  def to_payload
23
21
  Tapyrus.pack_var_int(index) << tx.to_payload
24
22
  end
25
-
26
23
  end
27
-
28
24
  end
29
25
  end
@@ -1,10 +1,8 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # reject message
5
4
  # https://bitcoin.org/en/developer-reference#reject
6
5
  class Reject < Base
7
-
8
6
  attr_accessor :message
9
7
  attr_accessor :code
10
8
  attr_accessor :reason
@@ -40,7 +38,6 @@ module Tapyrus
40
38
  e = ['tx', 'block'].include?(message) ? extra.htb : extra
41
39
  Tapyrus.pack_var_string(message) << [code].pack('C') << Tapyrus.pack_var_string(reason) << e
42
40
  end
43
-
44
41
  end
45
42
  end
46
43
  end
@@ -1,10 +1,8 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # sendcmpct message
5
4
  # https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
6
5
  class SendCmpct < Base
7
-
8
6
  COMMAND = 'sendcmpct'
9
7
 
10
8
  MODE_HIGH = 1
@@ -12,6 +10,7 @@ module Tapyrus
12
10
 
13
11
  attr_accessor :mode
14
12
  attr_accessor :version
13
+
15
14
  # TODO support version 2
16
15
 
17
16
  def initialize(mode = MODE_HIGH, version = 1)
@@ -38,6 +37,5 @@ module Tapyrus
38
37
  mode.zero?
39
38
  end
40
39
  end
41
-
42
40
  end
43
41
  end
@@ -1,16 +1,13 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # sendheaders message
5
4
  # https://bitcoin.org/en/developer-reference#sendheaders
6
5
  class SendHeaders < Base
7
-
8
6
  COMMAND = 'sendheaders'
9
7
 
10
8
  def to_payload
11
9
  ''
12
10
  end
13
11
  end
14
-
15
12
  end
16
13
  end
@@ -1,10 +1,8 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # tx message
5
4
  # https://bitcoin.org/en/developer-reference#tx
6
5
  class Tx < Base
7
-
8
6
  COMMAND = 'tx'
9
7
 
10
8
  attr_accessor :tx
@@ -23,8 +21,6 @@ module Tapyrus
23
21
  def to_payload
24
22
  tx.to_payload
25
23
  end
26
-
27
24
  end
28
-
29
25
  end
30
26
  end
@@ -1,17 +1,13 @@
1
1
  module Tapyrus
2
2
  module Message
3
-
4
3
  # verack message
5
4
  # https://bitcoin.org/en/developer-reference#verack
6
5
  class VerAck < Base
7
-
8
6
  COMMAND = 'verack'
9
7
 
10
8
  def to_payload
11
9
  ''
12
10
  end
13
-
14
11
  end
15
-
16
12
  end
17
- end
13
+ end
@@ -2,10 +2,8 @@
2
2
  require 'ipaddr'
3
3
  module Tapyrus
4
4
  module Message
5
-
6
5
  # https://bitcoin.org/en/developer-reference#version
7
6
  class Version < Base
8
-
9
7
  COMMAND = 'version'
10
8
 
11
9
  attr_accessor :version
@@ -61,9 +59,8 @@ module Tapyrus
61
59
  end
62
60
 
63
61
  def unpack_relay_field(payload)
64
- ( version >= 70001 && payload ) ? unpack_boolean(payload) : [ true, nil ]
62
+ (version >= 70_001 && payload) ? unpack_boolean(payload) : [true, nil]
65
63
  end
66
-
67
64
  end
68
65
  end
69
- end
66
+ end
@@ -1,9 +1,7 @@
1
1
  module Tapyrus
2
-
3
2
  # Mnemonic code for generating deterministic keys
4
3
  # https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
5
4
  class Mnemonic
6
-
7
5
  WORD_DIR = "#{__dir__}/mnemonic/wordlist"
8
6
 
9
7
  attr_reader :word_list
@@ -15,7 +13,7 @@ module Tapyrus
15
13
 
16
14
  # get support language list
17
15
  def self.word_lists
18
- Dir.glob("#{WORD_DIR}/**.txt").map{|f| f.gsub("#{WORD_DIR}/", '').gsub('.txt', '') }
16
+ Dir.glob("#{WORD_DIR}/**.txt").map { |f| f.gsub("#{WORD_DIR}/", '').gsub('.txt', '') }
19
17
  end
20
18
 
21
19
  # generate entropy from mnemonic word
@@ -23,11 +21,12 @@ module Tapyrus
23
21
  # @return [String] an entropy with hex format.
24
22
  def to_entropy(words)
25
23
  word_master = load_words
26
- mnemonic = words.map do |w|
27
- index = word_master.index(w.downcase)
28
- raise IndexError, 'word not found in words list.' unless index
29
- index.to_s(2).rjust(11, '0')
30
- end.join
24
+ mnemonic =
25
+ words.map do |w|
26
+ index = word_master.index(w.downcase)
27
+ raise IndexError, 'word not found in words list.' unless index
28
+ index.to_s(2).rjust(11, '0')
29
+ end.join
31
30
  entropy = mnemonic.slice(0, (mnemonic.length * 32) / 33)
32
31
  checksum = mnemonic.gsub(entropy, '')
33
32
  raise SecurityError, 'checksum mismatch.' unless checksum == checksum(entropy)
@@ -41,9 +40,9 @@ module Tapyrus
41
40
  raise ArgumentError, 'entropy is empty.' if entropy.nil? || entropy.empty?
42
41
  e = entropy.htb.unpack('B*').first
43
42
  seed = e + checksum(e)
44
- mnemonic_index = seed.chars.each_slice(11).map{|i|i.join.to_i(2)}
43
+ mnemonic_index = seed.chars.each_slice(11).map { |i| i.join.to_i(2) }
45
44
  word_master = load_words
46
- mnemonic_index.map{|i|word_master[i]}
45
+ mnemonic_index.map { |i| word_master[i] }
47
46
  end
48
47
 
49
48
  # generate seed from mnemonic
@@ -53,8 +52,13 @@ module Tapyrus
53
52
  # @return [String] seed
54
53
  def to_seed(mnemonic, passphrase: '')
55
54
  to_entropy(mnemonic)
56
- OpenSSL::PKCS5.pbkdf2_hmac(mnemonic.join(' ').downcase,
57
- 'mnemonic' + passphrase, 2048, 64, OpenSSL::Digest::SHA512.new).bth
55
+ OpenSSL::PKCS5.pbkdf2_hmac(
56
+ mnemonic.join(' ').downcase,
57
+ 'mnemonic' + passphrase,
58
+ 2048,
59
+ 64,
60
+ OpenSSL::Digest::SHA512.new
61
+ ).bth
58
62
  end
59
63
 
60
64
  # calculate entropy checksum
@@ -62,7 +66,7 @@ module Tapyrus
62
66
  # @return [String] an entropy checksum with bit string format
63
67
  def checksum(entropy)
64
68
  b = Tapyrus.sha256([entropy].pack('B*')).unpack('B*').first
65
- b.slice(0, (entropy.length/32))
69
+ b.slice(0, (entropy.length / 32))
66
70
  end
67
71
 
68
72
  private
@@ -71,7 +75,5 @@ module Tapyrus
71
75
  def load_words
72
76
  File.readlines("#{WORD_DIR}/#{word_list}.txt").map(&:strip)
73
77
  end
74
-
75
78
  end
76
-
77
79
  end